+++ /dev/null
-Hacking on Connection Manager
-*****************************
-
-
-Build tools requirements
-========================
-
-When building and testing directly from the repository it is important to
-have at least automake version 1.10 or later installed. All modern
-distributions should default to the latest version, but it seems that
-Debian's default is still an earlier version:
-
- Check version
- # dpkg -l '*automake*'
-
- Install new version
- # apt-get install automake1.10
- # update-alternatives --config automake
-
-
-Working with the source code repository
-=======================================
-
-The repository contains two extra scripts that accomplish the bootstrap
-process. One is called "bootstrap" which is the basic scripts that uses the
-autotools scripts to create the needed files for building and installing.
-It makes sure to call the right programs depending on the usage of shared or
-static libraries or translations etc.
-
-The second program is called "bootstrap-configure". This program will make
-sure to properly clean the repository, call the "bootstrap" script and then
-call configure with proper settings for development. It will use the best
-options and pass them over to configure. These options normally include
-the enabling the maintainer mode and the debugging features.
-
-So while in a normal source project the call "./configure ..." is used to
-configure the project with its settings like prefix and extra options. In
-case of bare repositories call "./bootstrap-configure" and it will bootstrap
-the repository and calls configure with all the correct options to make
-development easier.
-
-In case of preparing for a release with "make distcheck", don't use
-bootstrap-configure since it could export development specific settings.
-
-So the normal steps to checkout, build and install such a repository is
-like this:
-
- Checkout repository
- # git clone git://git.kernel.org/pub/scm/network/connman/connman.git
- # cd connman
-
- Configure and build
- # ./bootstrap-configure
- # make
-
- Check installation
- # make install DESTDIR=$PWD/x
- # find x
- # rm -rf x
-
- Check distribution
- # make distcheck
-
- Final installation
- # sudo make install
-
- Remove autogenerated files
- # make maintainer-clean
-
-
-Running from within the source code repository
-==============================================
-
-When using "./configure --enable-maintainer-mode" the automake scripts will
-use the plugins directly from within the repository. This removes the need
-to use "make install" when testing "connmand". The "bootstrap-configure"
-automatically includes this option.
-
- Run daemon in foreground with debugging
- # sudo ./src/connmand -n -d 'plugins/*'
-
-The debugging option -d takes an argument. This argument can be a comma
-separated list of file names like 'plugins/wifi.c,plugins/ethernet.c' to
-enable debugs in these files. Simple glob style pattern matching is
-supported in this list.
-
-For production installations or distribution packaging it is important that
-the "--enable-maintainer-mode" option is NOT used.
-
-Some times it is important to restrict the available interfaces. For example
-in cases where testing happens over a network connection. The "-i" command
-line switch allows to specify a glob pattern for the interface names.
-
- Run daemon for wireless interfaces
- # sudo ./src/connmand -n -i wlan*
-
-
-Debugging the D-Bus interface during runtime
-============================================
-
-Running the daemon with debugging information in the foreground is quite
-verbose and sometimes not really helpful. The "monitor-connman" script
-allows to monitor "PropertyChanged" D-Bus signals from various interfaces.
-
-Every "PropertyChanged" signal will generate a line of output. Some of them
-can get very complex. The first detail inside "{ ... }" is the interface
-name (without its service name prefix). The second detail inside "[ ... ]"
-is the object path. And after that it is followed by a key and value of
-the property that changed.
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 =
+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/peer_service.c src/machine.c src/util.c
src_connmand_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
- @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
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-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
endif
endif
-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
$(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)"\" \
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_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 \
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-iptables.c src/nat.c \
tools/iptables-unit.c
tools_iptables_unit_LDADD = gdbus/libgdbus-internal.la \
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/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
nodist_man_MANS = $(MANUAL_PAGES)
--enable-hh2serial-gps \
--enable-openconnect \
--enable-openvpn \
+ --enable-ipsec \
--enable-vpnc \
--enable-session-policy-local \
--enable-nmcompat \
-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 $@)
$(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)/$< $@
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
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 {
__connmanctl_monitor_completions(NULL);
rl_callback_handler_remove();
+#if !defined TIZEN_EXT
rl_message("");
+#endif
}
dbus_connection_unref(connection);
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}")
-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}],
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)
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
rely on MAC address ranges, etc
.TP
.BI EnableOnlineCheck=true\ \fR|\fB\ false
-Enable or disable use of HTTP GET as an online status check.
+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
The TLV formated byte array representing the
WiFi Display Informations Elements.
+
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
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]
Indicates the signal strength of the service. This
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
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.
+++ /dev/null
-{
- <syslog error>
- Memcheck:Cond
- obj:/lib/libc-*.so
- ...
- fun:localtime_r
- fun:__vsyslog_chk
- fun:__syslog_chk
- fun:__connman_log_init
- ...
-}
-{
- <iconv open>
- Memcheck:Addr4
- obj:/lib/libc-*.so
- obj:/lib/libglib-2.0.so*
- fun:g_iconv_open
- ...
- fun:g_convert
- fun:g_locale_to_utf8
- fun:g_strerror
- fun:g_key_file_load_from_file
- ...
-}
-{
- <ioctl ADDRT/DELRT>
- Memcheck:Param
- ioctl(SIOCADDRT/DELRT)
- obj:/lib/ld-*.so
- ...
-}
-{
- <g_main_loop>
- Memcheck:Leak
- fun:memalign
- ...
- fun:g_slice_alloc
- ...
- fun:g_main_loop_new
- ...
-}
-{
- <g_option_context_parse>
- Memcheck:Leak
- ...
- fun:g_slice_alloc
- ...
- fun:g_option_context_parse
- ...
-}
-{
- <g_key_file_load_from_data>
- Memcheck:Leak
- ...
- fun:g_slice_alloc
- ...
- fun:g_key_file_load_from_data
- ...
-}
-{
- <g_key_file_new 1>
- Memcheck:Leak
- ...
- fun:g_slice_alloc
- ...
- fun:g_key_file_new
- ...
-}
-{
- <g_key_file_new 2>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_key_file_new
- fun:main
-}
-{
- <connman plugin cleanup>
- Memcheck:Leak
- ...
- fun:__connman_plugin_cleanup
- ...
-}
-{
- <cmd line option parsing>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_strdup
- fun:g_set_prgname
- fun:g_option_context_parse
- fun:main
-}
-{
- <dbus system bus setup 1>
- Memcheck:Leak
- ...
- fun:dbus_malloc*
- ...
- fun:g_dbus_setup_bus
- fun:main
-}
-{
- <dbus system bus setup 2>
- Memcheck:Leak
- ...
- fun:g_malloc*
- ...
- fun:dbus_connection_set_watch_functions
- fun:setup_bus
- ...
-}
-{
- <key file get charset>
- Memcheck:Leak
- ...
- fun:g_*alloc*
- ...
- fun:g_strerror
- fun:g_key_file_load_from_file
- fun:main
-}
-{
- <dbus disconnect func set>
- Memcheck:Leak
- ...
- fun:filter_data_get
- fun:g_dbus_add_signal_watch
- fun:g_dbus_set_disconnect_function
- fun:main
-}
-{
- <plugin dlopen>
- Memcheck:Leak
- ...
- fun:dlopen
- fun:__connman_plugin_init
- fun:main
-}
-{
- <dbus system bus setup 3>
- Memcheck:Leak
- ...
- fun:dbus_malloc0
- ...
- fun:dbus_parse_address
- ...
- fun:g_dbus_setup_bus
- fun:main
-}
-{
- <libdbus internals 1>
- Memcheck:Leak
- fun:*malloc
- ...
- obj:/lib/libdbus-1.so.3.5.3
-}
-{
- <dbus system bus setup 4>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:dbus_*alloc*
- ...
- fun:g_dbus_setup_bus
- fun:main
-}
-{
- <dbus system bus setup 5>
- Memcheck:Leak
- fun:calloc
- fun:g_malloc0
- ...
- fun:g_dbus_set_disconnect_function
- fun:main
-}
-{
- <dbus bus remove match>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_source_set_callback
- fun:g_timeout_add_full
- fun:g_timeout_add
- ...
- fun:dbus_pending_call_block
- fun:dbus_connection_send_with_reply_and_block
- ...
- fun:dbus_bus_remove_match
-}
-{
- <g_main_loop_run/new>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_main_loop_*
- fun:main
-}
-{
- <g_main_context_dispatch>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_main_context_dispatch
-}
-{
- <libdbus internals 2>
- Memcheck:Leak
- fun:realloc
- fun:dbus_realloc
- ...
- fun:dbus_message_set_reply_serial
- fun:dbus_message_new_error
- ...
-}
-{
- <libdbus internals 3>
- Memcheck:Leak
- fun:realloc
- fun:dbus_realloc
- ...
- fun:dbus_message_new_signal
- ...
-}
-{
- <dbus_bus_register>
- Memcheck:Leak
- fun:malloc
- fun:realloc
- fun:dbus_realloc
- ...
- fun:dbus_pending_call_block
- fun:dbus_connection_send_with_reply_and_block
- fun:dbus_bus_register
-}
PPPD.RequirMPPEStateful mppe-stateful Allow MPPE to use stateful mode (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
=======
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;
parse_managed_objects(client, reply);
done:
+#if !defined TIZEN_EXT
if (client->ready)
client->ready(client, client->ready_data);
+#endif
dbus_message_unref(reply);
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,
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,
#include "gdbus.h"
+#define DISPATCH_TIMEOUT 0
+
#define info(fmt...)
#define error(fmt...)
#define debug(fmt...)
{
DBusConnection *conn = data;
+ dbus_connection_ref(conn);
+
/* Dispatch messages */
while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
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;
#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)
{
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 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;
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)
{
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
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)
{
};
#endif
+char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type);
uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code);
uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
int code, uint16_t *option_len, int *option_count);
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
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;
};
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;
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;
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);
+#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 (*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,
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;
+#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;
+#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 {
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;
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->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)
{
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);
g_free(network->path);
g_free(network->group);
g_free(network->name);
+#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);
+#if defined TIZEN_EXT
+ g_free(bss->wifi_vsie);
+#endif
g_free(bss);
}
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;
}
+#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;
+}
+
+const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
+ unsigned int *wifi_vsie_len)
+{
+ if (!network) {
+ *wifi_vsie_len = 0;
+ return NULL;
+ }
+
+ *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);
network->frequency = bss->frequency;
network->best_bss = bss;
+#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,
{
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
+ 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
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;
} else if (g_strcmp0(key, "CurrentBSS") == 0) {
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,
{
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)
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);
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] = {};
{ 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 },
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);
if (data->callback) {
data->callback(0, interface, data->user_data);
+#if !defined TIZEN_EXT
callback_p2p_support(interface);
+#endif
}
interface_create_data_free(data);
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;
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,
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,
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,
}
+#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);
+ goto done;
+ }
+
+ if (dbus_message_iter_init(reply, &args) == FALSE) {
+ SUPPLICANT_DBG("dbus_message_iter_init() failed");
+ 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,
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);
+ }
if (ret < 0) {
g_free(data->path);
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 (!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;
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)
{
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);
gnutls_priority_set_direct(gnutls_channel->session,
"NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT", NULL);
#endif
-
gnutls_certificate_allocate_credentials(&gnutls_channel->cred);
gnutls_credentials_set(gnutls_channel->session,
GNUTLS_CRD_CERTIFICATE, gnutls_channel->cred);
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);
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) {
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]);
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2016 Yann E. MORIN <yann.morin.1998@free.fr>. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifndef __CONNMAN_BACKTRACE_H
-#define __CONNMAN_BACKTRACE_H
-
-#ifdef HAVE_EXECINFO_H
-void print_backtrace(const char* program_path, const char* program_exec,
- unsigned int offset);
-#else
-#define print_backtrace(P,E,O)
-#endif
-
-#endif /* __CONNMAN_BACKTRACE_H */
connman_dbus_get_connection_unix_user_cb_t func,
void *user_data);
+int connman_dbus_get_connection_unix_user_sync(DBusConnection *connection,
+ const char *bus_name,
+ unsigned int *user_id);
+
typedef void (* connman_dbus_get_context_cb_t) (const unsigned char *context,
void *user_data, int err);
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);
int connman_inet_ifup(int index);
int connman_inet_ifdown(int index);
+#if defined TIZEN_EXT
+void connman_inet_update_device_ident(struct connman_device *device);
+#endif
+
int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress);
int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress);
int connman_inet_add_host_route(int index, const char *host, const char *gateway);
struct connman_debug_desc {
const char *name;
const char *file;
+#if defined TIZEN_EXT
+#define CONNMAN_DEBUG_FLAG_DEFAULT (1)
+#else
#define CONNMAN_DEBUG_FLAG_DEFAULT (0)
+#endif
#define CONNMAN_DEBUG_FLAG_PRINT (1 << 0)
#define CONNMAN_DEBUG_FLAG_ALIAS (1 << 1)
unsigned int flags;
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,
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);
#include <stdbool.h>
+#if defined TIZEN_EXT
+#include <glib.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
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
struct connman_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);
--- /dev/null
+%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;
}
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);
g_strdup(path), g_free))
return -EIO;
+#if defined TIZEN_EXT
+ if (pan->network)
+#endif
connman_network_set_associating(pan->network, true);
return -EINPROGRESS;
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",
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);
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;
<allow own="org.freedesktop.NetworkManager"/>
<allow send_destination="org.freedesktop.NetworkManager"/>
</policy>
+ <policy user="network_fw">
+ <allow own="org.freedesktop.NetworkManager"/>
+ <allow send_destination="org.freedesktop.NetworkManager"/>
+ </policy>
<policy at_console="true">
<allow send_destination="org.freedesktop.NetworkManager"/>
</policy>
#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_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 = {
#include <config.h>
#endif
+#include <stdio.h>
+
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <net/if.h>
#include <glib.h>
+#include <glib/gprintf.h>
+
#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
memset(system_hostname, 0, sizeof(system_hostname));
- if (gethostname(system_hostname, HOST_NAME_MAX) < 0) {
- connman_error("Failed to get current hostname");
- return -EIO;
- }
+#if defined TIZEN_EXT
+ FILE *fp = NULL;
+#define WIFI_MAC "/opt/etc/.mac.info"
+ {
+ char* rv = 0;
+ gchar* dev_id = "TIZEN";
+ char wifi_mac[HOST_NAME_MAX + 1];
+
+ fp = fopen(WIFI_MAC, "r");
+ if(!fp){
+ connman_error("Failed to get current hostname");
+ strncpy(system_hostname, dev_id, strlen(dev_id));
+ goto host_name_end;
+ }
+
+ rv = fgets(wifi_mac, HOST_NAME_MAX, fp);
+ if(!rv){
+ connman_error("Failed to get current hostname");
+ strncpy(system_hostname, dev_id, strlen(dev_id));
+ fclose(fp);
+ goto host_name_end;
+ }
+
+ dev_id = g_base64_encode((const guchar *)wifi_mac, strlen(wifi_mac));
+ g_sprintf(system_hostname, "TIZEN-%s", dev_id);
+ g_free(dev_id);
+ fclose(fp);
+ }
- if (strlen(system_hostname) > 0 &&
- strcmp(system_hostname, "(none)") != 0)
- connman_info("System hostname is %s", system_hostname);
- else
- create_hostname();
+ host_name_end :
+#else
+ if (gethostname(system_hostname, HOST_NAME_MAX) < 0) {
+ connman_error("Failed to get current hostname");
+ return -EIO;
+ }
+#endif
+ if (strlen(system_hostname) > 0 &&
+ strcmp(system_hostname, "(none)") != 0)
+ connman_info("System hostname is %s", system_hostname);
+ else
+ create_hostname();
memset(name, 0, sizeof(name));
--- /dev/null
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <gdbus.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/dbus.h>
+#include <connman/inet.h>
+#include <connman/plugin.h>
+#include <connman/network.h>
+#include <connman/setting.h>
+#include <connman/technology.h>
+
+#include <connman.h>
+
+#define PS_DBUS_SERVICE "com.tcore.ps"
+
+#define PS_MASTER_INTERFACE PS_DBUS_SERVICE ".master"
+#define PS_MODEM_INTERFACE PS_DBUS_SERVICE ".modem"
+#define PS_SERVICE_INTERFACE PS_DBUS_SERVICE ".service"
+#define PS_CONTEXT_INTERFACE PS_DBUS_SERVICE ".context"
+
+/* methods */
+#define GET_MODEMS "GetModems"
+#define GET_SERVICES "GetServices"
+#define GET_CONTEXTS "GetContexts"
+#define ACTIVATE_CONTEXT "Activate"
+#define DEACTIVATE_CONTEXT "Deactivate"
+#define GET_PROPERTIES "GetProperties"
+#define SET_PROPERTY "SetProperties"
+
+/* signals */
+#define MODEM_ADDED "ModemAdded"
+#define MODEM_REMOVED "ModemRemoved"
+#define SERVICE_ADDED "ServiceAdded"
+#define SERVICE_REMOVED "ServiceRemoved"
+#define CONTEXT_ADDED "ContextAdded"
+#define CONTEXT_REMOVED "ContextRemoved"
+#define PROPERTY_CHANGED "PropertyChanged"
+
+#define TIMEOUT 130000
+
+#define STRING2BOOL(a) (!(g_strcmp0(a, "TRUE")) ? (TRUE):(FALSE))
+
+static DBusConnection *connection;
+static GHashTable *modem_hash;
+static GHashTable *service_hash;
+static GHashTable *network_hash;
+
+struct telephony_service {
+ char *path;
+
+ gpointer p_modem;
+ char *act;
+ gboolean roaming; /* global roaming state */
+ gboolean ps_attached; /* packet service is available */
+};
+
+struct telephony_modem {
+ char *path;
+
+ char *operator;
+ gboolean powered;
+ gboolean sim_init;
+ gboolean flight_mode;
+ gboolean data_allowed;
+ gboolean roaming_allowed;
+
+ struct connman_device *device;
+ struct telephony_service *s_service;
+};
+
+struct telephony_network {
+ char *path;
+ int if_index;
+ gboolean routing_only;
+ gboolean ipv6_link_only;
+
+ 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;
+};
+
+static int telephony_default_subscription_id = 0;
+
+/* function prototype */
+static void telephony_connect(DBusConnection *connection, void *user_data);
+static void telephony_disconnect(DBusConnection *connection, void *user_data);
+static void __remove_modem(gpointer data);
+static void __remove_service(gpointer data);
+static void __remove_network(gpointer data);
+
+static int __modem_probe(struct connman_device *device);
+static void __modem_remove(struct connman_device *device);
+static int __modem_enable(struct connman_device *device);
+static int __modem_disable(struct connman_device *device);
+
+static int __network_probe(struct connman_network *network);
+static void __network_remove(struct connman_network *network);
+static int __network_connect(struct connman_network *network);
+static int __network_disconnect(struct connman_network *network);
+
+
+/* dbus request and reply */
+static int __dbus_request(const char *path, const char *interface,
+ const char *method,
+ DBusPendingCallNotifyFunction notify, void *user_data,
+ DBusFreeFunction free_function, int type, ...);
+
+static int __request_get_modems(void);
+static void __response_get_modems(DBusPendingCall *call, void *user_data);
+static int __request_get_services(const char *path);
+static void __response_get_services(DBusPendingCall *call, void *user_data);
+static int __request_get_contexts(struct telephony_modem *modem);
+static void __response_get_contexts(DBusPendingCall *call, void *user_data);
+static int __request_network_activate(struct connman_network *network);
+static void __response_network_activate(DBusPendingCall *call, void *user_data);
+static int __request_network_deactivate(struct connman_network *network);
+
+/* telephony internal function */
+static void __add_modem(const char *path, DBusMessageIter *prop);
+static void __add_service(struct telephony_modem *modem,
+ const char *service_path, DBusMessageIter *prop);
+static void __add_connman_device(const char *modem_path, const char *operator);
+static void __remove_connman_device(struct telephony_modem *modem);
+static void __remove_connman_networks(struct connman_device *device);
+static int __add_context(struct connman_device *device, const char *path,
+ DBusMessageIter *prop);
+
+/* signal handler */
+static gboolean __changed_modem(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __added_modem(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __removed_modem(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __changed_service(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __added_service(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __removed_service(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __changed_context(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __added_context(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+static gboolean __removed_context(DBusConnection *connection,
+ DBusMessage *message, void *user_data);
+
+/* device driver */
+static struct connman_device_driver modem_driver = {
+ .name = "device",
+ .type = CONNMAN_DEVICE_TYPE_CELLULAR,
+ .probe = __modem_probe,
+ .remove = __modem_remove,
+ .enable = __modem_enable,
+ .disable = __modem_disable,
+};
+
+/* network driver */
+static struct connman_network_driver network_driver = {
+ .name = "network",
+ .type = CONNMAN_NETWORK_TYPE_CELLULAR,
+ .probe = __network_probe,
+ .remove = __network_remove,
+ .connect = __network_connect,
+ .disconnect = __network_disconnect,
+};
+
+static int tech_probe(struct connman_technology *technology)
+{
+ return 0;
+}
+
+static void tech_remove(struct connman_technology *technology)
+{
+ return;
+}
+
+static struct connman_technology_driver tech_driver = {
+ .name = "cellular",
+ .type = CONNMAN_SERVICE_TYPE_CELLULAR,
+ .probe = tech_probe,
+ .remove = tech_remove,
+};
+
+/* local function */
+static void telephony_connect(DBusConnection *connection, void *user_data)
+{
+ DBG("connection %p", connection);
+ modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, __remove_modem);
+ service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, __remove_service);
+ network_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, __remove_network);
+
+ __request_get_modems();
+}
+
+static void telephony_disconnect(DBusConnection *connection, void *user_data)
+{
+ DBG("connection %p", connection);
+
+ if (modem_hash != NULL) {
+ g_hash_table_destroy(modem_hash);
+ modem_hash = NULL;
+ }
+
+ if (network_hash != NULL) {
+ g_hash_table_destroy(network_hash);
+ network_hash = NULL;
+ }
+}
+
+static void __remove_modem(gpointer data)
+{
+ struct telephony_modem *modem = data;
+
+ __remove_connman_device(modem);
+
+ g_free(modem->path);
+ g_free(modem->operator);
+ g_free(modem);
+}
+
+static void __remove_service(gpointer data)
+{
+ struct telephony_service *service = data;
+
+ g_free(service->path);
+ g_free(service->act);
+ g_free(service);
+}
+
+static void __remove_network(gpointer data)
+{
+ struct telephony_network *info = data;
+ struct connman_device *device;
+
+ device = connman_network_get_device(info->network);
+ if (device != NULL)
+ connman_device_remove_network(device, info->network);
+
+ connman_network_unref(info->network);
+
+ g_free(info->path);
+
+ connman_ipaddress_free(info->ipv4_address);
+ connman_ipaddress_free(info->ipv6_address);
+
+ g_free(info);
+}
+
+static void __set_device_powered(struct telephony_modem *modem,
+ gboolean powered)
+{
+ DBG("set modem(%s) powered(%d)", modem->path, powered);
+
+ if (modem->device)
+ connman_device_set_powered(modem->device, powered);
+}
+
+static int __check_device_powered(const char *path, gboolean powered)
+{
+ struct telephony_modem *modem = g_hash_table_lookup(modem_hash, path);
+
+ if (modem == NULL)
+ return -ENODEV;
+
+ DBG("check modem (%s) powered (%d)", modem->path, modem->powered);
+
+ if (modem->powered == powered)
+ return -EALREADY;
+
+ return 0;
+}
+
+static int __modem_probe(struct connman_device *device)
+{
+ DBG("device %p", device);
+ return 0;
+}
+
+static void __modem_remove(struct connman_device *device)
+{
+ DBG("device %p", device);
+}
+
+static int __modem_enable(struct connman_device *device)
+{
+ const char *path = connman_device_get_string(device, "Path");
+ DBG("device %p, path, %s", device, path);
+
+ return __check_device_powered(path, TRUE);
+}
+
+static int __modem_disable(struct connman_device *device)
+{
+ const char *path = connman_device_get_string(device, "Path");
+ DBG("device %p, path, %s", device, path);
+
+ return __check_device_powered(path, FALSE);
+}
+
+static int __network_probe(struct connman_network *network)
+{
+ DBG("network_prove network(%p)", network);
+ return 0;
+}
+
+static int __network_connect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ return __request_network_activate(network);
+}
+
+static int __network_disconnect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ if (connman_network_get_associating(network) == TRUE)
+ connman_network_clear_associating(network);
+
+ connman_network_set_associating(network, FALSE);
+
+ return __request_network_deactivate(network);
+}
+
+static void __network_remove(struct connman_network *network)
+{
+ char const *path = connman_network_get_string(network, "Path");
+ DBG("network %p path %s", network, path);
+
+ g_hash_table_remove(network_hash, path);
+}
+
+static int __dbus_request(const char *path, const char *interface,
+ const char *method,
+ DBusPendingCallNotifyFunction notify, void *user_data,
+ DBusFreeFunction free_function, int type, ...)
+{
+ DBusMessage *message;
+ DBusPendingCall *call;
+ dbus_bool_t ok;
+ va_list va;
+
+ DBG("path %s %s.%s", path, interface, method);
+
+ if (path == NULL)
+ return -EINVAL;
+
+ message = dbus_message_new_method_call(PS_DBUS_SERVICE, path, interface, method);
+ if (message == NULL)
+ return -ENOMEM;
+
+ dbus_message_set_auto_start(message, FALSE);
+
+ va_start(va, type);
+ ok = dbus_message_append_args_valist(message, type, va);
+ va_end(va);
+
+ if (!ok)
+ return -ENOMEM;
+
+ if (dbus_connection_send_with_reply(connection, message,
+ &call, TIMEOUT) == FALSE) {
+ connman_error("Failed to call %s.%s", interface, method);
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ if (call == NULL) {
+ connman_error("D-Bus connection not available");
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ dbus_pending_call_set_notify(call, notify, user_data, free_function);
+
+ dbus_message_unref(message);
+
+ return -EINPROGRESS;
+}
+
+static int __request_get_modems(void)
+{
+ DBG("request get modem");
+ /* call connect master */
+ return __dbus_request("/", PS_MASTER_INTERFACE, GET_MODEMS,
+ __response_get_modems, NULL, NULL, DBUS_TYPE_INVALID);
+}
+
+static void __response_get_modems(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args, dict;
+
+ DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("GetModems() %s %s", error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(reply));
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ /* DBG("message type (%d) dic(%d)",
+ * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
+ */
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry, property;
+ const char *modem_path;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &modem_path);
+ DBG("modem path (%s)", modem_path);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &property);
+
+ __add_modem(modem_path, &property);
+
+ dbus_message_iter_next(&dict);
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+}
+
+static int __request_get_services(const char *path)
+{
+ DBG("request get service");
+ return __dbus_request(path, PS_MODEM_INTERFACE, GET_SERVICES,
+ __response_get_services, g_strdup(path),
+ g_free, DBUS_TYPE_INVALID);
+}
+
+static void __response_get_services(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args, dict;
+
+ const char *path = user_data;
+ struct telephony_modem *modem;
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL)
+ return;
+ if (modem->device == NULL)
+ return;
+
+ DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("GetServices() %s %s", error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(reply));
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ /* DBG("message type (%d) dic(%d)",
+ * dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
+ */
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry, property;
+ const char *service_path;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &service_path);
+ DBG("service path (%s)", service_path);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &property);
+
+ __add_service(modem, service_path, &property);
+
+ dbus_message_iter_next(&dict);
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+}
+
+static int __request_get_contexts(struct telephony_modem *modem)
+{
+ DBG("request get contexts");
+ return __dbus_request(modem->s_service->path,
+ PS_SERVICE_INTERFACE, GET_CONTEXTS,
+ __response_get_contexts, g_strdup(modem->path),
+ g_free, DBUS_TYPE_INVALID);
+}
+
+static void __response_get_contexts(DBusPendingCall *call, void *user_data)
+{
+ DBusError error;
+ DBusMessage *reply;
+ DBusMessageIter args, dict;
+
+ const char *path = user_data;
+ struct telephony_modem *modem;
+
+ DBG("");
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL)
+ return;
+ if (modem->s_service == NULL)
+ return;
+ if (modem->device == NULL)
+ return;
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("GetContexts() %s %s", error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(reply));
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry, property;
+ const char *context_path;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &context_path);
+ DBG("context path (%s)", context_path);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &property);
+
+ __add_context(modem->device, context_path, &property);
+
+ dbus_message_iter_next(&dict);
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+}
+
+static int __request_network_activate(struct connman_network *network)
+{
+ int n_modems;
+ const char *path = NULL;
+ struct telephony_modem *modem = NULL;
+
+ n_modems = g_hash_table_size(modem_hash);
+ path = connman_network_get_string(network, "Path");
+ modem = connman_device_get_data(connman_network_get_device(network));
+ DBG("network %p, path %s, modem %s[%d]", network, path, modem->path,
+ telephony_default_subscription_id);
+
+ if (modem && n_modems > 1 && g_str_has_suffix(path, "_1") == TRUE) {
+ char *subscribe_id = g_strdup_printf("%d", telephony_default_subscription_id);
+
+ if (g_str_has_suffix(modem->path, subscribe_id) != TRUE) {
+ g_free(subscribe_id);
+ return -ENOLINK;
+ }
+ g_free(subscribe_id);
+ }
+
+ return __dbus_request(path, PS_CONTEXT_INTERFACE, ACTIVATE_CONTEXT,
+ __response_network_activate,
+ g_strdup(path), NULL, DBUS_TYPE_INVALID);
+}
+
+static gboolean __check_network_available(struct connman_network *network)
+{
+ if (network == NULL || connman_network_get_device(network) == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void __response_network_activate(DBusPendingCall *call, void *user_data)
+{
+ DBG("network activation response");
+
+ DBusError error;
+ DBusMessage *reply;
+
+ struct telephony_network *info;
+ const char *path = user_data;
+
+ info = g_hash_table_lookup(network_hash, path);
+ reply = dbus_pending_call_steal_reply(call);
+
+ if (info == NULL)
+ goto done;
+
+ if (__check_network_available(info->network) == FALSE) {
+ g_hash_table_remove(network_hash, path);
+ goto done;
+ }
+
+ dbus_error_init(&error);
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("connection activate() %s %s",
+ error.name, error.message);
+
+ if (connman_network_get_associating(info->network) == TRUE)
+ connman_network_set_error(info->network,
+ CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+
+ if (connman_network_get_connecting(info->network) == TRUE)
+ connman_network_set_error(info->network,
+ CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
+
+ if (connman_network_get_index(info->network) < 0)
+ connman_network_set_error(info->network,
+ CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+
+ dbus_error_free(&error);
+ goto done;
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+}
+
+static int __request_network_deactivate(struct connman_network *network)
+{
+ const char *path = connman_network_get_string(network, "Path");
+ DBG("network %p, path %s", network, path);
+
+ return __dbus_request(path, PS_CONTEXT_INTERFACE, DEACTIVATE_CONTEXT,
+ NULL, NULL, NULL, DBUS_TYPE_INVALID);
+}
+
+static void __response_get_default_subscription_id(DBusPendingCall *call,
+ void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args;
+
+ DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("GetDefaultDataSubscription() %s %s", error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(reply));
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
+ DBG("default subscription: %d", telephony_default_subscription_id);
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+}
+
+static int __request_get_default_subscription_id(const char *path)
+{
+ int ret;
+ char *telephony_modem_path = NULL;
+
+ telephony_modem_path = g_strdup_printf("/org/tizen/telephony%s", path);
+ DBG("request get default subscription id %s", telephony_modem_path);
+
+ ret = __dbus_request(telephony_modem_path,
+ "org.tizen.telephony.Network", "GetDefaultDataSubscription",
+ __response_get_default_subscription_id, NULL, NULL, DBUS_TYPE_INVALID);
+
+ g_free(telephony_modem_path);
+ return ret;
+}
+
+static void __add_modem(const char *path, DBusMessageIter *prop)
+{
+ struct telephony_modem *modem;
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem != NULL)
+ return;
+
+ modem = g_try_new0(struct telephony_modem, 1);
+ if (modem == NULL)
+ return;
+
+ modem->path = g_strdup(path);
+ modem->device = NULL;
+ modem->s_service = NULL;
+
+ g_hash_table_insert(modem_hash, g_strdup(path), modem);
+
+ while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *tmp;
+
+ dbus_message_iter_recurse(prop, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key (%s) value(%s)", key, tmp);
+
+ if (g_strcmp0(key, "powered") == 0) {
+ modem->powered = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "operator") == 0) {
+ modem->operator = g_strdup(tmp);
+ } else if (g_strcmp0(key, "sim_init") == 0) {
+ modem->sim_init = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "flight_mode") == 0) {
+ modem->flight_mode = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "roaming_allowed") == 0) {
+ modem->roaming_allowed = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "data_allowed") == 0) {
+ modem->data_allowed = STRING2BOOL(tmp);
+ }
+ dbus_message_iter_next(prop);
+ }
+
+ __add_connman_device(path, modem->operator);
+ __set_device_powered(modem, modem->powered);
+
+ if (g_hash_table_size(modem_hash) > 1)
+ __request_get_default_subscription_id(modem->path);
+
+ if (modem->powered != TRUE) {
+ DBG("modem is not powered");
+ return;
+ }
+
+ __request_get_services(modem->path);
+}
+
+static void __add_service(struct telephony_modem *modem,
+ const char *service_path, DBusMessageIter *prop)
+{
+ struct telephony_service *service;
+
+ if (modem->s_service != NULL)
+ return;
+
+ service = g_try_new0(struct telephony_service, 1);
+ if (service == NULL)
+ return;
+
+ service->path = g_strdup(service_path);
+ service->p_modem = modem;
+ g_hash_table_insert(service_hash, g_strdup(service_path), service);
+
+ while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *tmp;
+
+ dbus_message_iter_recurse(prop, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key (%s) value(%s)", key, tmp);
+
+ if (g_strcmp0(key, "roaming") == 0) {
+ service->roaming = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "act") == 0) {
+ service->act = g_strdup(tmp);
+ } else if (g_strcmp0(key, "ps_attached") == 0) {
+ service->ps_attached = STRING2BOOL(tmp);
+ }
+
+ dbus_message_iter_next(prop);
+ }
+
+ modem->s_service = service;
+ __request_get_contexts(modem);
+}
+
+static char *__get_ident(const char *path)
+{
+ char *pos;
+
+ if (*path != '/')
+ return NULL;
+
+ pos = strrchr(path, '/');
+ if (pos == NULL)
+ return NULL;
+
+ return pos + 1;
+}
+
+static void __add_connman_device(const char *modem_path, const char *operator)
+{
+ char* ident = NULL;
+ struct telephony_modem *modem;
+ struct connman_device *device;
+
+ DBG("path %s operator %s", modem_path, operator);
+
+ if (modem_path == NULL)
+ return;
+
+ if (operator == NULL)
+ return;
+
+ modem = g_hash_table_lookup(modem_hash, modem_path);
+ if (modem == NULL)
+ return;
+
+ if (modem->device) {
+ if (!g_strcmp0(operator,
+ connman_device_get_ident(modem->device)))
+ return;
+
+ __remove_connman_device(modem);
+ }
+
+ if (strlen(operator) == 0)
+ return;
+
+ device = connman_device_create(operator, CONNMAN_DEVICE_TYPE_CELLULAR);
+ if (device == NULL)
+ return;
+
+ ident = g_strdup_printf("%s_%s", __get_ident(modem_path), operator);
+ connman_device_set_ident(device, ident);
+ g_free(ident);
+
+ connman_device_set_string(device, "Path", modem_path);
+ connman_device_set_data(device, modem);
+
+ if (connman_device_register(device) < 0) {
+ connman_error("Failed to register cellular device");
+ connman_device_unref(device);
+ return;
+ }
+
+ modem->device = device;
+}
+
+static void __remove_connman_device(struct telephony_modem *modem)
+{
+ DBG("modem %p path %s device %p", modem, modem->path, modem->device);
+
+ if (modem->device == NULL)
+ return;
+
+ __remove_connman_networks(modem->device);
+
+ connman_device_unregister(modem->device);
+ connman_device_unref(modem->device);
+
+ modem->device = NULL;
+}
+
+static void __remove_connman_networks(struct connman_device *device)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ GSList *info_list = NULL;
+ GSList *list;
+
+ if (network_hash == NULL)
+ return;
+
+ g_hash_table_iter_init(&iter, network_hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ struct telephony_network *info = value;
+
+ if (connman_network_get_device(info->network) != device)
+ continue;
+
+ info_list = g_slist_append(info_list, info);
+ }
+
+ for (list = info_list; list != NULL; list = list->next) {
+ struct telephony_network *info = list->data;
+ connman_device_remove_network(device, info->network);
+ }
+
+ g_slist_free(info_list);
+}
+
+static gboolean connman_ipaddress_updated(struct connman_ipaddress *ipaddress,
+ const char *address, const char *gateway)
+{
+ if (ipaddress == NULL || address == NULL)
+ return FALSE;
+
+ if (g_strcmp0(ipaddress->local, address) != 0)
+ return TRUE;
+
+ if (g_strcmp0(ipaddress->gateway, gateway) != 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void __set_network_connected(struct telephony_network *network,
+ gboolean connected)
+{
+ gboolean setip = FALSE;
+
+ DBG("network %p connected %d", network, connected);
+
+ connman_network_set_index(network->network, network->if_index);
+ if (connman_network_get_connected(network->network) == connected)
+ return;
+
+ switch (network->ipv4_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ connman_network_set_ipv4_method(network->network,
+ network->ipv4_method);
+ break;
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ connman_network_set_ipv4_method(network->network,
+ network->ipv4_method);
+ connman_network_set_ipaddress(network->network,
+ network->ipv4_address);
+ setip = TRUE;
+ break;
+ }
+
+ switch (network->ipv6_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ break;
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ connman_network_set_ipv6_method(network->network,
+ network->ipv6_method);
+ setip = TRUE;
+ break;
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ connman_network_set_ipv6_method(network->network,
+ network->ipv6_method);
+ connman_network_set_ipaddress(network->network,
+ network->ipv6_address);
+ setip = TRUE;
+ break;
+ }
+
+ if (setip == TRUE)
+ connman_network_set_connected(network->network, connected);
+}
+
+static gboolean __set_network_context(
+ struct telephony_network *network,
+ DBusMessageIter *dict)
+{
+ int index = 0;
+ gboolean active = FALSE;
+ gboolean routing_only = FALSE;
+ gboolean ipv4_updated = FALSE;
+ gboolean ipv6_updated = FALSE;
+ gboolean ipv6_link_only = FALSE;
+ gboolean default_internet = FALSE;
+ gboolean active_proxy = FALSE;
+ char **proxies = NULL;
+ const char *dev_name = NULL;
+ const char *proxy_addr = NULL;
+ char *ipv4_addr = NULL, *ipv4_gw = NULL, *ipv4_netmask = NULL,
+ *ipv4_dns1 = NULL, *ipv4_dns2 = NULL;
+ char *ipv6_addr = NULL, *ipv6_gw = NULL, *ipv6_netmask = NULL,
+ *ipv6_dns1 = NULL, *ipv6_dns2 = NULL;
+ struct connman_service *service;
+
+ while (dbus_message_iter_get_arg_type(dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *value;
+
+ dbus_message_iter_recurse(dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+
+ if (g_strcmp0(key, "dev_name") == 0) {
+ dbus_message_iter_get_basic(&entry, &dev_name);
+ DBG("dev_name (%s)", dev_name);
+ } else if (g_strcmp0(key, "proxy") == 0) {
+ dbus_message_iter_get_basic(&entry, &proxy_addr);
+ DBG("proxy_addr (%s)", proxy_addr);
+ } else if (g_strcmp0(key, "ipv4_address") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv4_addr);
+ DBG("ipv4_addr (%s)", ipv4_addr);
+ } else if (g_strcmp0(key, "ipv4_gateway") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv4_gw);
+ DBG("ipv4_gw (%s)", ipv4_gw);
+ } else if (g_strcmp0(key, "ipv4_netmask") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv4_netmask);
+ DBG("ipv4_netmask (%s)", ipv4_netmask);
+ } else if (g_strcmp0(key, "ipv4_dns1") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv4_dns1);
+ DBG("ipv4_dns1 (%s)", ipv4_dns1);
+ } else if (g_strcmp0(key, "ipv4_dns2") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv4_dns2);
+ DBG("ipv4_dns2 (%s)", ipv4_dns2);
+ } else if (g_strcmp0(key, "ipv6_address") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv6_addr);
+ DBG("ipv6 address (%s)", ipv6_addr);
+ } else if (g_strcmp0(key, "ipv6_gateway") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv6_gw);
+ DBG("ipv6_gw (%s)", ipv6_gw);
+ } else if (g_strcmp0(key, "ipv6_netmask") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv6_netmask);
+ DBG("ipv6_netmask (%s)", ipv6_netmask);
+ } else if (g_strcmp0(key, "ipv6_dns1") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv6_dns1);
+ DBG("ipv6_dns1 (%s)", ipv6_dns1);
+ } else if (g_strcmp0(key, "ipv6_dns2") == 0) {
+ dbus_message_iter_get_basic(&entry, &ipv6_dns2);
+ DBG("ipv6_dns2 (%s)", ipv6_dns2);
+ } else if (g_strcmp0(key, "active") == 0) {
+ dbus_message_iter_get_basic(&entry, &value);
+ DBG("active (%s)", value);
+ active = STRING2BOOL(value);
+ } else if (g_strcmp0(key, "routing_only") == 0) {
+ dbus_message_iter_get_basic(&entry, &value);
+ DBG("routing_only (%s)", value);
+ routing_only = STRING2BOOL(value);
+ network->routing_only = routing_only;
+ } else if (g_strcmp0(key, "ipv6_link_only") == 0) {
+ dbus_message_iter_get_basic(&entry, &value);
+ DBG("ipv6_link_only (%s)", value);
+ ipv6_link_only = STRING2BOOL(value);
+ network->ipv6_link_only = ipv6_link_only;
+ }
+ else if (g_strcmp0(key, "default_internet_conn") == 0) {
+ dbus_message_iter_get_basic(&entry, &value);
+ DBG("default_internet (%s)", value);
+ default_internet = STRING2BOOL(value);
+ }
+
+ dbus_message_iter_next(dict);
+ }
+
+ if(routing_only){
+ //context active does not effect the connman service status.
+ //it only for setting the routing path.
+ DBG("routing_only(%d), active(%d)", routing_only, active);
+ return active;
+ }
+
+ if (g_strcmp0(proxy_addr, ":") == 0)
+ proxy_addr = NULL;
+ if (g_strcmp0(ipv4_addr, "0.0.0.0") == 0)
+ ipv4_addr = NULL;
+ if (g_strcmp0(ipv4_gw, "0.0.0.0") == 0)
+ ipv4_gw = NULL;
+ if (g_strcmp0(ipv4_netmask, "0.0.0.0") == 0)
+ ipv4_netmask = NULL;
+ if (g_strcmp0(ipv4_dns1, "0.0.0.0") == 0)
+ ipv4_dns1 = NULL;
+ if (g_strcmp0(ipv4_dns2, "0.0.0.0") == 0)
+ ipv4_dns2 = NULL;
+ if (g_strcmp0(ipv6_addr, "::") == 0)
+ ipv6_addr = NULL;
+ if (g_strcmp0(ipv6_gw, "::") == 0)
+ ipv6_gw = NULL;
+ if (g_strcmp0(ipv6_netmask, "::") == 0)
+ ipv6_netmask = NULL;
+ if (g_strcmp0(ipv6_dns1, "::") == 0)
+ ipv6_dns1 = NULL;
+ if (g_strcmp0(ipv6_dns2, "::") == 0)
+ ipv6_dns2 = NULL;
+
+ connman_network_set_bool(network->network, "DefaultInternet",
+ (bool)default_internet);
+
+ service = connman_service_lookup_from_network(network->network);
+ if (service == NULL)
+ return FALSE;
+
+ if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
+ /* Wi-Fi technology is always a top priority */
+ if (active == TRUE &&
+ connman_service_is_no_ref_user_pdn_connection(service) == TRUE &&
+ connman_service_get_type(connman_service_get_default_connection())
+ == CONNMAN_SERVICE_TYPE_WIFI) {
+ __request_network_deactivate(network->network);
+
+ return FALSE;
+ }
+ }
+
+ /* interface index set */
+ if (dev_name != NULL) {
+ index = connman_inet_ifindex(dev_name);
+ network->if_index = index;
+ DBG("interface index %d", index);
+ }
+
+ /* proxy set */
+ if (active == TRUE &&
+ connman_network_get_connected(network->network) == TRUE)
+ active_proxy = TRUE;
+
+ proxies = connman_service_get_proxy_servers(service);
+ if (proxies != NULL) {
+ if (proxy_addr == NULL)
+ connman_service_set_proxy(service, proxy_addr, active_proxy);
+ else if (g_strcmp0(proxy_addr, proxies[0]) != 0)
+ connman_service_set_proxy(service, proxy_addr, active_proxy);
+ } else if (proxy_addr != NULL)
+ connman_service_set_proxy(service, proxy_addr, active_proxy);
+
+ if (proxies != NULL)
+ g_strfreev(proxies);
+
+ __connman_service_nameserver_clear(service);
+
+ /* ipv4 set */
+ if (network->ipv4_address == NULL)
+ network->ipv4_address =
+ connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
+
+ if (network->ipv4_address == NULL)
+ return FALSE;
+
+ if (ipv4_addr == NULL && active == TRUE)
+ network->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;
+ else
+ network->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
+
+ connman_network_set_ipv4_method(network->network, network->ipv4_method);
+
+ ipv4_updated = connman_ipaddress_updated(network->ipv4_address,
+ ipv4_addr, ipv4_gw);
+ if (ipv4_updated == TRUE)
+ connman_ipaddress_set_ipv4(network->ipv4_address, ipv4_addr,
+ ipv4_netmask, ipv4_gw);
+
+ if (ipv4_dns1)
+#if defined TIZEN_EXT
+ __connman_service_nameserver_append(service, ipv4_dns1, FALSE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+#else
+ __connman_service_nameserver_append(service, ipv4_dns1, FALSE);
+#endif
+ //if (ipv4_dns2)
+ if (ipv4_dns2 && !ipv4_dns1)
+#if defined TIZEN_EXT
+ __connman_service_nameserver_append(service, ipv4_dns2, FALSE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+#else
+ __connman_service_nameserver_append(service, ipv4_dns2, FALSE);
+#endif
+ /* ipv6 set */
+ if (network->ipv6_address == NULL)
+ network->ipv6_address =
+ connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
+
+ if (network->ipv6_address == NULL)
+ return FALSE;
+
+ if(ipv6_link_only)
+ network->ipv6_method = CONNMAN_IPCONFIG_METHOD_AUTO;
+ else
+ network->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED;
+
+ if (ipv6_addr == NULL)
+ network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;
+
+ connman_network_set_ipv6_method(network->network, network->ipv6_method);
+
+ ipv6_updated = connman_ipaddress_updated(network->ipv6_address,
+ ipv6_addr, ipv6_gw);
+ if (ipv6_updated == TRUE)
+ connman_ipaddress_set_ipv6(network->ipv6_address, ipv6_addr,
+ 64, ipv6_gw);
+
+ if (ipv6_dns1)
+#if defined TIZEN_EXT
+ __connman_service_nameserver_append(service, ipv6_dns1, FALSE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
+ __connman_service_nameserver_append(service, ipv6_dns1, FALSE);
+#endif
+ //if (ipv6_dns2)
+ if (ipv6_dns2 && !ipv6_dns1)
+#if defined TIZEN_EXT
+ __connman_service_nameserver_append(service, ipv6_dns2, FALSE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
+ __connman_service_nameserver_append(service, ipv6_dns2, FALSE);
+#endif
+
+ if (active == TRUE &&
+ connman_network_get_connected(network->network) == TRUE) {
+ if (ipv4_updated == TRUE || ipv6_updated == TRUE) {
+ DBG("IPv4 updated %d, IPv6 updated %d", ipv4_updated, ipv6_updated);
+
+ __set_network_connected(network, FALSE);
+ } else {
+ DBG("Already connected");
+
+ return active;
+ }
+ }
+
+ if (active == TRUE)
+ connman_network_set_associating(network->network, TRUE);
+
+ return active;
+}
+
+static int __add_context(struct connman_device *device, const char *path,
+ DBusMessageIter *prop)
+{
+ char *ident;
+ gboolean active = FALSE;
+
+ struct telephony_modem *modem = connman_device_get_data(device);
+ struct connman_network *network;
+ struct telephony_network *info;
+
+ DBG("modem %p device %p path %s", modem, device, path);
+
+ ident = __get_ident(path);
+
+ network = connman_device_get_network(device, ident);
+ if (network != NULL)
+ return -EALREADY;
+
+ info = g_hash_table_lookup(network_hash, path);
+ if (info != NULL) {
+ DBG("path %p already exists with device %p", path,
+ connman_network_get_device(info->network));
+
+ if (connman_network_get_device(info->network))
+ return -EALREADY;
+
+ g_hash_table_remove(network_hash, path);
+ }
+
+ network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR);
+ if (network == NULL)
+ return -ENOMEM;
+
+ info = g_try_new0(struct telephony_network, 1);
+ if (info == NULL) {
+ connman_network_unref(network);
+ return -ENOMEM;
+ }
+
+ info->path = g_strdup(path);
+
+ connman_ipaddress_clear(info->ipv4_address);
+ connman_ipaddress_clear(info->ipv6_address);
+
+ info->network = network;
+
+ connman_network_set_string(network, "Path", path);
+ connman_network_set_name(network, path);
+
+ connman_network_set_group(network, ident);
+
+ g_hash_table_insert(network_hash, g_strdup(path), info);
+
+ connman_network_set_available(network, TRUE);
+ connman_network_set_bool(network, "Roaming", (bool)modem->s_service->roaming);
+
+ if (connman_device_add_network(device, network) != 0) {
+ g_hash_table_remove(network_hash, path);
+ return -EIO;
+ }
+
+ active = __set_network_context(info, prop);
+ if(info->routing_only){
+ int err = 0;
+ struct connman_service *routing_service;
+ struct connman_ipconfig *routing_ipconfig;
+
+ if(!active)
+ return TRUE;
+
+ routing_service = connman_service_lookup_from_network(info->network);
+ routing_ipconfig = __connman_service_get_ip4config(routing_service);
+ err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
+
+ DBG("set gateway rv(%d)", err);
+ return TRUE;
+ }
+
+ if (active == TRUE && (connman_network_get_associating(network) == TRUE ||
+ connman_network_get_connecting(network) == TRUE))
+ __set_network_connected(info, active);
+
+ return 0;
+}
+
+static gboolean __changed_modem(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ gboolean old_powered;
+ DBusMessageIter args, dict;
+ struct telephony_modem *modem;
+ const char *path = dbus_message_get_path(message);
+
+ DBG("modem changed signal %s", path);
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL) {
+ DBG("modem object does not exists");
+ return TRUE;
+ }
+
+ old_powered = modem->powered;
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *tmp;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key(%s), value(%s)", key, tmp);
+
+ if (g_strcmp0(key, "powered") == 0) {
+ modem->powered = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "operator") == 0) {
+ modem->operator = g_strdup(tmp);
+ } else if (g_strcmp0(key, "sim_init") == 0) {
+ modem->sim_init = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "flight_mode") == 0) {
+ modem->flight_mode = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "roaming_allowed") == 0) {
+ modem->roaming_allowed = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "data_allowed") == 0) {
+ modem->data_allowed = STRING2BOOL(tmp);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ if (modem->device == NULL)
+ __add_connman_device(path, modem->operator);
+
+ if (old_powered != modem->powered)
+ __set_device_powered(modem, modem->powered);
+
+ if (modem->powered != TRUE) {
+ DBG("modem is not powered");
+ return TRUE;
+ }
+
+ if (modem->s_service == NULL) {
+ __request_get_services(modem->path);
+ return TRUE;
+ }
+
+ DBG("modem(%s) flight mode(%d) data allowed(%d)",
+ modem->path, modem->flight_mode, modem->data_allowed);
+
+ return TRUE;
+}
+
+static gboolean __added_modem(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ const char *modem_path = NULL;
+ DBusMessageIter args, dict, tmp;
+
+ DBG("modem added signal (%s)", dbus_message_get_signature(message));
+
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+ memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
+
+ while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *value;
+
+ dbus_message_iter_recurse(&tmp, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &value);
+
+ DBG("key (%s) value(%s)", key, value);
+
+ if (g_strcmp0(key, "path") == 0)
+ modem_path = g_strdup(value);
+
+ dbus_message_iter_next(&tmp);
+ }
+
+ if (modem_path != NULL)
+ __add_modem(modem_path, &dict);
+
+ return TRUE;
+}
+
+static gboolean __removed_modem(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter iter;
+ const char *modem_path;
+
+ DBG("modem removed signal");
+
+ if (dbus_message_iter_init(message, &iter) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &modem_path);
+ g_hash_table_remove(modem_hash, modem_path);
+
+ return TRUE;
+}
+
+static gboolean __changed_service(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter args, dict;
+ struct telephony_modem *modem;
+ gboolean roaming_option = TRUE;
+ struct telephony_service *s_service;
+ const char *service_path = dbus_message_get_path(message);
+
+ DBG("service changed signal %s", service_path);
+
+ s_service = g_hash_table_lookup(service_hash, service_path);
+ if (s_service == NULL) {
+ DBG("service object does not exists");
+ return TRUE;
+ }
+
+ modem = s_service->p_modem;
+ if (modem == NULL) {
+ DBG("modem object does not exists");
+ return TRUE;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *tmp;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key(%s), value(%s)", key, tmp);
+
+ if (g_strcmp0(key, "roaming") == 0) {
+ s_service->roaming = STRING2BOOL(tmp);
+ } else if (g_strcmp0(key, "act") == 0) {
+ s_service->act = g_strdup(tmp);
+ } else if (g_strcmp0(key, "ps_attached") == 0) {
+ s_service->ps_attached = STRING2BOOL(tmp);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ roaming_option &= (!s_service->roaming && !modem->roaming_allowed)
+ || modem->roaming_allowed;
+
+ return TRUE;
+}
+
+static gboolean __added_service(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct telephony_modem *modem;
+ const char *service_path = NULL;
+ DBusMessageIter args, dict, tmp;
+ const char *path = dbus_message_get_path(message);
+
+ DBG("service added signal %s", path);
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL || modem->device == NULL)
+ return TRUE;
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+ memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
+
+ while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *value;
+
+ dbus_message_iter_recurse(&tmp, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &value);
+
+ DBG("key (%s) value(%s)", key, value);
+
+ if (g_strcmp0(key, "path") == 0)
+ service_path = value;
+
+ dbus_message_iter_next(&tmp);
+ }
+
+ if (service_path != NULL)
+ __add_service(modem, service_path, &dict);
+
+ return TRUE;
+}
+
+static gboolean __removed_service(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter iter;
+ const char *service_path;
+
+ DBG("service removed signal");
+
+ if (dbus_message_iter_init(message, &iter) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &service_path);
+ g_hash_table_remove(service_hash, service_path);
+
+ return TRUE;
+}
+
+static gboolean __changed_context(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ gboolean active = FALSE;
+ DBusMessageIter args, dict;
+ struct telephony_network *info;
+ const char *path = dbus_message_get_path(message);
+
+ DBG("network changed signal %s", path);
+
+ info = g_hash_table_lookup(network_hash, path);
+ if (info == NULL)
+ return TRUE;
+
+ if (__check_network_available(info->network) == FALSE) {
+ g_hash_table_remove(network_hash, path);
+ return TRUE;
+ }
+
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ active = __set_network_context(info, &dict);
+ if(info->routing_only){
+ int err = 0;
+ struct connman_service *routing_service;
+ struct connman_ipconfig *routing_ipconfig;
+
+ if(!active)
+ return TRUE;
+
+ routing_service = connman_service_lookup_from_network(info->network);
+ routing_ipconfig = __connman_service_get_ip4config(routing_service);
+ err = __connman_ipconfig_gateway_add(routing_ipconfig, routing_service);
+
+ DBG("set gateway rv(%d)", err);
+ return TRUE;
+ }
+
+ __set_network_connected(info, active);
+
+ if (active == FALSE &&
+ connman_network_get_connecting(info->network) == TRUE)
+ connman_network_set_connected(info->network, FALSE);
+
+ return TRUE;
+}
+
+static gboolean __added_context(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ const char *network_path = NULL;
+ DBusMessageIter args, dict, tmp;
+ struct telephony_modem *modem = NULL;
+ struct telephony_service *service = NULL;
+ const char *path = dbus_message_get_path(message);
+
+ DBG("network added signal %s", path);
+
+ service = g_hash_table_lookup(service_hash, path);
+ if (service == NULL || service->p_modem == NULL)
+ return TRUE;
+
+ modem = service->p_modem;
+ if (modem == NULL || modem->device == NULL)
+ return TRUE;
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+ memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
+
+ while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *value;
+
+ dbus_message_iter_recurse(&tmp, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &value);
+
+ DBG("key (%s) value(%s)", key, value);
+
+ if (g_strcmp0(key, "path") == 0)
+ network_path = g_strdup(value);
+
+ dbus_message_iter_next(&tmp);
+ }
+
+ if (network_path != NULL)
+ __add_context(modem->device, network_path, &dict);
+
+ return TRUE;
+}
+
+static gboolean __removed_context(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter iter;
+ const char *network_path = NULL;
+ struct telephony_service *service = NULL;
+ const char *path = dbus_message_get_path(message);
+
+ DBG("network removed signal %s", path);
+
+ service = g_hash_table_lookup(service_hash, path);
+ if (service == NULL || service->p_modem == NULL)
+ return TRUE;
+
+ if (dbus_message_iter_init(message, &iter) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &network_path);
+ g_hash_table_remove(network_hash, network_path);
+
+ return TRUE;
+}
+
+static gboolean __changed_default_subscription(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ DBusMessageIter args;
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+ if (dbus_message_iter_init(message, &args) == FALSE)
+ return TRUE;
+
+ dbus_message_iter_get_basic(&args, &telephony_default_subscription_id);
+ DBG("default subscription: %d", telephony_default_subscription_id);
+
+ return TRUE;
+}
+
+/* telephony initialization */
+static guint watch = 0;
+static guint modem_watch = 0;
+static guint modem_added_watch = 0;
+static guint modem_removed_watch = 0;
+static guint service_watch = 0;
+static guint service_added_watch = 0;
+static guint service_removed_watch = 0;
+static guint context_watch = 0;
+static guint context_added_watch = 0;
+static guint context_removed_watch = 0;
+static guint default_subscription_watch = 0;
+
+static int telephony_init(void)
+{
+ int err;
+
+ DBG("telephony plugin");
+
+ connection = connman_dbus_get_connection();
+ if (connection == NULL)
+ return -EIO;
+
+ /* telephony watch */
+ watch = g_dbus_add_service_watch(connection, PS_DBUS_SERVICE,
+ telephony_connect, telephony_disconnect,
+ NULL, NULL);
+
+ modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_MODEM_INTERFACE,
+ PROPERTY_CHANGED,
+ __changed_modem,
+ NULL, NULL);
+
+ modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_MASTER_INTERFACE,
+ MODEM_ADDED,
+ __added_modem,
+ NULL, NULL);
+
+ modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_MASTER_INTERFACE,
+ MODEM_REMOVED,
+ __removed_modem,
+ NULL, NULL);
+
+ service_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_SERVICE_INTERFACE,
+ PROPERTY_CHANGED,
+ __changed_service,
+ NULL, NULL);
+
+ service_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_MODEM_INTERFACE,
+ SERVICE_ADDED,
+ __added_service,
+ NULL, NULL);
+
+ service_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_MODEM_INTERFACE,
+ SERVICE_REMOVED,
+ __removed_service,
+ NULL, NULL);
+
+ context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_CONTEXT_INTERFACE,
+ PROPERTY_CHANGED,
+ __changed_context,
+ NULL, NULL);
+
+ context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_SERVICE_INTERFACE,
+ CONTEXT_ADDED,
+ __added_context,
+ NULL, NULL);
+
+ context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ PS_SERVICE_INTERFACE,
+ CONTEXT_REMOVED,
+ __removed_context,
+ NULL, NULL);
+
+ default_subscription_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ "org.tizen.telephony.Network",
+ "DefaultDataSubscription",
+ __changed_default_subscription,
+ NULL, NULL);
+
+ if (watch == 0 || modem_watch == 0 || modem_added_watch == 0
+ || modem_removed_watch == 0 || service_watch == 0
+ || service_added_watch == 0 || context_watch == 0
+ || service_removed_watch == 0
+ || context_added_watch == 0
+ || context_removed_watch == 0
+ || default_subscription_watch == 0) {
+ err = -EIO;
+ goto remove;
+ }
+
+ err = connman_network_driver_register(&network_driver);
+ if (err < 0)
+ goto remove;
+
+ err = connman_device_driver_register(&modem_driver);
+ if (err < 0) {
+ connman_network_driver_unregister(&network_driver);
+ goto remove;
+ }
+
+ err = connman_technology_driver_register(&tech_driver);
+ if (err < 0) {
+ connman_device_driver_unregister(&modem_driver);
+ connman_network_driver_unregister(&network_driver);
+ goto remove;
+ }
+
+ return 0;
+
+remove:
+ g_dbus_remove_watch(connection, watch);
+ g_dbus_remove_watch(connection, modem_watch);
+ g_dbus_remove_watch(connection, modem_added_watch);
+ g_dbus_remove_watch(connection, modem_removed_watch);
+ g_dbus_remove_watch(connection, service_watch);
+ g_dbus_remove_watch(connection, service_added_watch);
+ g_dbus_remove_watch(connection, service_removed_watch);
+ g_dbus_remove_watch(connection, context_watch);
+ g_dbus_remove_watch(connection, context_added_watch);
+ g_dbus_remove_watch(connection, context_removed_watch);
+ g_dbus_remove_watch(connection, default_subscription_watch);
+
+ dbus_connection_unref(connection);
+ return err;
+}
+
+static void telephony_exit(void)
+{
+ g_dbus_remove_watch(connection, watch);
+ g_dbus_remove_watch(connection, modem_watch);
+ g_dbus_remove_watch(connection, modem_added_watch);
+ g_dbus_remove_watch(connection, modem_removed_watch);
+ g_dbus_remove_watch(connection, service_watch);
+ g_dbus_remove_watch(connection, service_added_watch);
+ g_dbus_remove_watch(connection, service_removed_watch);
+ g_dbus_remove_watch(connection, context_watch);
+ g_dbus_remove_watch(connection, context_added_watch);
+ g_dbus_remove_watch(connection, context_removed_watch);
+ g_dbus_remove_watch(connection, default_subscription_watch);
+
+ telephony_disconnect(connection, NULL);
+
+ connman_device_driver_unregister(&modem_driver);
+ connman_network_driver_unregister(&network_driver);
+
+ dbus_connection_unref(connection);
+}
+
+CONNMAN_PLUGIN_DEFINE(telephony, "Samsung Telephony Framework plug-in", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)
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
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;
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)
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;
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.
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->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);
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 (!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);
+#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;
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;
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;
default:
break;
}
+
+#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);
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)
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;
+#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);
+#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)
}
}
+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);
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);
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"))
.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,
+#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,
wifi_technology = NULL;
}
-static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
+static GSupplicantSSID *ssid_ap_init(const char *ssid,
+ const char *passphrase)
{
GSupplicantSSID *ap;
DBG("ifname %s result %d ", info->ifname, result);
- 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);
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;
goto failed;
info->ifname = g_strdup(ifname);
+ if (!info->ifname)
+ goto failed;
wifi->tethering_param->technology = technology;
wifi->tethering_param->ssid = ssid_ap_init(identifier, passphrase);
--- /dev/null
+[D-BUS Service]
+Name=net.connman
+Exec=/bin/false
+User=network_fw
+Group=network_fw
+SystemdService=connman.service
--- /dev/null
+
+[global]
+OfflineMode=false
+
+[WiFi]
+Enable=false
+
+[Bluetooth]
+Enable=true
+
+[Wired]
+Enable=true
+
+[Cellular]
+Enable=true
--- /dev/null
+#!/bin/sh
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+
+#------------------------------------------------------------#
+# connman patch script for upgrade (3.0 -> the latest tizen) #
+#------------------------------------------------------------#
+
+chmod 755 /var/lib/connman
+chown -R network_fw:network_fw /var/lib/connman
#!/bin/sh
-DAEMON=@sbindir@/connmand
+DAEMON=@bindir@/connmand
DESC="Connection Manager"
. /lib/lsb/init-functions
+++ /dev/null
-d @runstatedir@/connman - - - -
-L+ /etc/resolv.conf - - - - @runstatedir@/connman/resolv.conf
--- /dev/null
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010,2012-2014 BMW Car IT GmbH.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <libgen.h>
+
+#include <dbus/dbus.h>
+
+extern char **environ;
+
+static void print(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vsyslog(LOG_INFO, format, ap);
+ va_end(ap);
+}
+
+static void append(DBusMessageIter *dict, const char *pattern)
+{
+ DBusMessageIter entry;
+ const char *key, *value;
+ char *delim;
+
+ delim = strchr(pattern, '=');
+ *delim = '\0';
+
+ key = pattern;
+ value = delim + 1;
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &value);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+int main(int argc, char *argv[])
+{
+ DBusConnection *conn;
+ DBusError error;
+ DBusMessage *msg;
+ DBusMessageIter iter, dict;
+ char **envp, *busname, *interface, *path, *reason;
+ int ret = 0;
+
+ openlog(basename(argv[0]), LOG_NDELAY | LOG_PID, LOG_DAEMON);
+
+ busname = getenv("CONNMAN_BUSNAME");
+ interface = getenv("CONNMAN_INTERFACE");
+ path = getenv("CONNMAN_PATH");
+
+ reason = getenv("script_type");
+
+ if (!busname || !interface || !path || !reason) {
+ print("Required environment variables not set; "
+ "bus=%s iface=%s path=%s reason=%s",
+ busname, interface, path, reason);
+ ret = 1;
+ goto out;
+ }
+ dbus_error_init(&error);
+
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (!conn) {
+ if (dbus_error_is_set(&error)) {
+ print("%s", error.message);
+ dbus_error_free(&error);
+ } else
+ print("Failed to get on system bus");
+
+ goto out;
+ }
+
+ msg = dbus_message_new_method_call(busname, path,
+ interface, "notify");
+ if (!msg) {
+ dbus_connection_unref(conn);
+ print("Failed to allocate method call");
+ goto out;
+ }
+
+ dbus_message_set_no_reply(msg, TRUE);
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &reason,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_iter_init_append(msg, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ for (envp = environ; envp && *envp; envp++)
+ append(&dict, *envp);
+
+ dbus_message_iter_close_container(&iter, &dict);
+
+ if (!dbus_connection_send(conn, msg, NULL)) {
+ print("Failed to send message");
+ goto out;
+ }
+
+ dbus_connection_flush(conn);
+
+ dbus_message_unref(msg);
+
+ dbus_connection_unref(conn);
+
+out:
+ closelog();
+
+ return ret;
+}
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;
/*
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
- * Copyright (C) 2016 Yann E. MORIN <yann.morin.1998@free.fr>. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <execinfo.h>
-#include <dlfcn.h>
-
-#include "connman.h"
-
-void print_backtrace(const char* program_path, const char* program_exec,
- 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]);
-}
type = dbus_message_iter_get_arg_type(&value);
if (g_str_equal(name, "Time")) {
+#if defined TIZEN_EXT
+ /* Tizen updates time (ntp) by system service */
+
+ return __connman_error_permission_denied(msg);
+#else
struct timeval tv;
dbus_uint64_t newval;
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "Time",
DBUS_TYPE_UINT64, &newval);
+#endif
} else if (g_str_equal(name, "TimeUpdates")) {
const char *strval;
enum time_updates newval;
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 {
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);
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
}
}
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);
}
}
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);
}
}
+#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;
}
}
+#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,
<allow send_destination="net.connman"/>
<allow send_interface="net.connman.Agent"/>
<allow send_interface="net.connman.Counter"/>
+ <allow send_interface="net.connman.Manager"/>
+ <allow send_interface="net.connman.Service"/>
+ <allow send_interface="net.connman.Technology"/>
+ <allow send_interface="net.connman.Notification"/>
+ </policy>
+ <policy user="network_fw">
+ <allow own="net.connman"/>
+ <allow send_destination="net.connman"/>
+ <allow send_interface="net.connman.Agent"/>
+ <allow send_interface="net.connman.Counter"/>
+ <allow send_interface="net.connman.Manager"/>
+ <allow send_interface="net.connman.Service"/>
+ <allow send_interface="net.connman.Technology"/>
<allow send_interface="net.connman.Notification"/>
</policy>
<policy at_console="true">
<allow send_interface="net.connman.Counter"/>
<allow send_interface="net.connman.Notification"/>
</policy>
+ <policy user="network_fw">
+ <allow own="net.connman"/>
+ <allow send_interface="net.connman.Agent"/>
+ <allow send_interface="net.connman.Counter"/>
+ <allow send_interface="net.connman.Notification"/>
+ </policy>
<policy context="default">
<allow send_destination="net.connman"/>
</policy>
+++ /dev/null
-[Unit]
-Description=Wait for network to be configured by ConnMan
-Requisite=connman.service
-After=connman.service
-Before=network-online.target
-DefaultDependencies=no
-Conflicts=shutdown.target
-
-[Service]
-Type=oneshot
-ExecStart=@sbindir@/connmand-wait-online
-RemainAfterExit=yes
-
-[Install]
-WantedBy=network-online.target
--- /dev/null
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="root">
+ <allow own="net.connman"/>
+ <allow send_destination="net.connman"/>
+ </policy>
+ <policy user="network_fw">
+ <allow own="net.connman"/>
+ <allow send_destination="net.connman"/>
+ </policy>
+ <policy context="default">
+ <deny own="net.connman"/>
+ <deny send_destination="net.connman"/>
+ <allow send_destination="net.connman" send_type="signal"/>
+ <allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="GetScanState" />
+
+ <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetTechnologies" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetServices" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Service" send_member="Connect" privilege="http://tizen.org/privilege/network.set" />
+ <check send_destination="net.connman" send_interface="net.connman.Service" send_member="Disconnect" privilege="http://tizen.org/privilege/network.set" />
+ <check send_destination="net.connman" send_interface="net.connman.Service" send_member="SetProperty" privilege="http://tizen.org/privilege/network.profile" />
+ <check send_destination="net.connman" send_interface="net.connman.Service" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Service" send_member="Remove" privilege="http://tizen.org/privilege/network.profile" />
+ <check send_destination="net.connman" send_interface="net.connman.Service" send_member="PropertyChanged" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Technology" send_member="Scan" privilege="http://tizen.org/privilege/network.set" />
+ <check send_destination="net.connman" send_interface="net.connman.Technology" send_member="SpecificScan" privilege="http://tizen.org/privilege/network.set" />
+ </policy>
+</busconfig>
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,
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);
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_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);
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);
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);
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 */
[Unit]
Description=Connection service
-DefaultDependencies=false
-Conflicts=shutdown.target
-RequiresMountsFor=@localstatedir@/lib/connman
-After=dbus.service network-pre.target systemd-sysusers.service
-Before=network.target multi-user.target shutdown.target
-Wants=network.target
+After=net-config.service
+DefaultDependencies=no
[Service]
Type=dbus
+User=network_fw
+Group=network_fw
BusName=net.connman
Restart=on-failure
-ExecStart=@sbindir@/connmand -n
+SmackProcessLabel=System
+ExecStart=@bindir@/connmand -n --noplugin vpn
StandardOutput=null
-CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SYS_TIME CAP_SYS_MODULE
-ProtectHome=true
-ProtectSystem=full
+Capabilities=cap_setgid,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i
+SecureBits=keep-caps
[Install]
WantedBy=multi-user.target
--- /dev/null
+[Unit]
+Description=DNS Proxy Socket
+Before=connman.service
+
+[Socket]
+ListenStream=127.0.0.1:53
+ListenDatagram=0.0.0.0:53
+FreeBind=true
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+[Install]
+WantedBy=sockets.target
\ No newline at end of file
--- /dev/null
+[Unit]
+Description=Connection service
+After=net-config.service
+DefaultDependencies=no
+
+[Service]
+Type=dbus
+User=network_fw
+Group=network_fw
+BusName=net.connman
+Restart=on-failure
+SmackProcessLabel=System
+ExecStart=@bindir@/connmand -n --noplugin vpn
+StandardOutput=null
+Capabilities=cap_setgid,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i
+SecureBits=keep-caps
+
+[Install]
+WantedBy=multi-user.target
return err;
}
+int connman_dbus_get_connection_unix_user_sync(DBusConnection *connection,
+ const char *bus_name,
+ unsigned int *user_id)
+{
+#if defined TIZEN_EXT
+ *user_id = 0;
+#else
+ unsigned long uid;
+ DBusError err;
+
+ dbus_error_init(&err);
+
+ uid = dbus_bus_get_unix_user(connection, bus_name, &err);
+
+ if (uid == (unsigned long)-1) {
+ DBG("Can not get unix user ID!");
+ if (dbus_error_is_set(&err)) {
+ DBG("%s", err.message);
+ dbus_error_free(&err);
+ }
+ return -1;
+ }
+
+ *user_id = (unsigned int)uid;
+#endif
+
+ return 0;
+}
+
static unsigned char *parse_context(DBusMessage *msg)
{
DBusMessageIter iter, array;
}
device = find_device(index);
+#if defined TIZEN_EXT
+ if (device) {
+ connman_inet_update_device_ident(device);
+ return;
+ }
+#else
if (device)
return;
+#endif
device = connman_device_create_from_index(index);
if (!device)
__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;
DBG("cleaning up %s index %d", interfaces[i], index);
+#if defined TIZEN_EXT
+ if (strcmp(interfaces[i], "wlan0") != 0)
+#endif
connman_inet_ifdown(index);
/*
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;
}
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_IPV4);
+#else
+ __connman_service_nameserver_remove(service,
+ dhcp->nameservers[i], false);
+#endif
}
g_strfreev(dhcp->nameservers);
dhcp->nameservers = NULL;
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);
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));
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);
__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);
__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.
*
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);
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)
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);
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 (!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
* 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;
}
}
+#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,
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 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)
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;
}
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)
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;
}
* 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)) {
+#endif
debug("client %d sent %d bytes but expecting %u pending %d",
client_sk, len, msg_len + 2, msg_len + 2 - 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;
}
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
debug("family %d protocol %d index %d", family, protocol, index);
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;
}
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 -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));
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;
g_free(ifr);
- if (count < numif) {
+ if (count < numif)
+ {
char **prev_result = result;
result = g_try_realloc(result, (count + 1) * sizeof(char *));
if (!result) {
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;
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);
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;
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);
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:
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;
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,
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;
}
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:
return -EINVAL;
repl = iptables_blob(table);
- if (!repl)
+ if(!repl)
return -ENOMEM;
if (debug_enabled)
#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>
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,
.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_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_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;
}
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);
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;
}
__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();
# 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
# match any of the list entries. Default value is
# 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
# other which is already connected.
# This setting has no effect if SingleConnectedTechnologies is enabled.
# AlwaysConnectedTechnologies =
+
+NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w
--- /dev/null
+[General]
+
+# 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.
+# InputRequestTimeout = 120
+
+# 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.
+# BrowserLaunchTimeout = 300
+
+# 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.
+# BackgroundScanning = true
+BackgroundScanning = false
+
+# 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.
+# FallbackTimeservers =
+#FallbackTimeservers = pool.ntp.org
+
+# List of fallback nameservers separated by "," used if no
+# nameservers are otherwise provided by the service. The
+# nameserver entries must be in numeric format, host
+# names are ignored.
+# FallbackNameservers =
+
+# 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.
+# DefaultAutoConnectTechnologies =
+
+# 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
+# by one in the order given, until one of them gets connected
+# or they are all tried. A service of a preferred technology
+# type in state 'ready' will get the default route when
+# compared to another preferred type further down the list
+# with state 'ready' or with a non-preferred type; a service
+# of a preferred technology type in state 'online' will get
+# 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
+NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w,eth
+
+# Allow connman to change the system hostname. This can
+# happen for example if we receive DHCP hostname option.
+# Default value is true.
+# AllowHostnameUpdates = true
+
+# 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
+# the other previously connected services are disconnected. With this
+# setting it does not matter whether the previously connected services
+# are in 'online' or 'ready' states, the newly connected service is
+# the only one that will be kept connected. A service connected by the
+# user will be used until going out of network coverage. With this
+# 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
+# listed here are used for tethering. If ethernet tethering is desired,
+# then ethernet should be added to the list. The technologies listed here
+# have to support tethering, currently tethering is implemented for wifi,
+# bluetooth, gadget and ethernet.
+# NOTE that if ethernet tethering is enabled, then a DHCP server is
+# started on all ethernet interfaces. Tethered ethernet should
+# never be connected to corporate or home network as it will disrupt
+# normal operation of these networks. Due to this ethernet is not
+# tethered by default. Do not activate ethernet tethering unless you
+# really know what you are doing.
+# TetheringTechnologies = wifi,bluetooth,gadget
+
+# Restore earlier tethering status when returning from offline mode,
+# re-enabling a technology, and after restarts and reboots.
+# Default value is false.
+# PersistentTetheringMode = 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).
+# Enable6to4 = false
+
+NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w
--- /dev/null
+[General]
+
+# 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.
+# InputRequestTimeout = 120
+
+# 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.
+# BrowserLaunchTimeout = 300
+
+# 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.
+# BackgroundScanning = true
+BackgroundScanning = false
+
+# 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.
+# FallbackTimeservers =
+#FallbackTimeservers = pool.ntp.org
+
+# List of fallback nameservers separated by "," used if no
+# nameservers are otherwise provided by the service. The
+# nameserver entries must be in numeric format, host
+# names are ignored.
+# FallbackNameservers =
+
+# 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.
+# DefaultAutoConnectTechnologies =
+
+# 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
+# by one in the order given, until one of them gets connected
+# or they are all tried. A service of a preferred technology
+# type in state 'ready' will get the default route when
+# compared to another preferred type further down the list
+# with state 'ready' or with a non-preferred type; a service
+# of a preferred technology type in state 'online' will get
+# 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
+NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w,eth0
+
+# Allow connman to change the system hostname. This can
+# happen for example if we receive DHCP hostname option.
+# Default value is true.
+# AllowHostnameUpdates = true
+
+# 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
+# the other previously connected services are disconnected. With this
+# setting it does not matter whether the previously connected services
+# are in 'online' or 'ready' states, the newly connected service is
+# the only one that will be kept connected. A service connected by the
+# user will be used until going out of network coverage. With this
+# 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
+# listed here are used for tethering. If ethernet tethering is desired,
+# then ethernet should be added to the list. The technologies listed here
+# have to support tethering, currently tethering is implemented for wifi,
+# bluetooth, gadget and ethernet.
+# NOTE that if ethernet tethering is enabled, then a DHCP server is
+# started on all ethernet interfaces. Tethered ethernet should
+# never be connected to corporate or home network as it will disrupt
+# normal operation of these networks. Due to this ethernet is not
+# tethered by default. Do not activate ethernet tethering unless you
+# really know what you are doing.
+# TetheringTechnologies = wifi,bluetooth,gadget
+
+# Restore earlier tethering status when returning from offline mode,
+# re-enabling a technology, and after restarts and reboots.
+# Default value is false.
+# PersistentTetheringMode = 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).
+# Enable6to4 = false
+
+NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w
--- /dev/null
+[General]
+
+# 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.
+# InputRequestTimeout = 120
+
+# 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.
+# BrowserLaunchTimeout = 300
+
+# 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.
+# BackgroundScanning = true
+BackgroundScanning = false
+
+# 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.
+# FallbackTimeservers =
+#FallbackTimeservers = pool.ntp.org
+
+# List of fallback nameservers separated by "," used if no
+# nameservers are otherwise provided by the service. The
+# nameserver entries must be in numeric format, host
+# names are ignored.
+# FallbackNameservers =
+
+# 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.
+# DefaultAutoConnectTechnologies =
+
+# 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
+# by one in the order given, until one of them gets connected
+# or they are all tried. A service of a preferred technology
+# type in state 'ready' will get the default route when
+# compared to another preferred type further down the list
+# with state 'ready' or with a non-preferred type; a service
+# of a preferred technology type in state 'online' will get
+# 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
+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.
+# Default value is true.
+# AllowHostnameUpdates = true
+
+# 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
+# the other previously connected services are disconnected. With this
+# setting it does not matter whether the previously connected services
+# are in 'online' or 'ready' states, the newly connected service is
+# the only one that will be kept connected. A service connected by the
+# user will be used until going out of network coverage. With this
+# 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
+# listed here are used for tethering. If ethernet tethering is desired,
+# then ethernet should be added to the list. The technologies listed here
+# have to support tethering, currently tethering is implemented for wifi,
+# bluetooth, gadget and ethernet.
+# NOTE that if ethernet tethering is enabled, then a DHCP server is
+# started on all ethernet interfaces. Tethered ethernet should
+# never be connected to corporate or home network as it will disrupt
+# normal operation of these networks. Due to this ethernet is not
+# tethered by default. Do not activate ethernet tethering unless you
+# really know what you are doing.
+# TetheringTechnologies = wifi,bluetooth,gadget
+
+# Restore earlier tethering status when returning from offline mode,
+# re-enabling a technology, and after restarts and reboots.
+# Default value is false.
+# PersistentTetheringMode = 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).
+# Enable6to4 = false
+
+NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w
+
+
+
+# Enable Tizen TV Profile Features
+TizenTVExtension = true
+
DBusMessageIter array, dict;
dbus_bool_t offlinemode;
const char *str;
+#if defined TIZEN_EXT
+ dbus_bool_t autoconnectmode;
+#endif
DBG("conn %p", conn);
connman_dbus_dict_append_basic(&dict, "SessionMode",
DBUS_TYPE_BOOLEAN,
&sessionmode);
+#if defined TIZEN_EXT
+ autoconnectmode = __connman_service_get_auto_connect_mode();
+ connman_dbus_dict_append_basic(&dict, "AutoConnectMode",
+ DBUS_TYPE_BOOLEAN,
+ &autoconnectmode);
+#endif
connman_dbus_dict_close(&array, &dict);
dbus_message_iter_get_basic(&value, &offlinemode);
+ if (offlinemode) {
+ 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 turn on offlinemode now!");
+ return __connman_error_permission_denied(msg);
+ }
+ }
__connman_technology_set_offlinemode(offlinemode);
} else if (g_str_equal(name, "SessionMode")) {
return __connman_error_invalid_arguments(msg);
dbus_message_iter_get_basic(&value, &sessionmode);
+ }
+#if defined TIZEN_EXT
+ else if (g_str_equal(name, "AutoConnectMode") == TRUE) {
+ bool automode;
- } else
+ if (type != DBUS_TYPE_BOOLEAN)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&value, &automode);
+
+ __connman_service_set_auto_connect_mode(automode);
+ }
+#endif
+ else
return __connman_error_invalid_property(msg);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
{
DBusMessage *reply;
+#if !defined TIZEN_EXT
DBG("");
+#endif
reply = dbus_message_new_method_return(msg);
if (!reply)
[D-BUS Service]
Name=net.connman
-Exec=@sbindir@/connmand -n
-User=root
+Exec=/bin/false
+User=network_fw
+Group=network_fw
SystemdService=connman.service
*/
#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;
bool wps;
bool use_wps;
char *pin_wps;
+#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)
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;
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;
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;
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);
+#if defined TIZEN_EXT
+ if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
+ return;
+#endif
+
service = connman_service_lookup_from_network(network);
if (!service)
return;
/* 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)
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
g_free(network->wifi.private_key_passphrase);
g_free(network->wifi.phase2_auth);
g_free(network->wifi.pin_wps);
-
+#if defined TIZEN_EXT
+ g_free(network->wifi.wifi_vsie);
+#endif
g_free(network->path);
g_free(network->group);
g_free(network->node);
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;
}
+#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);
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.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"))
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;
}
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;
}
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;
}
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;
}
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);
+#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) {
tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
tmx.status = STA_PLL;
}
DBG("interval/delta/delay/drift %fs/%+.3fs/%.3fs/%+ldppm",
- LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
+ LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
+#endif
}
static gboolean received_data(GIOChannel *channel, GIOCondition condition,
}
__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;
}
#include "connman.h"
-#define RESOLV_CONF_STATEDIR STATEDIR"/resolv.conf"
-#define RESOLV_CONF_ETC "/etc/resolv.conf"
-
#define RESOLVER_FLAG_PUBLIC (1 << 0)
/*
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) {
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;
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;
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)
#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;
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);
+#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
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 */
#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;
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);
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;
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 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;
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);
if (index < 0)
return -ENXIO;
+#if defined TIZEN_EXT
+ DBG("Resolver append nameserver: %s", nameserver);
+#endif
ret = connman_resolver_append(index, NULL, nameserver);
if (ret >= 0)
nameservers_changed(service);
if (service->nameservers_config) {
while (service->nameservers_config[i]) {
+#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, 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, 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, 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, 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++;
}
} else if (service->nameservers) {
while (service->nameservers[i]) {
+#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, 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, 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, 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, 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 (index < 0)
return -ENXIO;
+#if defined TIZEN_EXT
+ DBG("Resolver remove nameserver: %s", nameserver);
+#endif
ret = connman_resolver_remove(index, NULL, nameserver);
if (ret >= 0)
nameservers_changed(service);
static int nameserver_remove_all(struct connman_service *service,
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, 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, 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, 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, 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, type,
service->nameservers_config[i]);
+#endif
i++;
}
i = 0;
while (service->nameservers && service->nameservers[i]) {
+#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, 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, 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, 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, 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++;
}
* 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;
+#ifdef TIZEN_EXT
+ if(type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
+ 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 {
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;
service->nameservers_auto = nameservers;
} else {
service->nameservers = nameservers;
+#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;
g_timer_reset(service->stats_roaming.timer);
}
+#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 &&
+ 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;
+ 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->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;
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);
}
}
+#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,
+ 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->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)
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;
+#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);
+ }
+ 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)
{
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 = __connman_service_check_passphrase(service->security, passphrase);
if (err < 0)
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->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;
+ 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;
g_string_append(str, val);
}
+#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) {
if (gw && strlen(gw))
__connman_service_nameserver_add_routes(service, gw);
+#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,
if (!service->path)
return;
+#if !defined TIZEN_EXT
if (!allow_property_changed(service))
return;
+#endif
str = error2string(service->error);
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)
{
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;
}
}
continue;
}
+#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->state) ||
is_connected(service->state)) {
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;
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));
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;
+#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));
}
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 defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ break;
+#endif
if (!is_connecting(temp->state) && !is_connected(temp->state))
break;
}
if (err == -EINPROGRESS)
return __connman_error_operation_timeout(msg);
+#endif
service->ignore = false;
DBG("service %p", service);
+#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 !defined TIZEN_EXT
if (!service->favorite && !is_idle(service->state))
return false;
+#endif
__connman_service_disconnect(service);
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 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))
return false;
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) },
{ },
};
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
}
/**
}
/**
+ * __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
*
services_dirty = true;
}
+#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;
/* 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();
}
return -EALREADY;
}
+#if defined TIZEN_EXT
+static gboolean __connman_service_can_drop(struct connman_service *service)
+{
+ 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;
+ } 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 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 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)
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);
+#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
+ 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);
__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 (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),
case CONNMAN_SERVICE_STATE_CONFIGURATION:
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 (connman_setting_get_bool("EnableOnlineCheck")) {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+#if !defined TIZEN_EXT
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)
__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);
}
if (service->hidden)
return -EPERM;
+#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
DBG("service %p err %d", service, err);
service->connect_reason = reason;
-
if (err >= 0)
return 0;
__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);
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 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);
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 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;
}
+#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)
{
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);
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);
#include <config.h>
#endif
+#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
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;
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",
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;
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);
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;
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,
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" })) },
{ },
};
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;
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;
}
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) {
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;
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++)
import sys
import dbus
-if (len(sys.argv) >= 3 and len(sys.argv) != 4 and sys.argv[1] == "wifi"):
- print "Usage: %s wifi [SSID] [passphrase]" % (sys.argv[0])
+if (len(sys.argv) >= 2 and len(sys.argv) < 4 and sys.argv[1] == "wifi"):
+ print "Usage: %s wifi [SSID] [passphrase] [hidden]" % (sys.argv[0])
+ print "Example:"
+ print "Create the open system access point:"
+ print "%s wifi abcd \"\"" % (sys.argv[0])
+ print "Create the security access point:"
+ print "%s wifi abcd 123456789" % (sys.argv[0])
+ print "Create the hidden access point:"
+ print "%s wifi abcd 123456789 hidden" % (sys.argv[0])
+ print "Create the open and hidden access point:"
+ print "%s wifi abcd \"\" hidden" % (sys.argv[0])
sys.exit(1)
elif (len(sys.argv) < 2):
print "Usage: %s type" % (sys.argv[0])
manager = dbus.Interface(bus.get_object('net.connman', "/"),
'net.connman.Manager')
-def technology_enable_tethering(path, tech_type, ssid, psk):
+def technology_enable_tethering(path, tech_type, ssid, psk, hidden):
tech = dbus.Interface(bus.get_object("net.connman", path),
"net.connman.Technology")
if len(ssid) > 0:
tech.SetProperty("TetheringIdentifier",
ssid)
- if len(psk) > 0:
tech.SetProperty("TetheringPassphrase",
psk)
+ if tech_type == "wifi":
+ if len(hidden) > 0:
+ if hidden == "hidden":
+ tech.SetProperty("Hidden",dbus.Boolean(1))
+ else:
+ tech.SetProperty("Hidden",dbus.Boolean(0))
+ else:
+ tech.SetProperty("Hidden",dbus.Boolean(0))
+
print "Enabling %s tethering" % tech_type
tech.SetProperty("Tethering", dbus.Boolean(1))
tech = None
for path,_ in technologies:
- if (len(sys.argv) == 4):
+ if (len(sys.argv) == 5):
+ tech = technology_enable_tethering(path,
+ sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
+ elif (len(sys.argv) == 4):
tech = technology_enable_tethering(path,
- sys.argv[1], sys.argv[2], sys.argv[3])
+ sys.argv[1], sys.argv[2], sys.argv[3], "")
else:
- tech = technology_enable_tethering(path, sys.argv[1], "", "")
+ tech = technology_enable_tethering(path, sys.argv[1], "", "", "")
if tech != None:
break;
+++ /dev/null
-#!/usr/bin/python
-
-import sys
-import dbus
-
-if (len(sys.argv) != 2):
- print "Usage: %s <timezone>" % (sys.argv[0])
- sys.exit(1)
-
-bus = dbus.SystemBus()
-
-clock = dbus.Interface(bus.get_object('net.connman', '/'),
- 'net.connman.Clock')
-
-print "Setting timezone to %s" % (sys.argv[1])
-
-try:
- clock.SetProperty("Timezone", dbus.String(sys.argv[1], variant_level=1),
- signature=dbus.Signature('sv'))
-except dbus.exceptions.DBusException, e_msg:
- print e_msg
[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
-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
#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;
[D-BUS Service]
Name=net.connman.vpn
-Exec=@sbindir@/connman-vpnd -n
-User=root
+Exec=/bin/false
+User=network_fw
+Group=network_fw
SystemdService=connman-vpn.service
--- /dev/null
+/*
+ *
+ * ConnMan VPN daemon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <net/if.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/plugin.h>
+#include <connman/log.h>
+#include <connman/task.h>
+#include <connman/dbus.h>
+#include <connman/ipconfig.h>
+
+#include "../vpn-provider.h"
+
+#include "vpn.h"
+#include "ipsec.h"
+#include "vici-client.h"
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+typedef enum {
+ CERT_TYPE_NONE,
+ CERT_TYPE_DER,
+ CERT_TYPE_PEM,
+ CERT_TYPE_PKCS12,
+ CERT_TYPE_MAX,
+} cert_type_e;
+
+static DBusConnection *connection;
+static VICIClient *vici_client;
+static GFileMonitor* monitor;
+
+struct ipsec_private_data {
+ struct vpn_provider *provider;
+ vpn_provider_connect_cb_t connect_cb;
+ void *connect_user_data;
+};
+
+struct ipsec_event_data {
+ vpn_event_callback event_cb;
+ void *event_user_data;
+};
+
+struct {
+ const char *cm_opt;
+ const char *vici_key;
+ const char *subsection;
+ vici_add_element add_elem;
+} ipsec_conn_options[] = {
+ {"IPsec.Version", "version", NULL, vici_add_kv},
+ {"IPsec.LeftAddrs", "local_addrs", NULL, vici_add_kvl},
+ {"IPsec.RightAddrs", "remote_addrs", NULL, vici_add_kvl},
+
+ {"IPsec.LocalAuth", "auth", "local", vici_add_kv},
+ {"IPsec.LocalID", "id", "local", vici_add_kv},
+ {"IPsec.LocalXauthID", "xauth_id", "local", vici_add_kv},
+ {"IPsec.LocalXauthAuth", "auth", "local-xauth", vici_add_kv},
+ {"IPsec.LocalXauthXauthID", "xauth_id", "local-xauth", vici_add_kv},
+ {"IPsec.RemoteAuth", "auth", "remote", vici_add_kv},
+ {"IPsec.RemoteID", "id", "remote", vici_add_kv},
+ {"IPsec.RemoteXauthID", "xauth_id", "remote", vici_add_kv},
+ {"IPsec.RemoteXauthAuth", "auth", "remote-xauth", vici_add_kv},
+ {"IPsec.RemoteXauthXauthID", "xauth_id", "remote-xauth", vici_add_kv},
+ {"IPsec.ChildrenLocalTS", "local_ts", "children", vici_add_kvl},
+ {"IPsec.ChildrenRemoteTS", "remote_ts", "children", vici_add_kvl},
+};
+
+struct {
+ const char *cm_opt;
+ const char *vici_type;
+} ipsec_shared_options[] = {
+ {"IPsec.IKEData", "data"},
+ {"IPsec.IKEOwners", "owners"},
+ {"IPsec.XauthData", "data"},
+ {"IPsec.XauthOwners", "owners"},
+};
+
+struct {
+ const char *cm_opt;
+ const char *vici_type;
+ const char *vici_flag;
+} ipsec_cert_options[] = {
+ {"IPsec.CertType", "type", NULL},
+ {"IPsec.CertFlag", "flag", NULL},
+ {"IPsec.CertData", "data", NULL},
+ {"IPsec.CertPass", "data", NULL},
+};
+
+struct {
+ const char *cm_opt;
+ const char *vici_type;
+} ipsec_pkey_options[] = {
+ {"IPsec.PKeyType", "type"},
+ {"IPsec.PKeyData", "data"},
+};
+
+static const char *ikev1_esp_proposals [] ={
+ "aes256-sha256",
+ "aes128-sha256",
+ "aes256-sha1",
+ "aes128-sha1",
+ "aes256-md5",
+ "aes128-md5",
+ "3des-sha1",
+ "3des-md5",
+ NULL,
+};
+
+static const char *ikev1_proposals [] ={
+ "aes256-sha256-modp1024",
+ "aes128-sha256-modp1024",
+ "aes256-sha1-modp1024",
+ "aes128-sha1-modp1024",
+ "aes256-md5-modp1024",
+ "aes128-md5-modp1024",
+ "3des-sha1-modp1024",
+ "3des-md5-modp1024",
+ NULL,
+};
+
+static const char *ikev2_esp_proposals = "aes256-aes128-sha256-sha1";
+
+static const char *ikev2_proposals = "aes256-aes128-sha512-sha384-sha256-sha1-modp2048-modp1536-modp1024";
+
+static struct ipsec_event_data event_data;
+
+static void free_private_data(struct ipsec_private_data *data)
+{
+ g_free(data);
+}
+
+static int ipsec_notify(DBusMessage *msg, struct vpn_provider *provider)
+{
+ return 0;
+}
+
+static void ipsec_set_event_cb(vpn_event_callback event_cb, struct vpn_provider *provider)
+{
+ DBG("set event cb!");
+ event_data.event_cb = event_cb;
+ event_data.event_user_data = provider;
+ return;
+}
+
+static int ipsec_is_same_auth(const char* req, const char* target)
+{
+ if (req == NULL || target == NULL)
+ return 0;
+ return (g_strcmp0(req, target) == 0);
+}
+
+static int vici_load_cert(const char* type, const char* flag, const char* data)
+{
+ VICISection *sect;
+ int ret = 0;
+
+ sect = vici_create_section(NULL);
+ if (!sect)
+ return -ENOMEM;
+
+ vici_add_kv(sect, "type", type, NULL);
+ vici_add_kv(sect, "flag", flag, NULL);
+ vici_add_kv(sect, "data", data, NULL);
+
+ ret = vici_send_request(vici_client, VICI_CMD_LOAD_CERT, sect);
+ if (ret < 0)
+ connman_error("vici_send_request failed");
+
+ vici_destroy_section(sect);
+
+ return ret;
+}
+
+static void ipsec_add_default_child_sa_data(struct vpn_provider *provider, VICISection *child)
+{
+ const char *version = vpn_provider_get_string(provider, "IPsec.Version");
+ if (g_strcmp0(version, "1") == 0) {
+ int i = 0;
+ GSList *list;
+
+ for (list = NULL; ikev1_esp_proposals[i] != NULL; i++)
+ list = g_slist_append(list, g_strdup(ikev1_esp_proposals[i]));
+ vici_add_list(child, "esp_proposals", list, "net");
+ g_slist_free_full(list, g_free);
+ list = NULL;
+ } else {
+ vici_add_kvl(child, "esp_proposals", ikev2_esp_proposals, "net");
+ }
+ return;
+}
+
+static void ipsec_add_default_conn_data(struct vpn_provider *provider, VICISection *conn)
+{
+ const char *version = vpn_provider_get_string(provider, "IPsec.Version");
+ const char *remote_addr = vpn_provider_get_string(provider, "Host");
+
+ vici_add_kvl(conn, "remote_addrs", remote_addr, NULL);
+ if (g_strcmp0(version, "1") == 0) {
+ int i = 0;
+ GSList *list;
+
+ for (list = NULL; ikev1_proposals[i] != NULL; i++)
+ list = g_slist_append(list, g_strdup(ikev1_proposals[i]));
+ vici_add_list(conn, "proposals", list, NULL);
+ g_slist_free_full(list, g_free);
+ list = NULL;
+
+ if (g_strcmp0(vpn_provider_get_string(provider, "IPsec.LocalAuth"), "psk") == 0)
+ vici_add_kv(conn, "aggressive", "yes", NULL);
+ } else {
+ vici_add_kvl(conn, "proposals", ikev2_proposals, NULL);
+ }
+
+ vici_add_kvl(conn, "vips", "0.0.0.0", NULL);
+ return;
+}
+
+static char *load_file_from_path(const char *path)
+{
+ struct stat st;
+ FILE *fp = NULL;
+ int fd = 0;
+ size_t file_size = 0;
+ char *file_buff = NULL;
+
+ if (!path) {
+ connman_error("File path is NULL\n");
+ return NULL;
+ }
+
+ fp = fopen(path, "rb");
+ if (!fp) {
+ connman_error("fopen %s is failed\n", path);
+ return NULL;
+ }
+
+ fd = fileno(fp);
+ if (fd == -1) {
+ connman_error("fp is not a valid stream");
+ fclose(fp);
+ return NULL;
+ }
+
+ if (fstat(fd, &st) != 0) {
+ connman_error("fstat failed");
+ fclose(fp);
+ return NULL;
+ }
+
+ file_size = st.st_size;
+ file_buff = g_try_malloc0(sizeof(char)*st.st_size);
+ if (file_buff == NULL) {
+ connman_error("g_try_malloc0 failed\n");
+ fclose(fp);
+ return NULL;
+ }
+
+ if (fread(file_buff, 1, file_size, fp) != file_size) {
+ connman_error("file size not matched\n");
+ g_free(file_buff);
+ file_buff = NULL;
+ }
+
+ fclose(fp);
+ return file_buff;
+}
+
+static char * get_local_cert_str(struct vpn_provider *provider)
+{
+ const char *path;
+
+ if (!provider)
+ return NULL;
+
+ path = vpn_provider_get_string(provider, "IPsec.LocalCerts");
+
+ return load_file_from_path(path);
+}
+
+static int ipsec_load_conn(struct vpn_provider *provider, struct ipsec_private_data *data)
+{
+ const char *key;
+ const char *value;
+ const char *subsection;
+ char *local_cert_str;
+ VICISection *conn;
+ VICISection *children;
+ int i;
+ int ret = 0;
+
+ if (!provider || !data) {
+ connman_error("invalid provider or data");
+ return -EINVAL;
+ }
+
+ value = vpn_provider_get_string(provider, "Name");
+ DBG("Name: %s", value);
+ conn = vici_create_section(value);
+ children = vici_create_section("children");
+ add_subsection("children", children, conn);
+
+ for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
+ value = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
+ if (!value)
+ continue;
+
+ key = ipsec_conn_options[i].vici_key;
+ subsection = ipsec_conn_options[i].subsection;
+ ipsec_conn_options[i].add_elem(conn, key, value, subsection);
+ }
+
+ local_cert_str = get_local_cert_str(provider);
+ if (local_cert_str) {
+ /* TODO :remove this after debug */
+ DBG("There's local certification to add local section");
+ vici_add_kvl(conn, "certs", local_cert_str, "local");
+ g_free(local_cert_str);
+ }
+
+ ipsec_add_default_conn_data(provider, conn);
+ ipsec_add_default_child_sa_data(provider, children);
+
+ ret = vici_send_request(vici_client, VICI_CMD_LOAD_CONN, conn);
+ if (ret < 0)
+ connman_error("vici_send_request failed");
+
+ vici_destroy_section(conn);
+
+ return ret;
+}
+
+static int ipsec_load_shared_psk(struct vpn_provider *provider)
+{
+ const char *data;
+ const char *owner;
+ VICISection *sect;
+ int ret = 0;
+
+ if (!provider) {
+ connman_error("invalid provider");
+ return -EINVAL;
+ }
+
+ data = vpn_provider_get_string(provider, "IPsec.IKEData");
+ owner = vpn_provider_get_string(provider, "IPsec.IKEOwners");
+ DBG("IKEData: %s, IKEOwners: %s", data, owner);
+
+ if (!data)
+ return 0;
+
+ sect = vici_create_section(NULL);
+ if (!sect) {
+ return -ENOMEM;
+ }
+
+ vici_add_kv(sect, "type", VICI_SHARED_TYPE_PSK, NULL);
+ vici_add_kv(sect, "data", data, NULL);
+ vici_add_kvl(sect, "owners", owner, NULL);
+
+ ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
+ if (ret < 0)
+ connman_error("vici_send_request failed");
+
+ vici_destroy_section(sect);
+
+ return ret;
+}
+
+static int ipsec_load_shared_xauth(struct vpn_provider *provider)
+{
+ const char *data;
+ const char *owner;
+ VICISection *sect;
+ int ret = 0;
+
+ if (!provider) {
+ connman_error("invalid provider");
+ return -EINVAL;
+ }
+
+ data = vpn_provider_get_string(provider, "IPsec.XauthData");
+ owner = vpn_provider_get_string(provider, "IPsec.XauthOwners");
+ DBG("XauthData: %s, XauthOwners: %s", data, owner);
+
+ if (!data)
+ return 0;
+
+ sect = vici_create_section(NULL);
+
+ vici_add_kv(sect, "type", VICI_SHARED_TYPE_XAUTH, NULL);
+ vici_add_kv(sect, "data", data, NULL);
+ vici_add_kvl(sect, "owners", owner, NULL);
+
+ ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
+ if (ret < 0)
+ connman_error("vici_send_request failed");
+
+ vici_destroy_section(sect);
+
+ return ret;
+}
+
+static int ipsec_load_key(struct vpn_provider *provider)
+{
+ const char *type;
+ const char *path;
+ char *data;
+ VICISection *sect;
+ int ret = 0;
+
+ if (!provider) {
+ connman_error("invalid provider");
+ return -EINVAL;
+ }
+
+ type = vpn_provider_get_string(provider, "IPsec.PKeyType");
+ path = vpn_provider_get_string(provider, "IPsec.PKeyData");
+ DBG("PKeyType: %s, PKeyData: %s", type, path);
+
+ if (!type || !path)
+ return 0;
+
+ data = load_file_from_path(path);
+ if (!data)
+ return 0;
+
+ sect = vici_create_section(NULL);
+ if (!sect) {
+ g_free(data);
+ return -ENOMEM;
+ }
+
+ vici_add_kv(sect, "type", type, NULL);
+ vici_add_kv(sect, "data", data, NULL);
+
+ ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
+ if (ret < 0)
+ connman_error("vici_send_request failed");
+
+ vici_destroy_section(sect);
+ g_free(data);
+
+ return ret;
+}
+
+static int ipsec_initiate(struct vpn_provider *provider)
+{
+ VICISection *sect;
+ int ret = 0;
+
+ sect = vici_create_section(NULL);
+ if (!sect)
+ return -ENOMEM;
+
+ vici_add_kv(sect, "child", "net", NULL);
+ ret = vici_send_request(vici_client, VICI_CMD_INITIATE, sect);
+ if (ret < 0)
+ connman_error("vici_send_request failed");
+
+ vici_destroy_section(sect);
+
+ return ret;
+}
+
+static int ipsec_load_cert(struct vpn_provider *provider)
+{
+ const char *type;
+ const char *flag;
+ char *data;
+ const char *local_auth_type;
+ const char *remote_auth_type;
+ int ret = 0;
+
+ if (!provider) {
+ connman_error("invalid provider");
+ return -EINVAL;
+ }
+
+ local_auth_type = vpn_provider_get_string(provider, "IPsec.LocalAuth");
+ remote_auth_type = vpn_provider_get_string(provider, "IPsec.RemoteAuth");
+ if (!ipsec_is_same_auth(local_auth_type, "pubkey") &&
+ !ipsec_is_same_auth(remote_auth_type, "pubkey")) {
+ DBG("invalid auth type");
+ return 0;
+ }
+
+ type = vpn_provider_get_string(provider, "IPsec.CertType");
+ flag = vpn_provider_get_string(provider, "IPsec.CertFlag");
+ data = load_file_from_path(vpn_provider_get_string(provider, "IPsec.CertData"));
+ DBG("CertType: %s, CertFalg: %s,CertData: %s", type, flag, data);
+ if (!type || ! flag || !data) {
+ connman_error("invalid certification information");
+ g_free(data);
+ return -EINVAL;
+ }
+
+ ret = vici_load_cert(type, flag, data);
+ if (ret < 0)
+ connman_error("failed to load cert");
+
+ g_free(data);
+
+ return ret;
+}
+
+static int ipsec_terminate(struct vpn_provider *provider)
+{
+ VICISection *sect;
+ int ret = 0;
+
+ sect = vici_create_section(NULL);
+ if (!sect)
+ return -ENOMEM;
+
+ vici_add_kv(sect, "child", "net", NULL);
+ vici_add_kv(sect, "ike", vpn_provider_get_string(provider, "Name"), NULL);
+ vici_add_kv(sect, "timeout", "-1", NULL);
+ ret = vici_send_request(vici_client, VICI_CMD_TERMINATE, sect);
+ if (ret < 0)
+ connman_error("vici_send_request failed");
+
+ vici_destroy_section(sect);
+
+ return ret;
+}
+
+static void request_reply_cb(int err, void *user_data)
+{
+ struct ipsec_private_data *data;
+
+ data = (struct ipsec_private_data *)user_data;
+ DBG("request reply cb");
+
+ if(err != 0) {
+ if (event_data.event_cb)
+ event_data.event_cb(event_data.event_user_data, VPN_STATE_FAILURE);
+ /* TODO: Does close socket needed? */
+ } else {
+ DBG("Series of requests are succeeded");
+ /* TODO: Not sure about below */
+ if (event_data.event_cb)
+ event_data.event_cb(event_data.event_user_data, VPN_STATE_CONNECT);
+ }
+
+ free_private_data(data);
+}
+
+static void ipsec_vici_event_cb(VICIClientEvent event, void *user_data)
+{
+ struct vpn_provider *provider;
+
+ provider = (struct vpn_provider *)user_data;
+ if (!provider) {
+ DBG("Invalid user data");
+ return;
+ }
+
+ if(event == VICI_EVENT_CHILD_UP) {
+ if (event_data.event_cb)
+ event_data.event_cb(event_data.event_user_data, VPN_STATE_READY);
+ } else if (event == VICI_EVENT_CHILD_DOWN) {
+ if (event_data.event_cb)
+ event_data.event_cb(event_data.event_user_data, VPN_STATE_DISCONNECT);
+ } else {
+ DBG("Unknown event");
+ }
+
+ return;
+}
+
+static struct ipsec_private_data* create_ipsec_private_data(struct vpn_provider *provider,
+ vpn_provider_connect_cb_t cb, void* user_data)
+{
+ struct ipsec_private_data *data;
+ data = g_try_new0(struct ipsec_private_data, 1);
+ if (!data) {
+ connman_error("out of memory");
+ return NULL;
+ }
+
+ data->provider = provider;
+ data->connect_cb = cb;
+ data->connect_user_data = user_data;
+ return data;
+}
+
+static void vici_connect(struct ipsec_private_data *data)
+{
+ struct vpn_provider *provider = NULL;
+ vpn_provider_connect_cb_t cb = NULL;
+ int err = 0;
+
+ if (!data)
+ IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid data parameter");
+
+ provider = data->provider;
+ cb = data->connect_cb;
+ if (!provider || !cb)
+ IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid provider or callback");
+
+ DBG("data %p, provider %p", data, provider);
+
+ /*
+ * Initialize vici client
+ */
+ err = vici_initialize(&vici_client);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "failed to initialize vici_client");
+
+ /* TODO :remove this after debug */
+ DBG("success to initialize vici socket");
+
+ vici_set_request_reply_cb(vici_client, (vici_request_reply_cb)request_reply_cb, data);
+ /*
+ * Sets child-updown event
+ */
+ err = vici_set_event_cb(vici_client, (vici_event_cb)ipsec_vici_event_cb, provider);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "register event failed");
+
+ /* TODO :remove this after debug */
+ DBG("success to vici_set_event_cb");
+ /*
+ * Send the load-conn command
+ */
+ err = ipsec_load_conn(provider, data);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "load-conn failed");
+
+ /* TODO :remove this after debug */
+ DBG("success to ipsec_load_conn");
+
+ /*
+ * Send the load-shared command for PSK
+ */
+ err = ipsec_load_shared_psk(provider);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
+
+ /* TODO :remove this after debug */
+ DBG("success to ipsec_load_shared_psk");
+
+ /*
+ * Send the load-shared command for XAUTH
+ */
+ err = ipsec_load_shared_xauth(provider);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
+
+ /* TODO :remove this after debug */
+ DBG("success to ipsec_load_shared_xauth");
+ /*
+ * Send the load-cert command
+ */
+ err = ipsec_load_cert(provider);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "load-cert failed");
+
+ /* TODO :remove this after debug */
+ DBG("success to ipsec_load_cert");
+
+ /*
+ * Send the load-key command
+ */
+ err = ipsec_load_key(provider);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "load-key failed");
+
+ /* TODO :remove this after debug */
+ DBG("success to ipsec_load_cert");
+ /*
+ * Send the initiate command
+ */
+ err = ipsec_initiate(provider);
+ IPSEC_ERROR_CHECK_GOTO(err, done, "initiate failed");
+
+ /* TODO :remove this after debug */
+ DBG("success to ipsec_initiate");
+
+done:
+ /* refer to connect_cb on vpn-provider.c for cb */
+ if(cb)
+ cb(provider, data->connect_user_data, -err);
+ /* TODO: Does close socket needed? when err is not zero */
+
+ return;
+}
+
+static void monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file,
+ GFileMonitorEvent event_type, gpointer user_data)
+{
+ DBG("file %s", g_file_get_path(file));
+ if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
+ if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
+ DBG("file created: %s", VICI_DEFAULT_URI);
+ struct ipsec_private_data *data = user_data;
+ vici_connect(data);
+ g_object_unref(monitor);
+ }
+ }
+}
+
+static void monitor_vici_socket(struct ipsec_private_data *data)
+{
+ GError *error = NULL;
+ GFile* file;
+
+ file = g_file_new_for_path(VICI_DEFAULT_URI);
+ monitor = g_file_monitor_file(file, G_FILE_MONITOR_SEND_MOVED, NULL, &error);
+ if (error) {
+ connman_error("g_file_monitor_directory failed: %s / %d", error->message, error->code);
+ g_error_free(error);
+ if(event_data.event_cb)
+ event_data.event_cb(event_data.event_user_data, VPN_STATE_FAILURE);
+ return;
+ }
+ /* TODO :remove this after debug */
+ DBG("starting to monitor vici socket");
+ g_signal_connect(monitor, "changed", G_CALLBACK(monitor_changed), data);
+ g_object_unref(file);
+}
+
+static void check_vici_socket(struct ipsec_private_data *data)
+{
+ DBG("data %p", data);
+ if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
+ DBG("file exists: %s", VICI_DEFAULT_URI);
+ vici_connect(data);
+ } else {
+ monitor_vici_socket(data);
+ }
+}
+
+static void ipsec_died(struct connman_task *task, int exit_code, void *user_data)
+{
+ DBG("task %p exit_code %d", task, exit_code);
+ unlink(VICI_DEFAULT_URI);
+ vpn_died(task, exit_code, user_data);
+}
+
+static int ipsec_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)
+{
+ struct ipsec_private_data *data;
+ int err = 0;
+
+ data = create_ipsec_private_data(provider, cb, user_data);
+ if (!data) {
+ connman_error("create ipsec private data failed");
+ return -ENOMEM;
+ }
+ /*
+ * Start charon daemon using ipsec script of strongSwan.
+ */
+ err = connman_task_run(task, ipsec_died, provider, NULL, NULL, NULL);
+ if (err < 0) {
+ connman_error("charon start failed");
+ if (cb)
+ cb(provider, user_data, err);
+
+ g_free(data);
+ return err;
+ }
+
+ check_vici_socket(data);
+// g_usleep(G_USEC_PER_SEC);
+
+ return err;
+}
+
+static int ipsec_error_code(struct vpn_provider *provider, int exit_code)
+{
+ return 0;
+}
+
+static int ipsec_save(struct vpn_provider *provider, GKeyFile *keyfile)
+{
+ int i;
+ const char *option;
+
+ DBG("");
+ /*
+ * Save IKE connection configurations
+ */
+ for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
+ option = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
+ if (option)
+ g_key_file_set_string(keyfile,
+ vpn_provider_get_save_group(provider),
+ ipsec_conn_options[i].cm_opt,
+ option);
+ }
+
+ /*
+ * Save shared IKE PSK, EAP or XAUTH secret
+ */
+ for (i = 0; i < (int)ARRAY_SIZE(ipsec_shared_options); i++) {
+ option = vpn_provider_get_string(provider, ipsec_shared_options[i].cm_opt);
+ if (option)
+ g_key_file_set_string(keyfile,
+ vpn_provider_get_save_group(provider),
+ ipsec_shared_options[i].cm_opt,
+ option);
+ }
+
+ /*
+ * Save certification
+ */
+ for (i = 0; i < (int)ARRAY_SIZE(ipsec_cert_options); i++) {
+ option = vpn_provider_get_string(provider, ipsec_cert_options[i].cm_opt);
+ if (option)
+ g_key_file_set_string(keyfile,
+ vpn_provider_get_save_group(provider),
+ ipsec_cert_options[i].cm_opt,
+ option);
+ }
+
+ /*
+ * Save private key
+ */
+ for (i = 0; i < (int)ARRAY_SIZE(ipsec_pkey_options); i++) {
+ option = vpn_provider_get_string(provider, ipsec_pkey_options[i].cm_opt);
+ if (option)
+ g_key_file_set_string(keyfile,
+ vpn_provider_get_save_group(provider),
+ ipsec_pkey_options[i].cm_opt,
+ option);
+ }
+
+ /*
+ * Save local certification
+ */
+ option = vpn_provider_get_string(provider, "IPsec.LocalCerts");
+ if (option)
+ g_key_file_set_string(keyfile,
+ vpn_provider_get_save_group(provider),
+ "IPsec.LocalCerts",
+ option);
+ option = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
+ if (option)
+ g_key_file_set_string(keyfile,
+ vpn_provider_get_save_group(provider),
+ "IPsec.LocalCertPass",
+ option);
+ /*
+ * Save CA certification directory
+ */
+ option = vpn_provider_get_string(provider, "IPsec.CACertsDir");
+ if (option)
+ g_key_file_set_string(keyfile,
+ vpn_provider_get_save_group(provider),
+ "IPsec.CACertsDir",
+ option);
+
+ return 0;
+}
+
+static void ipsec_disconnect(struct vpn_provider *provider)
+{
+ int err = 0;
+ /*
+ * Send the terminate command
+ */
+ err = ipsec_terminate(provider);
+ IPSEC_ERROR_CHECK_RETURN(err, "terminate failed");
+
+ err = vici_deinitialize(vici_client);
+ IPSEC_ERROR_CHECK_RETURN(err, "failed to deinitialize vici_client");
+
+ return;
+}
+
+static struct vpn_driver vpn_driver = {
+ .flags = VPN_FLAG_NO_TUN,
+ .notify = ipsec_notify,
+ .set_event_cb = ipsec_set_event_cb,
+ .connect = ipsec_connect,
+ .error_code = ipsec_error_code,
+ .save = ipsec_save,
+ .disconnect = ipsec_disconnect,
+};
+
+static int ipsec_init(void)
+{
+ connection = connman_dbus_get_connection();
+
+ event_data.event_cb = NULL;
+ event_data.event_user_data = NULL;
+
+ return vpn_register("ipsec", &vpn_driver, IPSEC);
+}
+
+static void ipsec_exit(void)
+{
+ vpn_unregister("ipsec");
+
+ dbus_connection_unref(connection);
+}
+
+CONNMAN_PLUGIN_DEFINE(ipsec, "IPSec plugin", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_DEFAULT, ipsec_init, ipsec_exit)
--- /dev/null
+/*
+ *
+ * ConnMan VPN daemon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __CONNMAN_VPND_PLUGIN_IPSEC_H
+#define __CONNMAN_VPND_PLUGIN_IPSEC_H
+
+#define IPSEC_AUTH_PSK "PSK"
+#define IPSEC_AUTH_RSA "RSA"
+#define IPSEC_AUTH_XAUTH "XAUTH"
+
+#define VICI_SHARED_TYPE_PSK "IKE"
+#define VICI_SHARED_TYPE_XAUTH "xauth"
+
+#define IPSEC_ERROR_CHECK_GOTO(err, target, fmt, arg...) do { \
+ if (err < 0) { \
+ connman_error(fmt, ## arg); \
+ goto target; \
+ } \
+} while (0)
+
+#define IPSEC_ERROR_CHECK_RETURN(err, fmt, arg...) do { \
+ if (err < 0) { \
+ connman_error(fmt, ## arg); \
+ return; \
+ } \
+} while (0)
+
+#define IPSEC_ERROR_CHECK_RETURN_VAL(err, ret, fmt, arg...) do { \
+ if (err < 0) { \
+ connman_error(fmt, ## arg); \
+ return ret; \
+ } \
+} while (0)
+
+#endif /* __CONNMAN_VPND_PLUGIN_IPSEC_H */
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
--- /dev/null
+/*
+ *
+ * ConnMan VPN daemon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+
+#include <glib.h>
+
+#include <connman/log.h>
+#include "ipsec.h"
+#include "vici-client.h"
+
+#define SOCK_FD_MIN 3
+#define VICI_REQUEST_TIMEOUT 5000
+
+enum vici_element {
+ VICI_END = 0,
+ VICI_SECTION_START = 1,
+ VICI_SECTION_END = 2,
+ VICI_KEY_VALUE = 3,
+ VICI_LIST_START = 4,
+ VICI_LIST_ITEM = 5,
+ VICI_LIST_END = 6,
+};
+
+enum vici_packet_type {
+ VICI_CMD_REQUEST = 0,
+ VICI_CMD_RESPONSE = 1,
+ VICI_CMD_UNKNOWN = 2,
+ VICI_EVENT_REGISTER = 3,
+ VICI_EVENT_UNREGISTER = 4,
+ VICI_EVENT_CONFIRM = 5,
+ VICI_EVENT_UNKNOWN = 6,
+ VICI_EVENT = 7,
+};
+
+static const char *vici_cmd_str[] = {
+ "load-conn",
+ "load-shared",
+ "load-cert",
+ "load-authority",
+ "unload-authority",
+ "load-key",
+ "initiate",
+ "terminate",
+ "child-updown",
+ NULL,
+};
+
+struct request {
+ unsigned int allocated;
+ unsigned int used;
+ unsigned int hdr_len;
+ char *sndbuf;
+ int cmd;
+ int err;
+ /* process reply */
+ unsigned int rcv_pkt_size;
+ char *rcvbuf;
+ /* davici_cb cb; */
+ void *user;
+};
+
+struct _VICIClient {
+ /* io data */
+ int client_sock_fd;
+ int client_watch;
+ unsigned int rcv_pkt_size;
+ char *rcvbuf;
+ GSList *request_list;
+ vici_request_reply_cb reply_cb;
+ vici_event_cb event_cb;
+ void *reply_user_data;
+ void *event_user_data;
+};
+
+struct _VICISection {
+ char *name;
+ GHashTable *kvs;
+ GHashTable *kvls;
+ GHashTable *subsection;
+};
+
+static void remove_list(gpointer data)
+{
+ if (data == NULL)
+ return;
+
+ g_slist_free_full((GSList *)data, g_free);
+}
+
+void vici_destroy_section(VICISection* section)
+{
+ g_free(section->name);
+ g_hash_table_destroy(section->kvs);
+ g_hash_table_destroy(section->kvls);
+ g_hash_table_destroy(section->subsection);
+ g_free(section);
+}
+
+static void free_section(gpointer data)
+{
+ VICISection* section = (VICISection*)data;
+ vici_destroy_section(section);
+}
+
+VICISection* vici_create_section(const char* name)
+{
+ VICISection* section;
+
+ section = g_try_new0(VICISection, 1);
+ if (!section) {
+ connman_error("Failed to create section");
+ return NULL;
+ }
+
+ if (name)
+ section->name = g_strdup(name);
+ section->kvs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ section->kvls = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, remove_list);
+ section->subsection = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_section);
+ return section;
+}
+
+int add_subsection(const char* name, VICISection* child, VICISection* section)
+{
+ if (section == NULL || name == NULL || child == NULL) {
+ connman_error("invalid parameter");
+ return -1;
+ }
+
+ g_hash_table_insert(section->subsection, g_strdup(name), child);
+ return 0;
+}
+
+static int add_kvl_to_section(const char* key, const char* value, VICISection* section)
+{
+ GSList *list = NULL;
+ if (section == NULL || key == NULL || value == NULL) {
+ connman_error("invalid parameter");
+ return -1;
+ }
+
+ list = g_hash_table_lookup(section->kvls, key);
+ if (list == NULL)
+ list = g_slist_alloc();
+
+ list = g_slist_prepend(list, g_strdup(value));
+ g_hash_table_replace(section->kvls, g_strdup(key), list);
+ return 0;
+}
+
+static int add_kv_to_section(const char* key, const char* value, VICISection* section)
+{
+ if (section == NULL || key == NULL || value == NULL) {
+ connman_error("invalid parameter");
+ return -1;
+ }
+
+ g_hash_table_insert(section->kvs, g_strdup(key), g_strdup(value));
+ return 0;
+}
+
+static VICISection* get_subsection(VICISection* section, const char* name)
+{
+ VICISection* sub = g_hash_table_lookup(section->subsection, name);
+ if (sub == NULL) {
+ sub = vici_create_section(name);
+ add_subsection(name, sub, section);
+ }
+ return sub;
+}
+
+int vici_add_kv(VICISection* section, const char* key,
+ const char* value, const char* subsection)
+{
+ VICISection* target = section;
+ DBG("key: %s, value: %s, subsection: %s", key, value, subsection);
+
+ if (section == NULL || key == NULL) {
+ connman_error("invalid parameter");
+ return -1;
+ }
+
+ if (subsection)
+ target = get_subsection(section, subsection);
+
+ add_kv_to_section(key, value, target);
+ return 0;
+}
+
+int vici_add_kvl(VICISection* section, const char* key,
+ const char* value, const char* subsection)
+{
+ VICISection* target = section;
+
+ DBG("key: %s, value: %s, subsection: %s", key, value, subsection);
+ if (section == NULL || key == NULL) {
+ connman_error("invalid parameter");
+ return -1;
+ }
+
+ if (subsection)
+ target = get_subsection(section, subsection);
+
+ if (g_strcmp0(subsection, "children") == 0)
+ target = get_subsection(target, "net");
+
+ add_kvl_to_section(key, value, target);
+ return 0;
+}
+
+static void add_list_to_section(char *key, GSList *list, VICISection *section)
+{
+ if (section == NULL || key == NULL || list == NULL)
+ return;
+
+ g_hash_table_insert(section->kvls, g_strdup(key), g_slist_copy_deep(list, (GCopyFunc)g_strdup, NULL));
+ return;
+}
+
+int vici_add_list(VICISection* section, char *key, GSList *list, const char* subsection)
+{
+ VICISection* target = section;
+
+ DBG("key: %s, subsection: %s", key, subsection);
+ if (section == NULL || key == NULL) {
+ connman_error("invalid parameter");
+ return -1;
+ }
+
+ if (subsection)
+ target = get_subsection(section, subsection);
+
+ if (g_strcmp0(subsection, "children") == 0)
+ target = get_subsection(target, "net");
+
+ add_list_to_section(key, list, target);
+ return 0;
+}
+
+static char *load_cert_from_path(const char *path)
+{
+ struct stat st;
+ FILE *fp = NULL;
+ int fd = 0;
+ size_t file_size = 0;
+ char *file_buff = NULL;
+
+ fp = fopen(path, "rb");
+ if (fp == NULL) {
+ connman_error("fopen failed");
+ return NULL;
+ }
+
+ fd = fileno(fp);
+ if (fd == -1) {
+ connman_error("fp is not a valid stream");
+ fclose(fp);
+ return NULL;
+ }
+
+ if (fstat(fd, &st) != 0) {
+ connman_error("fstat failed");
+ fclose(fp);
+ return NULL;
+ }
+
+ file_size = st.st_size;
+ file_buff = g_try_malloc0(sizeof(char)*st.st_size);
+ if (file_buff == NULL) {
+ connman_error("g_try_malloc0 failed\n");
+ fclose(fp);
+ return NULL;
+ }
+
+ if (fread(file_buff, 1, file_size, fp) != file_size) {
+ connman_error("file size not matched\n");
+ g_free(file_buff);
+ file_buff = NULL;
+ }
+
+ fclose(fp);
+ return file_buff;
+}
+
+int vici_add_cert_kv(VICISection *section, const char *key,
+ const char *value, const char *subsection)
+{
+ char *cert = NULL;
+ int ret = 0;
+
+ if (value == NULL) {
+ DBG("value is null");
+ return 0;
+ }
+
+ cert = load_cert_from_path(value);
+ if (!cert)
+ return -1;
+
+ ret = vici_add_kv(section, key, (const char *)cert, subsection);
+ g_free(cert);
+ return ret;
+}
+
+int vici_add_cert_kvl(VICISection *section, const char *key,
+ const char *value, const char *subsection)
+{
+ char *cert = NULL;
+ int ret = 0;
+
+ cert = load_cert_from_path(value);
+ if (!cert)
+ return -1;
+
+ ret = vici_add_kvl(section, key, (const char *)cert, subsection);
+ g_free(cert);
+ return ret;
+}
+
+static void *add_element(struct request *r, enum vici_element type,
+ unsigned int size)
+{
+ unsigned int newlen;
+ void *ret, *new;
+
+ if (r->used + size + 1 > r->allocated) {
+ newlen = r->allocated;
+ while (newlen < r->used + size + 1) {
+ newlen *= 2;
+ }
+ new = realloc(r->sndbuf, newlen);
+ if (!new) {
+ r->err = -errno;
+ return NULL;
+ }
+ r->sndbuf = new;
+ r->allocated = newlen;
+ }
+ r->sndbuf[r->used++] = type;
+ ret = r->sndbuf + r->used;
+ r->used += size;
+ return ret;
+}
+
+static void section_start(struct request *r, const char *name)
+{
+ uint8_t nlen;
+ char *pos;
+
+ nlen = strlen(name);
+ pos = add_element(r, VICI_SECTION_START, 1 + nlen);
+ if (pos) {
+ pos[0] = nlen;
+ memcpy(pos + 1, name, nlen);
+ }
+}
+
+static void section_end(struct request *r)
+{
+ add_element(r, VICI_SECTION_END, 0);
+}
+
+static void key_value(struct request *r, const char *name,
+ const void *buf, unsigned int buflen)
+{
+ uint8_t nlen;
+ uint16_t vlen;
+ char *pos;
+
+ nlen = strlen(name);
+ pos = add_element(r, VICI_KEY_VALUE, 1 + nlen + sizeof(vlen) + buflen);
+ if (pos) {
+ pos[0] = nlen;
+ memcpy(pos + 1, name, nlen);
+ vlen = htons(buflen);
+ memcpy(pos + 1 + nlen, &vlen, sizeof(vlen));
+ memcpy(pos + 1 + nlen + sizeof(vlen), buf, buflen);
+ }
+}
+
+
+static void list_start(struct request *r, const char *name)
+{
+ uint8_t nlen;
+ char *pos;
+
+ nlen = strlen(name);
+ pos = add_element(r, VICI_LIST_START, 1 + nlen);
+ if (pos) {
+ pos[0] = nlen;
+ memcpy(pos + 1, name, nlen);
+ }
+}
+
+static void list_item(struct request *r, const void *buf,
+ unsigned int buflen)
+{
+ uint16_t vlen;
+ char *pos;
+
+ pos = add_element(r, VICI_LIST_ITEM, sizeof(vlen) + buflen);
+ if (pos) {
+ vlen = htons(buflen);
+ memcpy(pos, &vlen, sizeof(vlen));
+ memcpy(pos + sizeof(vlen), buf, buflen);
+ }
+}
+
+static void list_end(struct request *r)
+{
+ add_element(r, VICI_LIST_END, 0);
+}
+
+static void destroy_vici_request(gpointer data)
+{
+ struct request *req = (struct request *)data;
+ if(!req)
+ return;
+
+ g_free(req->sndbuf);
+ g_free(req);
+}
+
+static int create_vici_request(enum vici_packet_type type, VICIClientCmd cmd,
+ struct request **rp)
+{
+ struct request *req = NULL;
+
+ if (cmd >= VICI_CMD_MAX || !rp)
+ return -EINVAL;
+
+ req = g_try_new0(struct request, 1);
+ if (!req) {
+ connman_error("g_try_new0 failed");
+ return -ENOMEM;
+ }
+
+ req->used = 2;
+ req->used += strlen(vici_cmd_str[cmd]);
+ req->allocated = MIN(32, req->used);
+ req->sndbuf = g_try_new0(char, req->allocated);
+ if (!req->sndbuf) {
+ connman_error("g_try_new0 failed");
+ g_free(req);
+ return -ENOMEM;
+ }
+
+ req->sndbuf[0] = type;
+ req->sndbuf[1] = req->used - 2; /* except for type and name length */
+ memcpy(req->sndbuf + 2, vici_cmd_str[cmd], req->used - 2);
+ req->hdr_len = req->used;
+ req->cmd = cmd;
+
+ *rp = req;
+
+ return 0;
+}
+
+static void write_section_kvs(VICISection *section, struct request *req)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (section == NULL || req == NULL)
+ return;
+
+ g_hash_table_iter_init (&iter, section->kvs);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (!key || !value)
+ continue;
+ key_value(req, (const char*)key, (const void *)value, strlen((char *)value));
+ }
+
+ return;
+}
+
+static void write_list_item(gpointer data, gpointer user_data)
+{
+ struct request *req = NULL;
+ char *value = NULL;
+
+ if (!data || !user_data)
+ return;
+
+ value = (char *)data;
+ req = (struct request *)user_data;
+ list_item(req, value, strlen(value));
+
+ return;
+}
+
+static void write_section_kvls(VICISection *section, struct request *req)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (section == NULL || req == NULL)
+ return;
+
+ g_hash_table_iter_init (&iter, section->kvls);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (!key || !value)
+ continue;
+
+ list_start(req, key);
+ g_slist_foreach((GSList *)value, (GFunc)write_list_item, (gpointer)req);
+ list_end(req);
+ }
+
+ return;
+}
+
+static void write_section(struct request *req, VICISection *section)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (req == NULL || section == NULL)
+ return;
+
+ if (section->name)
+ section_start(req, section->name);
+
+ write_section_kvs(section, req);
+ write_section_kvls(section, req);
+
+ g_hash_table_iter_init(&iter, section->subsection);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (!key || !value)
+ continue;
+ write_section(req, (VICISection *)value);
+ }
+
+ if (section->name)
+ section_end(req);
+ return;
+}
+
+static int check_socket(int sock)
+{
+ struct pollfd p_fd;
+ int res = 0;
+
+ p_fd.fd = sock;
+ p_fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL;
+ res = poll((struct pollfd *) &p_fd, 1, 1);
+
+ if (res < 0) {
+ connman_error("Polling error from socket\n");
+ return -1;
+ } else if (res == 0) {
+ connman_error( "poll timeout. socket is busy\n");
+ return 1;
+ } else {
+
+ if (p_fd.revents & POLLERR) {
+ connman_error("Error! POLLERR from socket[%d]\n", sock);
+ return -1;
+ } else if (p_fd.revents & POLLHUP) {
+ connman_error("Error! POLLHUP from socket[%d]\n", sock);
+ return -1;
+ } else if (p_fd.revents & POLLNVAL) {
+ connman_error("Error! POLLNVAL from socket[%d]\n", sock);
+ return -1;
+ } else if (p_fd.revents & POLLIN) {
+ return 0;
+ } else if (p_fd.revents & POLLOUT) {
+ return 0;
+ }
+ }
+
+ connman_error("Unknown poll event [%d]\n", p_fd.revents);
+ return -1;
+}
+
+static int write_socket(int sock, char *data, int data_len)
+{
+ int wbytes = 0;
+ int left_len = data_len;
+ char *ptr = data;
+ int res = 0;
+
+ if (sock < SOCK_FD_MIN || !data || data_len < 0)
+ return -1;
+
+ res = check_socket(sock);
+ if (res < 0)
+ return -1;
+ else if (res > 0)
+ return -2;
+
+ errno = 0;
+ while (left_len) {
+ wbytes = write(sock, ptr, left_len);
+ if (wbytes <= 0) {
+ connman_error("Failed to write data into socket[%d].\n", sock);
+ break;
+ }else if (wbytes < left_len) {
+ left_len -= wbytes;
+ ptr += wbytes;
+ } else if (wbytes == left_len) {
+ left_len = 0;
+ } else {
+ connman_error("Unknown error occurred.\n");
+ break;
+ }
+ }
+
+ if (left_len)
+ return -1;
+ else
+ return 0;
+}
+
+int send_vici_command(struct request *req, VICIClient *vici_client)
+{
+ unsigned int size = 0;
+ int sock_fd = 0;
+ int res = 0;
+
+ if (req == NULL || vici_client == NULL) {
+ connman_error("request is NULL\n");
+ return -EINVAL;
+ }
+ sock_fd = vici_client->client_sock_fd;
+
+ size = htonl(req->used);
+ res = write_socket(sock_fd, (char *)&size, sizeof(size));
+ if (res != 0) {
+ connman_error("failed to send size with network byte order\n");
+ return -EIO;
+ }
+
+ res = write_socket(sock_fd, req->sndbuf, req->used);
+ if (res != 0) {
+ connman_error("failed to send pkt\n");
+ return -EIO;
+ }
+
+ if(req->cmd != VICI_CMD_REGISTER_CHILD_UPDOWN)
+ vici_client->request_list = g_slist_append(vici_client->request_list, req);
+
+ return res;
+}
+
+static void print_vici_element(int elem_type, char *value, int sections)
+{
+ int i = 0;
+
+
+ switch (elem_type) {
+ case VICI_SECTION_START:
+ for (i = 0; i < sections - 1; i++)
+ DBG("\t");
+ DBG("%s = {\n", value);
+ break;
+ case VICI_SECTION_END:
+ for (i = 0; i < sections; i++)
+ DBG("\t");
+ DBG("}\n");
+ break;
+ case VICI_KEY_VALUE:
+ for (i = 0; i < sections; i++)
+ DBG("\t");
+ DBG("%s\n", value);
+ break;
+ case VICI_LIST_START:
+ for (i = 0; i < sections; i++)
+ DBG("\t");
+ DBG("%s = [", value);
+ break;
+ case VICI_LIST_ITEM:
+ DBG("%s, ", value);
+ break;
+ case VICI_LIST_END:
+ DBG("]\n");
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+static void debug_vici_message(char *buf, unsigned int size)
+{
+ char temp[255];
+ unsigned int pos = 0;
+ int len = 0;
+ int sections = 0;
+ int type = -1;
+
+ if (buf == NULL || size == 0)
+ return;
+
+ pos = 1;
+ while (pos < size) {
+
+ type = buf[pos];
+ pos++;
+ switch (type) {
+ case VICI_SECTION_START:
+ {
+ len = buf[pos];
+ pos++;
+ g_strlcpy(temp, (const gchar *)&buf[pos], len + 1);
+ pos += len;
+ sections++;
+ }
+ break;
+ case VICI_SECTION_END:
+ {
+ sections--;
+ }
+ break;
+ case VICI_KEY_VALUE:
+ {
+ int key_len = 0;
+ int value_len = 0;
+
+ key_len = buf[pos];
+ pos++;
+ g_strlcpy(temp, (const gchar *)&buf[pos], key_len + 1);
+ temp[key_len] = '=';
+ pos += (key_len + 1);
+ value_len = buf[pos];
+ pos++;
+ g_strlcpy(temp + key_len + 1, (const gchar *)&buf[pos], value_len + 1);
+ pos += value_len;
+ }
+ break;
+ case VICI_LIST_START:
+ {
+ len = buf[pos];
+ pos++;
+ g_strlcpy(temp, (const gchar *)&buf[pos], len + 1);
+ pos += len;
+ }
+ break;
+ case VICI_LIST_ITEM:
+ {
+ pos++;
+ len = buf[pos];
+ pos++;
+ g_strlcpy(temp, (const gchar *)&buf[pos], len + 1);
+ pos += len;
+ }
+ break;
+ case VICI_LIST_END:
+ break;
+ default:
+ break;
+ }
+ print_vici_element(type, temp, sections);
+ }
+ return;
+}
+
+static unsigned int extract_key_value(char *buf, unsigned int pos, char **key, char **value)
+{
+ int key_len = 0;
+ int value_len = 0;
+
+ key_len = buf[pos];
+ pos++;
+ *key = g_strndup((const gchar *)&buf[pos], key_len);
+ pos+=(key_len + 1);
+ value_len = buf[pos];
+ pos++;
+ *value = g_strndup((const gchar *)&buf[pos], value_len);
+ pos+=value_len;
+ return pos;
+}
+
+static gboolean extract_request_result(char *buf, unsigned int size, char **err)
+{
+ gboolean success = FALSE;
+ unsigned int pos = 0;
+ int type = -1;
+
+ pos = 1;
+ while (pos < size) {
+
+ type = buf[pos];//3
+ pos++;
+ if (type == VICI_KEY_VALUE) {
+ char *key = NULL;
+ char *value = NULL;
+ pos = extract_key_value(buf, pos, &key, &value);
+ DBG("pos : %d size : %d\n", pos, size);
+
+ /* TODO :remove this after debug */
+ DBG("key : %s value : %s\n", key, value);
+ if (g_strcmp0(key, "success") == 0)
+ (g_strcmp0(value, "yes") == 0)?(success = TRUE):(success = FALSE);
+
+ if (g_strcmp0(key, "errmsg"))
+ *err = g_strdup(value);
+ g_free(key);
+ g_free(value);
+ }
+ }
+ return success;
+}
+
+static int handle_vici_result(gboolean success, int cmd, char * err)
+{
+ int ret = 0;
+ if (success)
+ return 0;
+
+ g_free(err);
+
+ switch (cmd) {
+ case VICI_CMD_LOAD_CONN:
+ ret = EINVAL;
+ break;
+ case VICI_CMD_LOAD_SHARED:
+ ret = EINVAL;
+ break;
+ case VICI_CMD_LOAD_CERT:
+ ret = EINVAL;
+ break;
+ case VICI_CMD_LOAD_AUTH:
+ ret = 0;
+ break;
+ case VICI_CMD_LOAD_KEY:
+ ret = EINVAL;
+ break;
+ case VICI_CMD_INITIATE:
+ ret = ECONNABORTED;
+ break;
+ case VICI_CMD_TERMINATE:
+ ret = EINVAL;
+ break;
+ default:
+ break;
+ }
+
+ DBG(" %s failed with %d!\n", vici_cmd_str[cmd], ret);
+ return ret;
+}
+
+static int process_vici_response(struct request * req)
+{
+ char *err = NULL;
+ gboolean success = FALSE;
+ int ret = 0;
+
+ if (!req)
+ return -1;
+
+ if (!req->rcvbuf || req->rcvbuf[0] != VICI_CMD_RESPONSE)
+ return -1;
+
+ //TODO: remove below when there's no further problem.
+ debug_vici_message(req->rcvbuf, req->rcv_pkt_size);
+
+ success = extract_request_result(req->rcvbuf, req->rcv_pkt_size, &err);
+ ret = handle_vici_result(success, req->cmd, err);
+
+ return ret;
+}
+
+int vici_send_request(VICIClient *vici_client, VICIClientCmd cmd, VICISection *root)
+{
+ struct request *req = NULL;
+ int ret;
+
+ DBG("%s", vici_cmd_str[cmd]);
+ ret = create_vici_request(VICI_CMD_REQUEST, cmd, &req);
+ if (ret < 0) {
+ connman_error("error on create_request\n");
+ return ret;
+ }
+
+ write_section(req, root);
+ //TODO: remove below when there's no further problem.
+ debug_vici_message(req->sndbuf + req->hdr_len - 1, req->used - req->hdr_len + 1);
+
+ ret = send_vici_command(req, vici_client);
+ if (ret < 0) {
+ destroy_vici_request(req);
+ connman_error("error on send_command\n");
+ }
+
+ return ret;
+}
+
+
+int vici_set_event_cb(VICIClient *vici_client, vici_event_cb cb, gpointer user_data)
+{
+ struct request *req = NULL;
+ int ret;
+
+ DBG("%s",vici_cmd_str[VICI_EVENT_CHILD_UP]);
+ ret = create_vici_request(VICI_EVENT_REGISTER, VICI_CMD_REGISTER_CHILD_UPDOWN, &req);
+ if (ret < 0) {
+ connman_error("error on create_request\n");
+ return ret;
+ }
+
+ ret = send_vici_command(req, vici_client);
+ if (ret < 0) {
+ connman_error("error on send_command\n");
+ }
+
+ destroy_vici_request(req);
+ vici_client->event_cb = cb;
+ vici_client->event_user_data = user_data;
+
+ return ret;
+
+}
+
+static int get_socket_from_source(GIOChannel *source, GIOCondition condition)
+{
+ int sock = -1;
+ /* check socket */
+ sock = g_io_channel_unix_get_fd(source);
+ if (sock < SOCK_FD_MIN)
+ return -1;
+
+ if ((condition & G_IO_ERR) || (condition & G_IO_HUP) || (condition & G_IO_NVAL)) {
+ connman_error("G_IO_ERR/G_IO_HUP/G_IO_NVAL received sock [%d] condition [%d]\n", sock, condition);
+ //TODO: handle the breaking socket
+ return -1;
+ }
+ return sock;
+}
+
+static int read_socket(int sock, char *data, unsigned int data_len)
+{
+ int rbytes = 0;
+ int total_rbytes = 0;
+
+ if (sock < SOCK_FD_MIN || !data || data_len <= 0)
+ return -1;
+
+ while (data_len > 0) {
+ errno = 0;
+ rbytes = read(sock, data, data_len);
+ if (rbytes <= 0)
+ return -1;
+
+ total_rbytes += rbytes;
+ data += rbytes;
+ data_len -= rbytes;
+ }
+
+ return total_rbytes;
+}
+
+static int recv_vici_pkt(int sock, struct _VICIClient *vici_client)
+{
+ if(!vici_client)
+ return -1;
+
+ if (vici_client->rcv_pkt_size == 0) {
+ unsigned int pkt_size = 0;
+ if (read_socket(sock, (char *)&pkt_size, sizeof(pkt_size)) < 0)
+ return -1;
+
+ vici_client->rcv_pkt_size = ntohl(pkt_size);
+ /* TODO :REMOVE THIS AFTER DEBUG */
+ DBG("rcv_pkt_size [%d] will be recved\n", vici_client->rcv_pkt_size);
+ } else {
+
+ DBG("rcv_pkt_size [%d] is recved\n", vici_client->rcv_pkt_size);
+ char *buf = NULL;
+ buf = g_try_malloc0(vici_client->rcv_pkt_size);
+ if (buf == NULL)
+ return -1;
+
+ if (read_socket(sock, buf, vici_client->rcv_pkt_size) < 0) {
+ g_free(buf);
+ return -1;
+ }
+ vici_client->rcvbuf = buf;
+ }
+
+ return 0;
+}
+
+static struct request *pop_vici_request(VICIClient *vici_client)
+{
+ GSList *list = NULL;
+
+ if (!vici_client)
+ return NULL;
+
+ list = vici_client->request_list;
+ if(!list)
+ return NULL;
+
+ return list->data;
+}
+
+static void process_vici_reply(VICIClient *vici_client)
+{
+ struct request *req;
+ int ret = 0;
+
+ if (!vici_client)
+ return;
+
+ /* get first request */
+ req = pop_vici_request(vici_client);
+ if (!req)
+ return;
+
+ req->rcvbuf = vici_client->rcvbuf;
+ req->rcv_pkt_size = vici_client->rcv_pkt_size;
+
+ ret = process_vici_response(req);
+ vici_client->request_list = g_slist_remove(vici_client->request_list, req);
+ destroy_vici_request(req);
+
+ /* TODO :remove this after debug */
+ DBG("left request reply : %d", g_slist_length(vici_client->request_list));
+
+ if (ret != 0 || g_slist_length(vici_client->request_list) == 0)
+ vici_client->reply_cb(ret, vici_client->reply_user_data);
+
+}
+
+static int extract_event_name(char *buf, unsigned int size, char *temp)
+{
+ int pos = 1;
+ int name_len = 0;
+ name_len = buf[pos];
+ pos++;
+ DBG("event len: %d", name_len);
+ while(pos < size && pos - 2 < name_len) {
+ temp[pos - 2] = buf[pos];
+ pos++;
+ }
+ temp[pos] = '\0';
+ DBG("event name: %s", temp);
+ return pos;
+}
+
+static char *vici_get_value(char *buf, unsigned int pos, unsigned int size, char *search_key)
+{
+ int type = -1;
+
+ pos = 1;
+ while (pos < size) {
+
+ type = buf[pos];//3
+ pos++;
+ if (type == VICI_KEY_VALUE) {
+ char *key = NULL;
+ char *value = NULL;
+ pos = extract_key_value(buf, pos, &key, &value);
+ if (g_strcmp0(search_key, key) == 0) {
+ g_free(key);
+ return value;
+ }
+
+ g_free(key);
+ g_free(value);
+ }
+ }
+ return NULL;
+}
+
+static void process_child_updown(VICIClient *vici_client,char *buf, unsigned int size)
+{
+ char *state = NULL;
+
+ state = vici_get_value(buf, 0, size, "state");
+ if (g_strcmp0(state, "ESTABLISHED") == 0) {
+ DBG("ESTABLISHED");
+ vici_client->event_cb(VICI_EVENT_CHILD_UP, vici_client->event_user_data);
+ } else if (g_strcmp0(state, "DELETING") == 0) {
+ DBG("DELETING");
+ vici_client->event_cb(VICI_EVENT_CHILD_DOWN, vici_client->event_user_data);
+ } else {
+ DBG("Unknown event");
+ }
+ g_free(state);
+ return;
+}
+
+static void process_vici_event(VICIClient *vici_client)
+{
+ char *buf = NULL;
+ unsigned int size = 0;
+ unsigned int pos = 0;
+ char temp[256] = {0,};
+ if (!vici_client || !(vici_client->rcvbuf) || vici_client->rcv_pkt_size == 0)
+ return;
+
+ buf = vici_client->rcvbuf;
+ size = vici_client->rcv_pkt_size;
+
+ pos = extract_event_name(buf, size, temp);
+ /* TODO: remove below after debug */
+ /* add parser */
+ if (g_strcmp0(temp, "child-updown") == 0)
+ process_child_updown(vici_client, buf + pos -1, size - pos);
+}
+
+static void process_vici_packet(VICIClient *vici_client, char *buf)
+{
+
+ if (!vici_client || !buf)
+ return;
+
+ if (buf[0] == VICI_CMD_RESPONSE) {
+ DBG("VICI_CMD_RESPONSE\n");
+ process_vici_reply(vici_client);
+ } else if (buf[0] == VICI_EVENT_CONFIRM) {
+ DBG("VICI_EVENT_CONFIRM\n");
+ } else if (buf[0] == VICI_EVENT) {
+ DBG("VICI_EVENT");
+ process_vici_event(vici_client);
+ } else {
+ DBG("Not handled [%u]", buf[0]);
+ }
+ return;
+}
+
+static gboolean process_vici_msg(GIOChannel *source,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ VICIClient *vici_client = NULL;
+ int sock = 0;
+
+ vici_client = (VICIClient *)user_data;
+ if (!vici_client)
+ return FALSE;
+
+ sock = get_socket_from_source(source, condition);
+ if (sock < 0)
+ return FALSE;
+
+
+ if(recv_vici_pkt(sock, vici_client) < 0)
+ return FALSE;
+
+ if (!vici_client->rcvbuf) {
+ return TRUE;
+ }
+
+ process_vici_packet(vici_client, vici_client->rcvbuf);
+ g_free(vici_client->rcvbuf);
+ vici_client->rcvbuf = NULL;
+ vici_client->rcv_pkt_size = 0;
+
+ return TRUE;
+}
+
+static int str_to_socket_addr(const char *uri, struct sockaddr_un *addr)
+{
+ memset(addr, 0, sizeof(*addr));
+ addr->sun_family = AF_UNIX;
+ strncpy(addr->sun_path, uri, sizeof(addr->sun_path));
+
+ addr->sun_path[sizeof(addr->sun_path)-1] = '\0';
+
+ return offsetof(struct sockaddr_un, sun_path) + strlen(addr->sun_path);
+}
+
+static int connect_socket(const char *uri)
+{
+ struct sockaddr_un addr;
+ int len, fd;
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
+ connman_error("socket() failed");
+ return -errno;
+ }
+
+ len = str_to_socket_addr(uri, &addr);
+ if (len == -1) {
+ connman_error("str_to_socket_addr failed");
+ close(fd);
+ return -1;
+ }
+
+ if (connect(fd, (struct sockaddr*)&addr, len) < 0) {
+ connman_error("connect failed. errno %d/%s", errno, strerror(errno));
+ close(fd);
+ return -errno;
+ }
+
+ return fd;
+}
+
+static int initialize_vici_source(VICIClient *vici_client)
+{
+ GIOChannel *vici_channel;
+ if (!vici_client) {
+ return -ENOMEM;
+ }
+
+ vici_client->client_sock_fd = connect_socket(VICI_DEFAULT_URI);
+ if (vici_client->client_sock_fd < 0) {
+ connman_error("connect_socket failed");
+ return -EIO;
+ }
+
+ vici_channel = g_io_channel_unix_new(vici_client->client_sock_fd);
+ if (!vici_channel) {
+ connman_error("g_io_channel_unix_new failed");
+ close(vici_client->client_sock_fd);
+ return -ENOMEM;
+ }
+
+ vici_client->client_watch = g_io_add_watch_full(vici_channel,
+ G_PRIORITY_LOW,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ (GIOFunc)process_vici_msg,
+ (gpointer)vici_client,
+ NULL);
+ g_io_channel_unref(vici_channel);
+ return 0;
+}
+
+int vici_initialize(VICIClient **vici_client)
+{
+ int ret = 0;
+
+ *vici_client = g_try_new0(VICIClient, 1);
+ if (!*vici_client) {
+ connman_error("out of memory");
+ return -ENOMEM;
+ }
+
+ ret = initialize_vici_source(*vici_client);
+ if (ret != 0) {
+ g_free(*vici_client);
+ return ret;
+ }
+
+ DBG("connected");
+ return 0;
+}
+
+void vici_set_request_reply_cb(VICIClient *vici_client, vici_request_reply_cb reply_cb, gpointer user_data)
+{
+ vici_client->reply_cb = reply_cb;
+ vici_client->reply_user_data = user_data;
+}
+
+int vici_deinitialize(VICIClient *vici_client)
+{
+ if (vici_client->client_watch > 0) {
+ g_source_remove(vici_client->client_watch);
+ vici_client->client_watch = 0;
+ }
+
+ close(vici_client->client_sock_fd);
+ g_slist_free_full(vici_client->request_list, destroy_vici_request);
+ g_free(vici_client->rcvbuf);
+ g_free(vici_client);
+
+ return 0;
+}
--- /dev/null
+/*
+ *
+ * ConnMan VPN daemon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __VICI_CLIENT_H
+#define __VICI_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* strongswan VICI plugin client part*/
+struct _VICIClient;
+typedef struct _VICIClient VICIClient;
+
+struct _VICISection;
+typedef struct _VICISection VICISection;
+
+typedef enum {
+ VICI_CMD_LOAD_CONN,
+ VICI_CMD_LOAD_SHARED,
+ VICI_CMD_LOAD_CERT,
+ VICI_CMD_LOAD_AUTH,
+ VICI_CMD_UNLOAD_AUTH,
+ VICI_CMD_LOAD_KEY,
+ VICI_CMD_INITIATE,
+ VICI_CMD_TERMINATE,
+ VICI_CMD_REGISTER_CHILD_UPDOWN,
+ VICI_CMD_MAX,
+} VICIClientCmd;
+
+typedef enum {
+ VICI_EVENT_CHILD_UP,
+ VICI_EVENT_CHILD_DOWN,
+ VICI_EVENT_MAX,
+} VICIClientEvent;
+#define VICI_DEFAULT_URI "/var/run/charon.vici"
+
+typedef int (*vici_add_element)(VICISection *sect, const char *key,
+ const char *value, const char *subsection);
+
+typedef void (*vici_request_reply_cb)(int err, void *user_data);
+typedef void (*vici_event_cb)(VICIClientEvent event, void *user_data);
+
+VICISection* vici_create_section(const char *name);
+int add_subsection(const char* name, VICISection* child, VICISection* section);
+void vici_destroy_section(VICISection *sect);
+int vici_add_kv(VICISection *sect, const char *key,
+ const char *value, const char *subsection);
+int vici_add_kvl(VICISection *sect, const char *key,
+ const char *value, const char *subsection);
+int vici_add_list(VICISection* section, char *key,
+ GSList *list, const char* subsection);
+int vici_add_cert_kv(VICISection *section, const char *key,
+ const char *value, const char *subsection);
+int vici_add_cert_kvl(VICISection *section, const char *key,
+ const char *value, const char *subsection);
+
+int vici_initialize(VICIClient **vici_client);
+int vici_deinitialize(VICIClient *vici_client);
+void vici_set_request_reply_cb(VICIClient *vici_client, vici_request_reply_cb reply_cb, gpointer user_data);
+int vici_send_request(VICIClient *vici_client, VICIClientCmd cmd, VICISection *root);
+int vici_set_event_cb(VICIClient *vici_client, vici_event_cb cb, gpointer user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VICI_CLIENT_H */
return NULL;
}
+#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);
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);
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,
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;
}
<policy user="root">
<allow own="net.connman.vpn"/>
<allow send_destination="net.connman.vpn"/>
- <allow send_interface="net.connman.vpn.Agent"/>
+ <allow send_interface="net.connman.vpn.Agent"/>
+ </policy>
+ <policy user="network_fw">
+ <allow own="net.connman.vpn"/>
+ <allow send_destination="net.connman.vpn"/>
+ <allow send_interface="net.connman.vpn.Agent"/>
</policy>
<policy at_console="true">
<allow send_destination="net.connman.vpn"/>
<allow own="net.connman.vpn"/>
<allow send_interface="net.connman.vpn.Agent"/>
</policy>
+ <policy user="network_fw">
+ <allow own="net.connman.vpn"/>
+ <allow send_interface="net.connman.vpn.Agent"/>
+ </policy>
<policy context="default">
<allow send_destination="net.connman.vpn"/>
</policy>
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 __vpn_ipconfig_cleanup(void);
#include "vpn-provider.h"
-
+#if !defined TIZEN_EXT
char *__vpn_provider_create_identifier(const char *host, const char *domain);
+#else
+char *__vpn_provider_create_identifier(const char *host, const char *domain, const char *name);
+#endif
bool __vpn_provider_check_routes(struct vpn_provider *provider);
int __vpn_provider_append_user_route(struct vpn_provider *provider,
int family, const char *network,