summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]AUTHORS0
-rw-r--r--HACKING109
-rwxr-xr-x[-rw-r--r--]Makefile.am119
-rwxr-xr-x[-rw-r--r--]Makefile.plugins37
-rwxr-xr-x[-rw-r--r--]README0
-rwxr-xr-x[-rw-r--r--]TODO0
-rwxr-xr-x[-rw-r--r--]acinclude.m40
-rwxr-xr-x[-rw-r--r--]client/agent.c0
-rwxr-xr-x[-rw-r--r--]client/agent.h0
-rwxr-xr-x[-rw-r--r--]client/commands.c24
-rwxr-xr-x[-rw-r--r--]client/commands.h0
-rwxr-xr-x[-rw-r--r--]client/dbus_helpers.c0
-rwxr-xr-x[-rw-r--r--]client/dbus_helpers.h0
-rwxr-xr-x[-rw-r--r--]client/input.c2
-rwxr-xr-x[-rw-r--r--]client/input.h0
-rwxr-xr-x[-rw-r--r--]client/main.c0
-rwxr-xr-x[-rw-r--r--]client/peers.c0
-rwxr-xr-x[-rw-r--r--]client/peers.h0
-rwxr-xr-x[-rw-r--r--]client/services.c0
-rwxr-xr-x[-rw-r--r--]client/services.h0
-rwxr-xr-x[-rw-r--r--]client/vpnconnections.c0
-rwxr-xr-x[-rw-r--r--]client/vpnconnections.h0
-rw-r--r--configure.ac75
-rw-r--r--connman.manifest5
-rwxr-xr-x[-rw-r--r--]doc/advanced-configuration.txt0
-rwxr-xr-x[-rw-r--r--]doc/agent-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/backtrace.txt0
-rwxr-xr-x[-rw-r--r--]doc/behavior-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/clock-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/config-format.txt0
-rw-r--r--doc/connman.conf.5.in2
-rwxr-xr-x[-rw-r--r--]doc/counter-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/ipconfig-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/manager-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/overview-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/peer-api.txt1
-rwxr-xr-x[-rw-r--r--]doc/plugin-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/service-api.txt33
-rwxr-xr-x[-rw-r--r--]doc/session-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/session-overview.txt0
-rwxr-xr-x[-rw-r--r--]doc/session-policy-format.txt0
-rwxr-xr-x[-rw-r--r--]doc/technology-api.txt17
-rw-r--r--doc/valgrind.suppressions235
-rw-r--r--doc/vpn-config-format.txt29
-rwxr-xr-x[-rw-r--r--]doc/vpn-connection-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/vpn-manager-api.txt0
-rwxr-xr-x[-rw-r--r--]doc/vpn-overview.txt0
-rwxr-xr-x[-rw-r--r--]gdbus/client.c8
-rwxr-xr-x[-rw-r--r--]gdbus/gdbus.h6
-rwxr-xr-x[-rw-r--r--]gdbus/mainloop.c4
-rwxr-xr-x[-rw-r--r--]gdbus/object.c2
-rwxr-xr-x[-rw-r--r--]gdbus/polkit.c0
-rwxr-xr-x[-rw-r--r--]gdbus/watch.c0
-rwxr-xr-x[-rw-r--r--]gdhcp/client.c193
-rwxr-xr-x[-rw-r--r--]gdhcp/common.c65
-rwxr-xr-x[-rw-r--r--]gdhcp/common.h1
-rwxr-xr-x[-rw-r--r--]gdhcp/gdhcp.h14
-rwxr-xr-x[-rw-r--r--]gdhcp/ipv4ll.c0
-rwxr-xr-x[-rw-r--r--]gdhcp/ipv4ll.h0
-rwxr-xr-x[-rw-r--r--]gdhcp/server.c29
-rwxr-xr-x[-rw-r--r--]gsupplicant/dbus.c0
-rwxr-xr-x[-rw-r--r--]gsupplicant/dbus.h0
-rwxr-xr-x[-rw-r--r--]gsupplicant/gsupplicant.h58
-rw-r--r--gsupplicant/supplicant.c779
-rwxr-xr-x[-rw-r--r--]gweb/giognutls.c1
-rwxr-xr-x[-rw-r--r--]gweb/giognutls.h0
-rwxr-xr-x[-rw-r--r--]gweb/gionotls.c0
-rwxr-xr-x[-rw-r--r--]gweb/gresolv.c8
-rwxr-xr-x[-rw-r--r--]gweb/gresolv.h0
-rwxr-xr-x[-rw-r--r--]gweb/gweb.c14
-rwxr-xr-x[-rw-r--r--]gweb/gweb.h0
-rwxr-xr-x[-rw-r--r--]include/agent.h0
-rw-r--r--include/backtrace.h32
-rwxr-xr-x[-rw-r--r--]include/dbus.h4
-rwxr-xr-x[-rw-r--r--]include/device.h5
-rwxr-xr-x[-rw-r--r--]include/inet.h4
-rwxr-xr-x[-rw-r--r--]include/inotify.h0
-rwxr-xr-x[-rw-r--r--]include/ipaddress.h0
-rwxr-xr-x[-rw-r--r--]include/ipconfig.h0
-rwxr-xr-x[-rw-r--r--]include/log.h4
-rwxr-xr-x[-rw-r--r--]include/machine.h0
-rwxr-xr-x[-rw-r--r--]include/network.h47
-rwxr-xr-x[-rw-r--r--]include/notifier.h0
-rwxr-xr-x[-rw-r--r--]include/option.h0
-rwxr-xr-x[-rw-r--r--]include/peer.h0
-rwxr-xr-x[-rw-r--r--]include/plugin.h0
-rwxr-xr-x[-rw-r--r--]include/provider.h0
-rwxr-xr-x[-rw-r--r--]include/provision.h0
-rwxr-xr-x[-rw-r--r--]include/proxy.h0
-rwxr-xr-x[-rw-r--r--]include/resolver.h0
-rwxr-xr-x[-rw-r--r--]include/rtnl.h0
-rwxr-xr-x[-rw-r--r--]include/service.h41
-rwxr-xr-x[-rw-r--r--]include/session.h0
-rwxr-xr-x[-rw-r--r--]include/setting.h0
-rwxr-xr-x[-rw-r--r--]include/storage.h0
-rwxr-xr-x[-rw-r--r--]include/task.h0
-rwxr-xr-x[-rw-r--r--]include/technology.h4
-rwxr-xr-x[-rw-r--r--]include/timeserver.h0
-rwxr-xr-x[-rw-r--r--]include/utsname.h0
-rwxr-xr-x[-rw-r--r--]include/version.h.in0
-rwxr-xr-x[-rw-r--r--]include/vpn-dbus.h0
-rwxr-xr-xpackaging/connman.spec343
-rwxr-xr-x[-rw-r--r--]plugins/bluetooth.c36
-rwxr-xr-x[-rw-r--r--]plugins/connman-nmcompat.conf4
-rwxr-xr-x[-rw-r--r--]plugins/dundee.c0
-rwxr-xr-x[-rw-r--r--]plugins/ethernet.c0
-rwxr-xr-x[-rw-r--r--]plugins/gadget.c87
-rwxr-xr-x[-rw-r--r--]plugins/hh2serial-gps.c0
-rwxr-xr-x[-rw-r--r--]plugins/iospm.c0
-rwxr-xr-x[-rw-r--r--]plugins/loopback.c53
-rwxr-xr-x[-rw-r--r--]plugins/mcc.h0
-rwxr-xr-x[-rw-r--r--]plugins/neard.c0
-rwxr-xr-x[-rw-r--r--]plugins/nmcompat.c0
-rwxr-xr-x[-rw-r--r--]plugins/ofono.c0
-rwxr-xr-x[-rw-r--r--]plugins/pacrunner.c0
-rwxr-xr-x[-rw-r--r--]plugins/polkit.c0
-rwxr-xr-x[-rw-r--r--]plugins/polkit.policy0
-rwxr-xr-x[-rw-r--r--]plugins/session_policy_local.c0
-rwxr-xr-xplugins/telephony.c1934
-rwxr-xr-x[-rw-r--r--]plugins/tist.c0
-rwxr-xr-x[-rw-r--r--]plugins/vpn.c2
-rwxr-xr-x[-rw-r--r--]plugins/wifi.c902
-rw-r--r--resources/usr/share/dbus-1/system-services/net.connman.service6
-rw-r--r--resources/var/lib/connman/settings15
-rw-r--r--scripts/500.connman_upgrade.sh9
-rwxr-xr-x[-rw-r--r--]scripts/connman.in2
-rw-r--r--scripts/connman_resolvconf.conf.in2
-rwxr-xr-xscripts/ipsec-script.c146
-rwxr-xr-x[-rw-r--r--]scripts/libppp-plugin.c0
-rwxr-xr-x[-rw-r--r--]scripts/openconnect-script.c0
-rwxr-xr-x[-rw-r--r--]scripts/openvpn-script.c0
-rwxr-xr-x[-rw-r--r--]src/6to4.c0
-rwxr-xr-x[-rw-r--r--]src/agent-connman.c6
-rwxr-xr-x[-rw-r--r--]src/agent.c0
-rw-r--r--src/backtrace.c138
-rwxr-xr-x[-rw-r--r--]src/bridge.c0
-rwxr-xr-x[-rw-r--r--]src/clock.c6
-rwxr-xr-x[-rw-r--r--]src/config.c52
-rwxr-xr-x[-rw-r--r--]src/connection.c70
-rwxr-xr-x[-rw-r--r--]src/connman-dbus.conf13
-rwxr-xr-x[-rw-r--r--]src/connman-polkit.conf6
-rw-r--r--src/connman-wait-online.service.in15
-rw-r--r--src/connman.conf30
-rwxr-xr-x[-rw-r--r--]src/connman.h97
-rwxr-xr-x[-rw-r--r--]src/connman.service.in18
-rw-r--r--src/connman.socket13
-rw-r--r--src/connman_tv.service.in19
-rwxr-xr-x[-rw-r--r--]src/counter.c0
-rwxr-xr-x[-rw-r--r--]src/dbus.c29
-rwxr-xr-x[-rw-r--r--]src/detect.c7
-rwxr-xr-x[-rw-r--r--]src/device.c86
-rwxr-xr-x[-rw-r--r--]src/dhcp.c73
-rwxr-xr-x[-rw-r--r--]src/dhcpv6.c89
-rwxr-xr-x[-rw-r--r--]src/dnsproxy.c352
-rwxr-xr-x[-rw-r--r--]src/eduroam.config0
-rwxr-xr-x[-rw-r--r--]src/error.c0
-rwxr-xr-x[-rw-r--r--]src/inet.c95
-rwxr-xr-x[-rw-r--r--]src/inotify.c0
-rwxr-xr-x[-rw-r--r--]src/ipaddress.c0
-rwxr-xr-x[-rw-r--r--]src/ipconfig.c79
-rwxr-xr-x[-rw-r--r--]src/ippool.c0
-rwxr-xr-x[-rw-r--r--]src/iptables.c2
-rwxr-xr-x[-rw-r--r--]src/ipv6pd.c0
-rwxr-xr-x[-rw-r--r--]src/log.c233
-rwxr-xr-x[-rw-r--r--]src/machine.c0
-rwxr-xr-x[-rw-r--r--]src/main.c75
-rwxr-xr-x[-rw-r--r--]src/main.conf7
-rwxr-xr-xsrc/main_disable_eth.conf110
-rwxr-xr-xsrc/main_ivi.conf110
-rwxr-xr-xsrc/main_tv.conf116
-rwxr-xr-x[-rw-r--r--]src/manager.c39
-rwxr-xr-x[-rw-r--r--]src/nat.c0
-rwxr-xr-x[-rw-r--r--]src/net.connman.service.in5
-rwxr-xr-x[-rw-r--r--]src/network.c478
-rwxr-xr-x[-rw-r--r--]src/notifier.c0
-rwxr-xr-x[-rw-r--r--]src/ntp.c66
-rwxr-xr-x[-rw-r--r--]src/peer.c0
-rwxr-xr-x[-rw-r--r--]src/peer_service.c0
-rwxr-xr-x[-rw-r--r--]src/plugin.c0
-rwxr-xr-x[-rw-r--r--]src/provider.c10
-rwxr-xr-x[-rw-r--r--]src/proxy.c0
-rwxr-xr-x[-rw-r--r--]src/resolver.c34
-rwxr-xr-x[-rw-r--r--]src/rfkill.c10
-rwxr-xr-x[-rw-r--r--]src/rtnl.c139
-rwxr-xr-x[-rw-r--r--]src/service.c1976
-rwxr-xr-x[-rw-r--r--]src/session.c0
-rwxr-xr-x[-rw-r--r--]src/shared/netlink.c0
-rwxr-xr-x[-rw-r--r--]src/shared/netlink.h0
-rwxr-xr-x[-rw-r--r--]src/shared/util.c0
-rwxr-xr-x[-rw-r--r--]src/shared/util.h0
-rwxr-xr-x[-rw-r--r--]src/stats.c0
-rwxr-xr-x[-rw-r--r--]src/storage.c14
-rwxr-xr-x[-rw-r--r--]src/task.c0
-rwxr-xr-x[-rw-r--r--]src/technology.c284
-rwxr-xr-x[-rw-r--r--]src/tethering.c170
-rwxr-xr-x[-rw-r--r--]src/timeserver.c14
-rwxr-xr-x[-rw-r--r--]src/timezone.c0
-rwxr-xr-x[-rw-r--r--]src/util.c0
-rwxr-xr-x[-rw-r--r--]src/utsname.c0
-rwxr-xr-x[-rw-r--r--]src/wispr.c7
-rwxr-xr-x[-rw-r--r--]src/wpad.c2
-rwxr-xr-xtest/enable-tethering34
-rwxr-xr-xtest/set-timezone21
-rwxr-xr-x[-rw-r--r--]tools/dbus-test.c0
-rwxr-xr-x[-rw-r--r--]tools/dhcp-server-test.c0
-rwxr-xr-x[-rw-r--r--]tools/dhcp-test.c0
-rwxr-xr-x[-rw-r--r--]tools/dnsproxy-test.c0
-rwxr-xr-x[-rw-r--r--]tools/iptables-test.c0
-rwxr-xr-x[-rw-r--r--]tools/iptables-unit.c0
-rwxr-xr-x[-rw-r--r--]tools/manager-api.c0
-rwxr-xr-x[-rw-r--r--]tools/netlink-test.c0
-rwxr-xr-x[-rw-r--r--]tools/polkit-test.c0
-rwxr-xr-x[-rw-r--r--]tools/private-network-test.c0
-rwxr-xr-x[-rw-r--r--]tools/resolv-test.c0
-rwxr-xr-x[-rw-r--r--]tools/session-api.c0
-rwxr-xr-x[-rw-r--r--]tools/session-test.c0
-rwxr-xr-x[-rw-r--r--]tools/session-test.h0
-rwxr-xr-x[-rw-r--r--]tools/session-utils.c0
-rwxr-xr-x[-rw-r--r--]tools/stats-tool.c0
-rwxr-xr-x[-rw-r--r--]tools/supplicant-dbus.c0
-rwxr-xr-x[-rw-r--r--]tools/supplicant-dbus.h0
-rwxr-xr-x[-rw-r--r--]tools/supplicant-test.c0
-rwxr-xr-x[-rw-r--r--]tools/supplicant.c0
-rwxr-xr-x[-rw-r--r--]tools/supplicant.h0
-rwxr-xr-x[-rw-r--r--]tools/tap-test.c0
-rwxr-xr-x[-rw-r--r--]tools/web-test.c0
-rwxr-xr-x[-rw-r--r--]tools/wispr.c0
-rwxr-xr-x[-rw-r--r--]tools/wpad-test.c0
-rwxr-xr-x[-rw-r--r--]unit/test-ippool.c0
-rwxr-xr-x[-rw-r--r--]vpn/connman-task.te0
-rwxr-xr-x[-rw-r--r--]vpn/connman-vpn.service.in10
-rwxr-xr-x[-rw-r--r--]vpn/main.c28
-rwxr-xr-x[-rw-r--r--]vpn/net.connman.vpn.service.in5
-rw-r--r--vpn/plugins/ipsec.c925
-rw-r--r--vpn/plugins/ipsec.h51
-rwxr-xr-x[-rw-r--r--]vpn/plugins/l2tp.c0
-rwxr-xr-x[-rw-r--r--]vpn/plugins/openconnect.c0
-rwxr-xr-x[-rw-r--r--]vpn/plugins/openvpn.c2
-rwxr-xr-x[-rw-r--r--]vpn/plugins/pptp.c0
-rw-r--r--vpn/plugins/vici-client.c1290
-rw-r--r--vpn/plugins/vici-client.h84
-rwxr-xr-x[-rw-r--r--]vpn/plugins/vpn.c56
-rwxr-xr-x[-rw-r--r--]vpn/plugins/vpn.h7
-rwxr-xr-x[-rw-r--r--]vpn/plugins/vpnc.c0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-agent.c0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-agent.h0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-config.c14
-rwxr-xr-x[-rw-r--r--]vpn/vpn-dbus.conf7
-rwxr-xr-x[-rw-r--r--]vpn/vpn-ipconfig.c0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-manager.c0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-polkit.conf4
-rwxr-xr-x[-rw-r--r--]vpn/vpn-polkit.policy0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-provider.c23
-rwxr-xr-x[-rw-r--r--]vpn/vpn-provider.h0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-rtnl.c0
-rwxr-xr-x[-rw-r--r--]vpn/vpn-rtnl.h0
-rwxr-xr-x[-rw-r--r--]vpn/vpn.h5
-rwxr-xr-x[-rw-r--r--]vpn/vpn.ver0
258 files changed, 12474 insertions, 838 deletions
diff --git a/AUTHORS b/AUTHORS
index 44c65f88..44c65f88 100644..100755
--- a/AUTHORS
+++ b/AUTHORS
diff --git a/HACKING b/HACKING
deleted file mode 100644
index 80382ed4..00000000
--- a/HACKING
+++ /dev/null
@@ -1,109 +0,0 @@
-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.
diff --git a/Makefile.am b/Makefile.am
index e67a7a55..76c5419c 100644..100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,8 +19,7 @@ noinst_HEADERS = include/rtnl.h include/task.h \
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)))
@@ -43,10 +42,6 @@ else
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
@@ -64,29 +59,30 @@ if VPN
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 =
@@ -98,15 +94,23 @@ builtin_libadd =
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 \
@@ -126,10 +130,10 @@ src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) $(backtrace_sources) \
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
@@ -157,28 +161,45 @@ builtin_vpn_sources =
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
@@ -216,7 +237,7 @@ build_vpn_plugindir = $(vpn_plugindir)
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)"\" \
@@ -225,7 +246,8 @@ AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
-DSCRIPTDIR=\""$(build_scriptdir)"\" \
-DSTORAGEDIR=\""$(storagedir)\"" \
-DVPN_STORAGEDIR=\""$(vpn_storagedir)\"" \
- -DCONFIGDIR=\""$(configdir)\""
+ -DCONFIGDIR=\""$(configdir)\"" \
+ -fPIE
if VPN
AM_CPPFLAGS = -I$(builddir)/include -I$(srcdir)/gdbus
@@ -249,7 +271,7 @@ EXTRA_DIST = src/genbuiltin src/connman-dbus.conf src/connman-polkit.conf \
$(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)"\" \
@@ -293,13 +315,13 @@ client_connmanctl_SOURCES = client/dbus_helpers.h client/dbus_helpers.c \
client/main.c
client_connmanctl_LDADD = gdbus/libgdbus-internal.la @DBUS_LIBS@ @GLIB_LIBS@ \
- -lreadline -ldl
+ -lreadline -ldl -lncurses
endif
noinst_PROGRAMS += unit/test-ippool
-unit_test_ippool_SOURCES = $(backtrace_sources) src/log.c src/dbus.c \
- src/error.c src/ippool.c unit/test-ippool.c
+unit_test_ippool_SOURCES = src/log.c src/dbus.c src/error.c \
+ src/ippool.c unit/test-ippool.c
unit_test_ippool_LDADD = gdbus/libgdbus-internal.la \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
@@ -352,7 +374,7 @@ tools_polkit_test_LDADD = @DBUS_LIBS@
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 \
@@ -367,7 +389,7 @@ tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl
tools_iptables_unit_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
-DIPTABLES_SAVE=\""${IPTABLES_SAVE}"\"
-tools_iptables_unit_SOURCES = $(backtrace_sources) src/log.c \
+tools_iptables_unit_SOURCES = src/log.c \
src/iptables.c src/firewall-iptables.c src/nat.c \
tools/iptables-unit.c
tools_iptables_unit_LDADD = gdbus/libgdbus-internal.la \
@@ -427,13 +449,12 @@ EXTRA_DIST += doc/overview-api.txt doc/behavior-api.txt \
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)
@@ -445,6 +466,7 @@ DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles \
--enable-hh2serial-gps \
--enable-openconnect \
--enable-openvpn \
+ --enable-ipsec \
--enable-vpnc \
--enable-session-policy-local \
--enable-nmcompat \
@@ -500,8 +522,7 @@ do_subst = $(AM_V_GEN)$(SED) \
-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 $@)
@@ -523,10 +544,6 @@ scripts/connman: scripts/connman.in Makefile
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(do_subst) < $< > $@
-scripts/connman_resolvconf.conf: scripts/connman_resolvconf.conf.in
- $(AM_V_at)$(MKDIR_P) $(dir $@)
- $(do_subst) < $< > $@
-
include/connman/version.h: include/version.h
$(AM_V_at)$(MKDIR_P) include/connman
$(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@
diff --git a/Makefile.plugins b/Makefile.plugins
index dce8b283..1eb0c3f2 100644..100755
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -58,6 +58,18 @@ builtin_modules += dundee
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
@@ -99,6 +111,25 @@ vpn_plugins_openvpn_la_LDFLAGS = $(plugin_ldflags)
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
@@ -216,6 +247,12 @@ script_PROGRAMS += scripts/openvpn-script
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
diff --git a/README b/README
index cff3131e..cff3131e 100644..100755
--- a/README
+++ b/README
diff --git a/TODO b/TODO
index c1694e3d..c1694e3d 100644..100755
--- a/TODO
+++ b/TODO
diff --git a/acinclude.m4 b/acinclude.m4
index 9e8e0dc5..9e8e0dc5 100644..100755
--- a/acinclude.m4
+++ b/acinclude.m4
diff --git a/client/agent.c b/client/agent.c
index d0208892..d0208892 100644..100755
--- a/client/agent.c
+++ b/client/agent.c
diff --git a/client/agent.h b/client/agent.h
index 669a5934..669a5934 100644..100755
--- a/client/agent.h
+++ b/client/agent.h
diff --git a/client/commands.c b/client/commands.c
index 583095b1..746e1589 100644..100755
--- a/client/commands.c
+++ b/client/commands.c
@@ -2395,12 +2395,30 @@ static struct _peer_service *fill_in_peer_service(unsigned char *bjr_query,
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) {
@@ -2408,6 +2426,12 @@ static struct _peer_service *fill_in_peer_service(unsigned char *bjr_query,
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 {
diff --git a/client/commands.h b/client/commands.h
index d5d1becf..d5d1becf 100644..100755
--- a/client/commands.h
+++ b/client/commands.h
diff --git a/client/dbus_helpers.c b/client/dbus_helpers.c
index 6ca407d4..6ca407d4 100644..100755
--- a/client/dbus_helpers.c
+++ b/client/dbus_helpers.c
diff --git a/client/dbus_helpers.h b/client/dbus_helpers.h
index 395808ac..395808ac 100644..100755
--- a/client/dbus_helpers.h
+++ b/client/dbus_helpers.h
diff --git a/client/input.c b/client/input.c
index 78319ff8..d9d2b7b1 100644..100755
--- a/client/input.c
+++ b/client/input.c
@@ -273,7 +273,9 @@ int __connmanctl_input_init(int argc, char *argv[])
__connmanctl_monitor_completions(NULL);
rl_callback_handler_remove();
+#if !defined TIZEN_EXT
rl_message("");
+#endif
}
dbus_connection_unref(connection);
diff --git a/client/input.h b/client/input.h
index c7256a41..c7256a41 100644..100755
--- a/client/input.h
+++ b/client/input.h
diff --git a/client/main.c b/client/main.c
index 6d3c57f9..6d3c57f9 100644..100755
--- a/client/main.c
+++ b/client/main.c
diff --git a/client/peers.c b/client/peers.c
index bf1aa0ea..bf1aa0ea 100644..100755
--- a/client/peers.c
+++ b/client/peers.c
diff --git a/client/peers.h b/client/peers.h
index fdf7ce76..fdf7ce76 100644..100755
--- a/client/peers.h
+++ b/client/peers.h
diff --git a/client/services.c b/client/services.c
index 0c18669b..0c18669b 100644..100755
--- a/client/services.c
+++ b/client/services.c
diff --git a/client/services.h b/client/services.h
index 9b555fe7..9b555fe7 100644..100755
--- a/client/services.h
+++ b/client/services.h
diff --git a/client/vpnconnections.c b/client/vpnconnections.c
index d7bcbfee..d7bcbfee 100644..100755
--- a/client/vpnconnections.c
+++ b/client/vpnconnections.c
diff --git a/client/vpnconnections.h b/client/vpnconnections.h
index a915c843..a915c843 100644..100755
--- a/client/vpnconnections.h
+++ b/client/vpnconnections.h
diff --git a/configure.ac b/configure.ac
index 4baa6852..01ecd950 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,6 +65,20 @@ AC_ARG_ENABLE(hh2serial-gps,
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}])
@@ -73,7 +87,7 @@ AC_ARG_ENABLE(openconnect,
[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
@@ -93,7 +107,7 @@ AC_ARG_ENABLE(openvpn,
[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
@@ -105,6 +119,30 @@ 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}])
@@ -113,7 +151,7 @@ AC_ARG_ENABLE(vpnc,
[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
@@ -133,7 +171,7 @@ AC_ARG_ENABLE(l2tp,
[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)
@@ -141,7 +179,7 @@ if (test "${enable_l2tp}" != "no"); then
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)
@@ -158,7 +196,7 @@ AC_ARG_ENABLE(pptp,
[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)
@@ -166,7 +204,7 @@ if (test "${enable_pptp}" != "no"); then
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)
@@ -182,9 +220,6 @@ AC_CHECK_LIB(resolv, ns_initparse, dummy=yes, [
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))
@@ -223,6 +258,11 @@ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.28, dummy=yes,
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)
@@ -257,14 +297,6 @@ if (test -n "${path_systemdunit}"); then
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}],
@@ -382,7 +414,7 @@ AM_CONDITIONAL(TOOLS, test "${enable_tools}" != "no")
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=""
@@ -414,7 +446,7 @@ fi
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],
@@ -429,8 +461,9 @@ fi
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)
diff --git a/connman.manifest b/connman.manifest
new file mode 100644
index 00000000..97e8c313
--- /dev/null
+++ b/connman.manifest
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
diff --git a/doc/advanced-configuration.txt b/doc/advanced-configuration.txt
index 12c2250e..12c2250e 100644..100755
--- a/doc/advanced-configuration.txt
+++ b/doc/advanced-configuration.txt
diff --git a/doc/agent-api.txt b/doc/agent-api.txt
index aa7271d4..aa7271d4 100644..100755
--- a/doc/agent-api.txt
+++ b/doc/agent-api.txt
diff --git a/doc/backtrace.txt b/doc/backtrace.txt
index ac8472cc..ac8472cc 100644..100755
--- a/doc/backtrace.txt
+++ b/doc/backtrace.txt
diff --git a/doc/behavior-api.txt b/doc/behavior-api.txt
index 5feea768..5feea768 100644..100755
--- a/doc/behavior-api.txt
+++ b/doc/behavior-api.txt
diff --git a/doc/clock-api.txt b/doc/clock-api.txt
index 6818f5a8..6818f5a8 100644..100755
--- a/doc/clock-api.txt
+++ b/doc/clock-api.txt
diff --git a/doc/config-format.txt b/doc/config-format.txt
index ed3123aa..ed3123aa 100644..100755
--- a/doc/config-format.txt
+++ b/doc/config-format.txt
diff --git a/doc/connman.conf.5.in b/doc/connman.conf.5.in
index 95b177f5..fdc8e9ec 100644
--- a/doc/connman.conf.5.in
+++ b/doc/connman.conf.5.in
@@ -138,7 +138,7 @@ be used by DHCP servers to identify specific clients without having to
rely on MAC address ranges, etc
.TP
.BI EnableOnlineCheck=true\ \fR|\fB\ false
-Enable or disable use of HTTP GET as 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
diff --git a/doc/counter-api.txt b/doc/counter-api.txt
index 32411d57..32411d57 100644..100755
--- a/doc/counter-api.txt
+++ b/doc/counter-api.txt
diff --git a/doc/ipconfig-api.txt b/doc/ipconfig-api.txt
index 080fdac5..080fdac5 100644..100755
--- a/doc/ipconfig-api.txt
+++ b/doc/ipconfig-api.txt
diff --git a/doc/manager-api.txt b/doc/manager-api.txt
index 31e137ca..31e137ca 100644..100755
--- a/doc/manager-api.txt
+++ b/doc/manager-api.txt
diff --git a/doc/overview-api.txt b/doc/overview-api.txt
index fd51d706..fd51d706 100644..100755
--- a/doc/overview-api.txt
+++ b/doc/overview-api.txt
diff --git a/doc/peer-api.txt b/doc/peer-api.txt
index cc094ff2..b871f4d5 100644..100755
--- a/doc/peer-api.txt
+++ b/doc/peer-api.txt
@@ -100,3 +100,4 @@ Properties string State [readonly] [experimental]
The TLV formated byte array representing the
WiFi Display Informations Elements.
+
diff --git a/doc/plugin-api.txt b/doc/plugin-api.txt
index ea5ec0a1..ea5ec0a1 100644..100755
--- a/doc/plugin-api.txt
+++ b/doc/plugin-api.txt
diff --git a/doc/service-api.txt b/doc/service-api.txt
index 6cdb0bb5..4fe4093a 100644..100755
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -122,6 +122,13 @@ Methods dict GetProperties() [deprecated]
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
@@ -193,6 +200,32 @@ Properties string State [readonly]
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
diff --git a/doc/session-api.txt b/doc/session-api.txt
index e8da5224..e8da5224 100644..100755
--- a/doc/session-api.txt
+++ b/doc/session-api.txt
diff --git a/doc/session-overview.txt b/doc/session-overview.txt
index 976c3518..976c3518 100644..100755
--- a/doc/session-overview.txt
+++ b/doc/session-overview.txt
diff --git a/doc/session-policy-format.txt b/doc/session-policy-format.txt
index babc2c10..babc2c10 100644..100755
--- a/doc/session-policy-format.txt
+++ b/doc/session-policy-format.txt
diff --git a/doc/technology-api.txt b/doc/technology-api.txt
index f22e9b29..fb6bd314 100644..100755
--- a/doc/technology-api.txt
+++ b/doc/technology-api.txt
@@ -45,6 +45,18 @@ Signals PropertyChanged(string name, variant value)
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
@@ -100,3 +112,8 @@ Properties boolean Powered [readwrite]
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.
diff --git a/doc/valgrind.suppressions b/doc/valgrind.suppressions
deleted file mode 100644
index c1c7bca1..00000000
--- a/doc/valgrind.suppressions
+++ /dev/null
@@ -1,235 +0,0 @@
-{
- <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
-}
diff --git a/doc/vpn-config-format.txt b/doc/vpn-config-format.txt
index 0bc62c08..cb0f16a8 100644
--- a/doc/vpn-config-format.txt
+++ b/doc/vpn-config-format.txt
@@ -207,6 +207,35 @@ PPTP VPN supports following options (see pptp(8) and pppd(8) for details)
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
=======
diff --git a/doc/vpn-connection-api.txt b/doc/vpn-connection-api.txt
index a814a388..a814a388 100644..100755
--- a/doc/vpn-connection-api.txt
+++ b/doc/vpn-connection-api.txt
diff --git a/doc/vpn-manager-api.txt b/doc/vpn-manager-api.txt
index 66c5beef..66c5beef 100644..100755
--- a/doc/vpn-manager-api.txt
+++ b/doc/vpn-manager-api.txt
diff --git a/doc/vpn-overview.txt b/doc/vpn-overview.txt
index 42b6e94a..42b6e94a 100644..100755
--- a/doc/vpn-overview.txt
+++ b/doc/vpn-overview.txt
diff --git a/gdbus/client.c b/gdbus/client.c
index a011e19c..9748ae25 100644..100755
--- a/gdbus/client.c
+++ b/gdbus/client.c
@@ -58,8 +58,10 @@ struct GDBusClient {
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;
@@ -729,6 +731,7 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
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,
@@ -815,6 +818,7 @@ gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
return TRUE;
}
+#endif
struct method_call_data {
GDBusReturnFunction function;
@@ -1095,8 +1099,10 @@ static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
parse_managed_objects(client, reply);
done:
+#if !defined TIZEN_EXT
if (client->ready)
client->ready(client, client->ready_data);
+#endif
dbus_message_unref(reply);
@@ -1367,6 +1373,7 @@ gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
return TRUE;
}
+#if !defined TIZEN_EXT
gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
GDBusClientFunction ready, void *user_data)
{
@@ -1378,6 +1385,7 @@ gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
return TRUE;
}
+#endif
gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
GDBusProxyFunction proxy_added,
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 69fbc107..70190b71 100644..100755
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -339,10 +339,12 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
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);
@@ -352,7 +354,9 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
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);
@@ -379,8 +383,10 @@ gboolean g_dbus_client_set_disconnect_watch(GDBusClient *client,
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,
diff --git a/gdbus/mainloop.c b/gdbus/mainloop.c
index b90a8447..edb384ef 100644..100755
--- a/gdbus/mainloop.c
+++ b/gdbus/mainloop.c
@@ -30,6 +30,8 @@
#include "gdbus.h"
+#define DISPATCH_TIMEOUT 0
+
#define info(fmt...)
#define error(fmt...)
#define debug(fmt...)
@@ -68,6 +70,8 @@ static gboolean message_dispatch(void *data)
{
DBusConnection *conn = data;
+ dbus_connection_ref(conn);
+
/* Dispatch messages */
while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
diff --git a/gdbus/object.c b/gdbus/object.c
index a2201016..c333d5b7 100644..100755
--- a/gdbus/object.c
+++ b/gdbus/object.c
@@ -1248,8 +1248,10 @@ static struct generic_data *object_path_ref(DBusConnection *connection,
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;
diff --git a/gdbus/polkit.c b/gdbus/polkit.c
index 9e95fa38..9e95fa38 100644..100755
--- a/gdbus/polkit.c
+++ b/gdbus/polkit.c
diff --git a/gdbus/watch.c b/gdbus/watch.c
index 447e4867..447e4867 100644..100755
--- a/gdbus/watch.c
+++ b/gdbus/watch.c
diff --git a/gdhcp/client.c b/gdhcp/client.c
index 3e67fcd5..5a455f08 100644..100755
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -50,9 +50,30 @@
#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,
@@ -156,6 +177,10 @@ struct _GDHCPClient {
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, ...)
@@ -480,6 +505,9 @@ static int send_request(GDHCPClient *dhcp_client)
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)
@@ -1516,6 +1544,21 @@ static gboolean request_timeout(gpointer user_data)
{
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);
@@ -1817,71 +1860,6 @@ static char *get_ip(uint32_t ip)
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;
@@ -2405,6 +2383,10 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
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);
@@ -2429,6 +2411,18 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
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,
@@ -2666,6 +2660,11 @@ static gboolean ipv4ll_announce_timeout(gpointer dhcp_data)
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);
@@ -2717,6 +2716,11 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
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) {
@@ -2803,13 +2807,32 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
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);
@@ -2852,7 +2875,11 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
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);
@@ -2861,7 +2888,11 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
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);
@@ -3002,8 +3033,19 @@ char *g_dhcp_client_get_server_address(GDHCPClient *dhcp_client)
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)
{
@@ -3230,6 +3272,9 @@ void g_dhcp_client_unref(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,
@@ -3265,3 +3310,19 @@ GSList *g_dhcpv6_copy_prefixes(GSList *prefixes)
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
diff --git a/gdhcp/common.c b/gdhcp/common.c
index 6f816718..b8c5091a 100644..100755
--- a/gdhcp/common.c
+++ b/gdhcp/common.c
@@ -182,6 +182,71 @@ int dhcp_end_option(uint8_t *optionptr)
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)
{
diff --git a/gdhcp/common.h b/gdhcp/common.h
index 75abc183..7da13135 100644..100755
--- a/gdhcp/common.h
+++ b/gdhcp/common.h
@@ -178,6 +178,7 @@ struct in6_pktinfo {
};
#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);
diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h
index eaf6a748..f51a8b05 100644..100755
--- a/gdhcp/gdhcp.h
+++ b/gdhcp/gdhcp.h
@@ -153,6 +153,11 @@ GDHCPClientError g_dhcp_client_set_send(GDHCPClient *client,
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,
@@ -211,6 +216,9 @@ struct _GDHCPServer;
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);
@@ -231,10 +239,16 @@ void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_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
diff --git a/gdhcp/ipv4ll.c b/gdhcp/ipv4ll.c
index d9001987..d9001987 100644..100755
--- a/gdhcp/ipv4ll.c
+++ b/gdhcp/ipv4ll.c
diff --git a/gdhcp/ipv4ll.h b/gdhcp/ipv4ll.h
index bee8138a..bee8138a 100644..100755
--- a/gdhcp/ipv4ll.h
+++ b/gdhcp/ipv4ll.h
diff --git a/gdhcp/server.c b/gdhcp/server.c
index f7795f7e..44ce771a 100644..100755
--- a/gdhcp/server.c
+++ b/gdhcp/server.c
@@ -66,6 +66,7 @@ struct _GDHCPServer {
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;
};
@@ -399,6 +400,7 @@ GDHCPServer *g_dhcp_server_new(GDHCPType type,
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;
@@ -650,9 +652,12 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
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;
@@ -698,8 +703,21 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
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;
}
@@ -828,6 +846,15 @@ void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server,
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)
diff --git a/gsupplicant/dbus.c b/gsupplicant/dbus.c
index 2957979a..2957979a 100644..100755
--- a/gsupplicant/dbus.c
+++ b/gsupplicant/dbus.c
diff --git a/gsupplicant/dbus.h b/gsupplicant/dbus.h
index 3a904069..3a904069 100644..100755
--- a/gsupplicant/dbus.h
+++ b/gsupplicant/dbus.h
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index db61595b..88606262 100644..100755
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -56,8 +56,13 @@ extern "C" {
#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)
@@ -97,6 +102,10 @@ typedef enum {
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 {
@@ -129,6 +138,12 @@ 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;
@@ -155,10 +170,23 @@ struct _GSupplicantSSID {
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;
@@ -268,6 +296,9 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
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);
@@ -337,6 +368,24 @@ GSupplicantInterface *g_supplicant_peer_get_group_interface(GSupplicantPeer *pee
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);
@@ -349,9 +398,18 @@ struct _GSupplicantCallbacks {
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,
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 4f790122..5e9f5095 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -191,6 +191,9 @@ struct _GSupplicantInterface {
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 {
@@ -215,6 +218,13 @@ 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;
};
@@ -234,6 +244,15 @@ struct _GSupplicantNetwork {
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 {
@@ -361,6 +380,12 @@ static const char *security2string(GSupplicantSecurity security)
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;
@@ -525,6 +550,7 @@ static void callback_interface_removed(GSupplicantInterface *interface)
callbacks_pointer->interface_removed(interface);
}
+#if !defined TIZEN_EXT
static void callback_p2p_support(GSupplicantInterface *interface)
{
SUPPLICANT_DBG("");
@@ -535,6 +561,7 @@ static void callback_p2p_support(GSupplicantInterface *interface)
if (callbacks_pointer && callbacks_pointer->p2p_support)
callbacks_pointer->p2p_support(interface);
}
+#endif
static void callback_scan_started(GSupplicantInterface *interface)
{
@@ -591,6 +618,30 @@ static void callback_network_removed(GSupplicantNetwork *network)
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)
{
@@ -728,6 +779,9 @@ static void remove_interface(gpointer data)
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);
@@ -748,6 +802,15 @@ static void remove_network(gpointer data)
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);
}
@@ -756,6 +819,9 @@ static void remove_bss(gpointer data)
struct g_supplicant_bss *bss = data;
g_free(bss->path);
+#if defined TIZEN_EXT
+ g_free(bss->wifi_vsie);
+#endif
g_free(bss);
}
@@ -1101,6 +1167,9 @@ unsigned int g_supplicant_interface_get_max_scan_ssids(
if (!interface)
return 0;
+ if (interface->max_scan_ssids == 0)
+ return WPAS_MAX_SCAN_SSIDS;
+
return interface->max_scan_ssids;
}
@@ -1301,6 +1370,48 @@ const char *g_supplicant_peer_get_name(GSupplicantPeer *peer)
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)
{
@@ -1383,16 +1494,105 @@ bool g_supplicant_peer_has_requested_connection(GSupplicantPeer *peer)
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);
@@ -1406,7 +1606,14 @@ static void merge_network(GSupplicantNetwork *network)
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");
@@ -1415,11 +1622,41 @@ static void merge_network(GSupplicantNetwork *network)
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);
@@ -1609,6 +1846,23 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
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,
@@ -1793,6 +2047,9 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
{
struct g_supplicant_bss *bss = user_data;
const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
+#if defined TIZEN_EXT
+ const unsigned char WIFI_OUI[] = {0x00, 0x16, 0x32};
+#endif
unsigned char *ie, *ie_end;
DBusMessageIter array;
unsigned int value;
@@ -1808,6 +2065,9 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
#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);
@@ -1820,7 +2080,19 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
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;
@@ -1866,23 +2138,51 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
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
@@ -1984,6 +2284,12 @@ static void bss_property(const char *key, DBusMessageIter *iter,
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
@@ -2269,8 +2575,10 @@ static void interface_property(const char *key, DBusMessageIter *iter,
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;
@@ -2347,6 +2655,9 @@ static void interface_property(const char *key, DBusMessageIter *iter,
} 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,
@@ -2403,15 +2714,30 @@ static void scan_bss_data(const char *key, DBusMessageIter *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)
@@ -2740,7 +3066,9 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
return;
supplicant_dbus_property_foreach(iter, bss_property, bss);
-
+#if defined TIZEN_EXT
+ network->frequency = bss->frequency;
+#endif
old_security = network->security;
bss_compute_security(bss);
@@ -2781,12 +3109,27 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
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
@@ -2794,7 +3137,14 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
*/
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 {
@@ -2896,7 +3246,7 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
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;
@@ -2909,6 +3259,79 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
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] = {};
@@ -3473,6 +3896,12 @@ static struct {
{ 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 },
@@ -3789,7 +4218,9 @@ static void interface_create_property(const char *key, DBusMessageIter *iter,
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);
@@ -3908,7 +4339,9 @@ static void interface_get_result(const char *error,
if (data->callback) {
data->callback(0, interface, data->user_data);
+#if !defined TIZEN_EXT
callback_p2p_support(interface);
+#endif
}
interface_create_data_free(data);
@@ -4204,7 +4637,11 @@ static void interface_scan_params(DBusMessageIter *iter, void *user_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);
@@ -4236,8 +4673,14 @@ static int interface_ready_to_scan(GSupplicantInterface *interface)
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:
@@ -4266,8 +4709,13 @@ int g_supplicant_interface_scan(GSupplicantInterface *interface,
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;
@@ -4322,7 +4770,11 @@ static void interface_select_network_result(const char *error,
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);
}
@@ -4340,9 +4792,15 @@ static void interface_select_network_params(DBusMessageIter *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,
@@ -4366,11 +4824,23 @@ 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;
@@ -4536,8 +5006,10 @@ static void add_network_security_tls(DBusMessageIter *dict,
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",
@@ -4546,9 +5018,11 @@ static void add_network_security_tls(DBusMessageIter *dict,
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);
@@ -4580,8 +5054,10 @@ static void add_network_security_peap(DBusMessageIter *dict,
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,
@@ -4591,9 +5067,11 @@ static void add_network_security_peap(DBusMessageIter *dict,
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
}
@@ -4619,19 +5097,46 @@ static void add_network_security_peap(DBusMessageIter *dict,
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;
@@ -4640,9 +5145,16 @@ static void add_network_security_eap(DBusMessageIter *dict,
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,
@@ -4791,6 +5303,20 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
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",
@@ -4846,6 +5372,28 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
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);
}
@@ -4895,6 +5443,12 @@ static void interface_add_wps_params(DBusMessageIter *iter, void *user_data)
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);
}
@@ -4911,7 +5465,17 @@ static void wps_start(const char *error, DBusMessageIter *iter, void *user_data)
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,
@@ -4928,6 +5492,136 @@ static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
}
+#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,
@@ -5010,14 +5704,20 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
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);
@@ -5092,6 +5792,16 @@ static int network_remove(struct interface_data *data)
SUPPLICANT_DBG("");
+#if defined TIZEN_EXT
+ GSupplicantInterface *intf = NULL;
+ /*
+ * Check if 'interface' is valid
+ */
+ intf = g_hash_table_lookup(interface_table, interface->path);
+ if (intf == NULL)
+ return -EINVAL;
+#endif
+
return supplicant_dbus_method_call(interface->path,
SUPPLICANT_INTERFACE ".Interface", "RemoveNetwork",
network_remove_params, network_remove_result, data,
@@ -5158,7 +5868,17 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
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;
@@ -5633,6 +6353,28 @@ int g_supplicant_set_widi_ies(GSupplicantP2PServiceParams *p2p_service_params,
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 ","
@@ -5650,12 +6392,14 @@ static const char *g_supplicant_rule4 = "type=signal,"
"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)
{
@@ -5712,9 +6456,16 @@ int g_supplicant_register(const GSupplicantCallbacks *callbacks)
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,
@@ -5756,9 +6507,11 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks)
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);
diff --git a/gweb/giognutls.c b/gweb/giognutls.c
index 09dc9e72..31cf9020 100644..100755
--- a/gweb/giognutls.c
+++ b/gweb/giognutls.c
@@ -458,7 +458,6 @@ GIOChannel *g_io_channel_gnutls_new(int fd)
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);
diff --git a/gweb/giognutls.h b/gweb/giognutls.h
index ea0df8ff..ea0df8ff 100644..100755
--- a/gweb/giognutls.h
+++ b/gweb/giognutls.h
diff --git a/gweb/gionotls.c b/gweb/gionotls.c
index 29988954..29988954 100644..100755
--- a/gweb/gionotls.c
+++ b/gweb/gionotls.c
diff --git a/gweb/gresolv.c b/gweb/gresolv.c
index 8a51a9f6..cf16a48c 100644..100755
--- a/gweb/gresolv.c
+++ b/gweb/gresolv.c
@@ -946,10 +946,12 @@ bool g_resolv_add_nameserver(GResolv *resolv, const char *address,
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);
@@ -1051,6 +1053,8 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
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);
@@ -1058,6 +1062,8 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
}
}
+ debug(resolv, "");
+
if (resolv->result_family != AF_INET) {
if (add_query(lookup, hostname, ns_t_aaaa)) {
if (resolv->result_family != AF_INET6) {
@@ -1071,6 +1077,8 @@ guint g_resolv_lookup_hostname(GResolv *resolv, const char *hostname,
}
}
+ debug(resolv, "");
+
g_queue_push_tail(resolv->lookup_queue, lookup);
debug(resolv, "lookup %p id %d", lookup, lookup->id);
diff --git a/gweb/gresolv.h b/gweb/gresolv.h
index fac14f54..fac14f54 100644..100755
--- a/gweb/gresolv.h
+++ b/gweb/gresolv.h
diff --git a/gweb/gweb.c b/gweb/gweb.c
index 393afe0a..7037cd94 100644..100755
--- a/gweb/gweb.c
+++ b/gweb/gweb.c
@@ -809,6 +809,10 @@ static void handle_multi_line(struct web_session *session)
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) {
@@ -1257,6 +1261,16 @@ static void resolv_result(GResolvResultStatus status,
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]);
diff --git a/gweb/gweb.h b/gweb/gweb.h
index 6c28542a..6c28542a 100644..100755
--- a/gweb/gweb.h
+++ b/gweb/gweb.h
diff --git a/include/agent.h b/include/agent.h
index 6961f7a1..6961f7a1 100644..100755
--- a/include/agent.h
+++ b/include/agent.h
diff --git a/include/backtrace.h b/include/backtrace.h
deleted file mode 100644
index 12a202d7..00000000
--- a/include/backtrace.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *
- * 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 */
diff --git a/include/dbus.h b/include/dbus.h
index 26f94d63..3087fe40 100644..100755
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -180,6 +180,10 @@ int connman_dbus_get_connection_unix_user(DBusConnection *connection,
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);
diff --git a/include/device.h b/include/device.h
index 9ac800a2..36b2f550 100644..100755
--- a/include/device.h
+++ b/include/device.h
@@ -126,6 +126,11 @@ struct connman_device_driver {
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);
diff --git a/include/inet.h b/include/inet.h
index 6482934a..07427300 100644..100755
--- a/include/inet.h
+++ b/include/inet.h
@@ -39,6 +39,10 @@ char *connman_inet_ifname(int index);
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);
diff --git a/include/inotify.h b/include/inotify.h
index 4bc63303..4bc63303 100644..100755
--- a/include/inotify.h
+++ b/include/inotify.h
diff --git a/include/ipaddress.h b/include/ipaddress.h
index 3655ca86..3655ca86 100644..100755
--- a/include/ipaddress.h
+++ b/include/ipaddress.h
diff --git a/include/ipconfig.h b/include/ipconfig.h
index 68ef40b6..68ef40b6 100644..100755
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
diff --git a/include/log.h b/include/log.h
index 8b00e9dc..7687ed0b 100644..100755
--- a/include/log.h
+++ b/include/log.h
@@ -52,7 +52,11 @@ void connman_debug(const char *format, ...)
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;
diff --git a/include/machine.h b/include/machine.h
index c8d8735e..c8d8735e 100644..100755
--- a/include/machine.h
+++ b/include/machine.h
diff --git a/include/network.h b/include/network.h
index 4fc20c1c..4be5fbf0 100644..100755
--- a/include/network.h
+++ b/include/network.h
@@ -55,7 +55,11 @@ enum connman_network_error {
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
@@ -90,6 +94,9 @@ void connman_network_set_group(struct connman_network *network,
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);
@@ -117,6 +124,41 @@ int connman_network_set_nameservers(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,
@@ -157,6 +199,9 @@ struct connman_network_driver {
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);
diff --git a/include/notifier.h b/include/notifier.h
index 50b5fb4c..50b5fb4c 100644..100755
--- a/include/notifier.h
+++ b/include/notifier.h
diff --git a/include/option.h b/include/option.h
index 5e97ed4c..5e97ed4c 100644..100755
--- a/include/option.h
+++ b/include/option.h
diff --git a/include/peer.h b/include/peer.h
index 80663932..80663932 100644..100755
--- a/include/peer.h
+++ b/include/peer.h
diff --git a/include/plugin.h b/include/plugin.h
index 8d2bb08e..8d2bb08e 100644..100755
--- a/include/plugin.h
+++ b/include/plugin.h
diff --git a/include/provider.h b/include/provider.h
index d28651ad..d28651ad 100644..100755
--- a/include/provider.h
+++ b/include/provider.h
diff --git a/include/provision.h b/include/provision.h
index 3eb80a86..3eb80a86 100644..100755
--- a/include/provision.h
+++ b/include/provision.h
diff --git a/include/proxy.h b/include/proxy.h
index 7842f65f..7842f65f 100644..100755
--- a/include/proxy.h
+++ b/include/proxy.h
diff --git a/include/resolver.h b/include/resolver.h
index 70a02ade..70a02ade 100644..100755
--- a/include/resolver.h
+++ b/include/resolver.h
diff --git a/include/rtnl.h b/include/rtnl.h
index aa70f4d8..aa70f4d8 100644..100755
--- a/include/rtnl.h
+++ b/include/rtnl.h
diff --git a/include/service.h b/include/service.h
index 958e7fd1..30550233 100644..100755
--- a/include/service.h
+++ b/include/service.h
@@ -24,6 +24,10 @@
#include <stdbool.h>
+#if defined TIZEN_EXT
+#include <glib.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -137,6 +141,43 @@ void connman_service_create_ip4config(struct connman_service *service,
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
diff --git a/include/session.h b/include/session.h
index 5106e886..5106e886 100644..100755
--- a/include/session.h
+++ b/include/session.h
diff --git a/include/setting.h b/include/setting.h
index a8820217..a8820217 100644..100755
--- a/include/setting.h
+++ b/include/setting.h
diff --git a/include/storage.h b/include/storage.h
index 4c23a14e..4c23a14e 100644..100755
--- a/include/storage.h
+++ b/include/storage.h
diff --git a/include/task.h b/include/task.h
index 9977d634..9977d634 100644..100755
--- a/include/task.h
+++ b/include/task.h
diff --git a/include/technology.h b/include/technology.h
index 97db6607..55bb3dd5 100644..100755
--- a/include/technology.h
+++ b/include/technology.h
@@ -36,6 +36,10 @@ extern "C" {
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);
diff --git a/include/timeserver.h b/include/timeserver.h
index 48ea1945..48ea1945 100644..100755
--- a/include/timeserver.h
+++ b/include/timeserver.h
diff --git a/include/utsname.h b/include/utsname.h
index b8165f68..b8165f68 100644..100755
--- a/include/utsname.h
+++ b/include/utsname.h
diff --git a/include/version.h.in b/include/version.h.in
index d3d6dd37..d3d6dd37 100644..100755
--- a/include/version.h.in
+++ b/include/version.h.in
diff --git a/include/vpn-dbus.h b/include/vpn-dbus.h
index 01780cbd..01780cbd 100644..100755
--- a/include/vpn-dbus.h
+++ b/include/vpn-dbus.h
diff --git a/packaging/connman.spec b/packaging/connman.spec
new file mode 100755
index 00000000..0554f9a7
--- /dev/null
+++ b/packaging/connman.spec
@@ -0,0 +1,343 @@
+%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
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index f759a902..f89edfa0 100644..100755
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -192,8 +192,14 @@ static bool pan_connect(struct bluetooth_pan *pan,
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;
}
@@ -211,6 +217,18 @@ static void pan_connect_cb(DBusMessage *message, void *user_data)
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);
@@ -262,6 +280,9 @@ static int bluetooth_pan_connect(struct connman_network *network)
g_strdup(path), g_free))
return -EIO;
+#if defined TIZEN_EXT
+ if (pan->network)
+#endif
connman_network_set_associating(pan->network, true);
return -EINPROGRESS;
@@ -286,6 +307,9 @@ static void pan_disconnect_cb(DBusMessage *message, void *user_data)
DBG("network %p", pan->network);
+#if defined TIZEN_EXT
+ if (pan->network)
+#endif
connman_network_set_connected(pan->network, false);
}
@@ -299,6 +323,11 @@ static int bluetooth_pan_disconnect(struct connman_network *network)
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",
@@ -524,7 +553,10 @@ static void device_enable_cb(const DBusError *error, void *user_data)
goto out;
}
+#if !defined TIZEN_EXT
enable_device(device, path);
+#endif
+
out:
g_free(path);
}
@@ -591,7 +623,9 @@ static void device_disable_cb(const DBusError *error, void *user_data)
goto out;
}
+#if !defined TIZEN_EXT
disable_device(device, path);
+#endif
out:
g_free(path);
@@ -883,7 +917,7 @@ static void bluetooth_tech_remove(struct connman_technology *technology)
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;
diff --git a/plugins/connman-nmcompat.conf b/plugins/connman-nmcompat.conf
index 5887a345..a051d927 100644..100755
--- a/plugins/connman-nmcompat.conf
+++ b/plugins/connman-nmcompat.conf
@@ -5,6 +5,10 @@
<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>
diff --git a/plugins/dundee.c b/plugins/dundee.c
index b5420acf..b5420acf 100644..100755
--- a/plugins/dundee.c
+++ b/plugins/dundee.c
diff --git a/plugins/ethernet.c b/plugins/ethernet.c
index 9a4d7413..9a4d7413 100644..100755
--- a/plugins/ethernet.c
+++ b/plugins/ethernet.c
diff --git a/plugins/gadget.c b/plugins/gadget.c
index 94f66487..cce51e26 100644..100755
--- a/plugins/gadget.c
+++ b/plugins/gadget.c
@@ -25,6 +25,8 @@
#include <errno.h>
#include <net/if.h>
+#include <stdio.h>
+#include <string.h>
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
@@ -226,6 +228,71 @@ static struct connman_device_driver gadget_dev_driver = {
};
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)
@@ -246,6 +313,8 @@ static void gadget_tech_remove_interface(struct connman_technology *technology,
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,
@@ -270,6 +339,8 @@ static void gadget_tech_enable_tethering(struct connman_technology *technology,
connman_inet_ifup(index);
connman_inet_add_to_bridge(index, bridge);
+
+ add_station(index);
}
}
@@ -283,6 +354,8 @@ static void gadget_tech_disable_tethering(struct connman_technology *technology,
connman_inet_remove_from_bridge(index, bridge);
+ remove_station(index);
+
connman_inet_ifdown(index);
connman_technology_tethering_notify(technology, false);
@@ -305,14 +378,28 @@ static int gadget_tech_set_tethering(struct connman_technology *technology,
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 = {
diff --git a/plugins/hh2serial-gps.c b/plugins/hh2serial-gps.c
index 99394e1c..99394e1c 100644..100755
--- a/plugins/hh2serial-gps.c
+++ b/plugins/hh2serial-gps.c
diff --git a/plugins/iospm.c b/plugins/iospm.c
index fcb4cea1..fcb4cea1 100644..100755
--- a/plugins/iospm.c
+++ b/plugins/iospm.c
diff --git a/plugins/loopback.c b/plugins/loopback.c
index e113887d..44100c64 100644..100755
--- a/plugins/loopback.c
+++ b/plugins/loopback.c
@@ -23,6 +23,8 @@
#include <config.h>
#endif
+#include <stdio.h>
+
#include <errno.h>
#include <unistd.h>
#include <limits.h>
@@ -34,6 +36,8 @@
#include <net/if.h>
#include <glib.h>
+#include <glib/gprintf.h>
+
#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
@@ -62,16 +66,47 @@ static int setup_hostname(void)
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));
diff --git a/plugins/mcc.h b/plugins/mcc.h
index 0e0407c9..0e0407c9 100644..100755
--- a/plugins/mcc.h
+++ b/plugins/mcc.h
diff --git a/plugins/neard.c b/plugins/neard.c
index 69586df6..69586df6 100644..100755
--- a/plugins/neard.c
+++ b/plugins/neard.c
diff --git a/plugins/nmcompat.c b/plugins/nmcompat.c
index 883ce9bd..883ce9bd 100644..100755
--- a/plugins/nmcompat.c
+++ b/plugins/nmcompat.c
diff --git a/plugins/ofono.c b/plugins/ofono.c
index 78f8f196..78f8f196 100644..100755
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
diff --git a/plugins/pacrunner.c b/plugins/pacrunner.c
index d2464a5e..d2464a5e 100644..100755
--- a/plugins/pacrunner.c
+++ b/plugins/pacrunner.c
diff --git a/plugins/polkit.c b/plugins/polkit.c
index ae38364a..ae38364a 100644..100755
--- a/plugins/polkit.c
+++ b/plugins/polkit.c
diff --git a/plugins/polkit.policy b/plugins/polkit.policy
index 0de152ce..0de152ce 100644..100755
--- a/plugins/polkit.policy
+++ b/plugins/polkit.policy
diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c
index f003c0e1..f003c0e1 100644..100755
--- a/plugins/session_policy_local.c
+++ b/plugins/session_policy_local.c
diff --git a/plugins/telephony.c b/plugins/telephony.c
new file mode 100755
index 00000000..2b4c5a4a
--- /dev/null
+++ b/plugins/telephony.c
@@ -0,0 +1,1934 @@
+/*
+ *
+ * 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)
diff --git a/plugins/tist.c b/plugins/tist.c
index ad5ef79e..ad5ef79e 100644..100755
--- a/plugins/tist.c
+++ b/plugins/tist.c
diff --git a/plugins/vpn.c b/plugins/vpn.c
index c2a332ba..d3d75b81 100644..100755
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -1726,7 +1726,7 @@ static gboolean property_changed(DBusConnection *conn,
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
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 34c16dfd..8bc6307b 100644..100755
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -152,10 +152,27 @@ struct wifi_data {
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;
@@ -163,10 +180,128 @@ static GList *p2p_iface_list = 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;
@@ -545,6 +680,11 @@ static void register_peer_service_cb(int result,
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)
@@ -1069,6 +1209,15 @@ static int get_hidden_connections(GSupplicantScanParams *scan_data)
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);
@@ -1208,8 +1357,11 @@ static int throw_wifi_scan(struct connman_device *device,
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);
@@ -1238,6 +1390,45 @@ static void hidden_free(struct hidden_params *hidden)
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(&notifier);
+ 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)
{
@@ -1283,14 +1474,31 @@ static void scan_callback(int result, GSupplicantInterface *interface,
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);
/*
@@ -1302,6 +1510,23 @@ static void scan_callback(int result, GSupplicantInterface *interface,
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(&notifier);
+ is_wifi_notifier_registered = true;
+ }
+#endif
}
static void scan_callback_hidden(int result,
@@ -1358,7 +1583,11 @@ static gboolean autoscan_timeout(gpointer data)
} 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);
@@ -1552,6 +1781,15 @@ static int wifi_disable(struct connman_device *device)
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(&notifier);
+ is_wifi_notifier_registered = false;
+ }
+#endif
+
ret = g_supplicant_interface_remove(wifi->interface, NULL, NULL);
if (ret < 0)
return ret;
@@ -1779,6 +2017,137 @@ static int p2p_find(struct connman_device *device)
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.
@@ -1893,9 +2262,18 @@ static int wifi_scan(enum connman_service_type type,
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);
@@ -1949,6 +2327,9 @@ static struct connman_device_driver wifi_ng_driver = {
.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)
@@ -1988,15 +2369,42 @@ static void network_remove(struct connman_network *network)
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);
@@ -2022,6 +2430,12 @@ static GSupplicantSecurity network_security(const char *security)
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;
}
@@ -2039,7 +2453,6 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
ssid->security = network_security(security);
ssid->passphrase = connman_network_get_string(network,
"WiFi.Passphrase");
-
ssid->eap = connman_network_get_string(network, "WiFi.EAP");
/*
@@ -2083,6 +2496,13 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
ssid->use_wps = connman_network_get_bool(network, "WiFi.UseWPS");
ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
+#if defined TIZEN_EXT
+ ssid->bssid = connman_network_get_bssid(network);
+#endif
+#if defined TIZEN_EXT
+ ssid->freq = connman_network_get_frequency(network);
+#endif
+
if (connman_setting_get_bool("BackgroundScanning"))
ssid->bgscan = BGSCAN_DEFAULT;
}
@@ -2117,6 +2537,9 @@ static int network_connect(struct connman_network *network)
} 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);
@@ -2128,7 +2551,30 @@ static int network_connect(struct connman_network *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);
@@ -2159,6 +2605,9 @@ static int network_disconnect(struct connman_network *network)
struct connman_device *device = connman_network_get_device(network);
struct wifi_data *wifi;
int err;
+#if defined TIZEN_EXT
+ struct connman_service *service;
+#endif
DBG("network %p", network);
@@ -2166,6 +2615,29 @@ static int network_disconnect(struct connman_network *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)
@@ -2173,8 +2645,14 @@ static int network_disconnect(struct connman_network *network)
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;
@@ -2297,16 +2775,49 @@ static bool handle_wps_completion(GSupplicantInterface *interface,
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;
@@ -2329,6 +2840,26 @@ static bool handle_4way_handshake_failure(GSupplicantInterface *interface,
struct connman_network *network,
struct wifi_data *wifi)
{
+#if defined TIZEN_EXT
+ const char *security;
+ struct connman_service *service;
+
+ if (wifi->connected)
+ return false;
+
+ security = connman_network_get_string(network, "WiFi.Security");
+
+ if (security && g_str_equal(security, "ieee8021x") == true &&
+ wifi->state == G_SUPPLICANT_STATE_ASSOCIATED) {
+ wifi->retries = 0;
+ connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY);
+
+ return false;
+ }
+
+ if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
+ return false;
+#else
struct connman_service *service;
if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
@@ -2336,6 +2867,7 @@ static bool handle_4way_handshake_failure(GSupplicantInterface *interface,
if (wifi->connected)
return false;
+#endif
service = connman_service_lookup_from_network(network);
if (!service)
@@ -2354,6 +2886,47 @@ static bool handle_4way_handshake_failure(GSupplicantInterface *interface,
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;
@@ -2401,7 +2974,11 @@ static void interface_state(GSupplicantInterface *interface)
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);
@@ -2409,8 +2986,25 @@ static void interface_state(GSupplicantInterface *interface)
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;
@@ -2461,6 +3055,46 @@ static void interface_state(GSupplicantInterface *interface)
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;
@@ -2470,6 +3104,10 @@ static void interface_state(GSupplicantInterface *interface)
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);
@@ -2606,7 +3244,38 @@ static void scan_started(GSupplicantInterface *interface)
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)
@@ -2644,9 +3313,11 @@ static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network)
unsigned char strength;
strength = 120 + g_supplicant_network_get_signal(supplicant_network);
+
+#if !defined TIZEN_EXT
if (strength > 100)
strength = 100;
-
+#endif
return strength;
}
@@ -2663,6 +3334,11 @@ static void network_added(GSupplicantNetwork *supplicant_network)
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);
@@ -2687,6 +3363,9 @@ static void network_added(GSupplicantNetwork *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) {
@@ -2710,6 +3389,11 @@ static void network_added(GSupplicantNetwork *supplicant_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));
@@ -2719,21 +3403,53 @@ static void network_added(GSupplicantNetwork *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,
@@ -2768,6 +3484,18 @@ static void network_removed(GSupplicantNetwork *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);
@@ -2781,6 +3509,13 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
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);
@@ -2800,6 +3535,18 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
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)
@@ -2870,6 +3617,17 @@ static void apply_peer_services(GSupplicantPeer *peer,
}
}
+static void add_station(const char *mac)
+{
+ connman_technology_tethering_add_station(CONNMAN_SERVICE_TYPE_WIFI,
+ mac);
+}
+
+static void remove_station(const char *mac)
+{
+ connman_technology_tethering_remove_station(mac);
+}
+
static void peer_found(GSupplicantPeer *peer)
{
GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
@@ -2877,7 +3635,10 @@ static void peer_found(GSupplicantPeer *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);
@@ -2934,6 +3695,11 @@ static void peer_changed(GSupplicantPeer *peer, GSupplicantPeerState state)
struct connman_peer *connman_peer;
const char *identifier;
+#if defined TIZEN_EXT
+ if (!wifi)
+ return;
+#endif
+
identifier = g_supplicant_peer_get_identifier(peer);
DBG("ident: %s", identifier);
@@ -3023,6 +3789,11 @@ static void peer_request(GSupplicantPeer *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);
@@ -3034,6 +3805,100 @@ static void peer_request(GSupplicantPeer *peer)
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"))
@@ -3073,10 +3938,17 @@ static const GSupplicantCallbacks callbacks = {
.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,
@@ -3095,7 +3967,8 @@ static void tech_remove(struct connman_technology *technology)
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;
@@ -3193,7 +4066,7 @@ static void sta_remove_callback(int result,
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);
@@ -3239,10 +4112,11 @@ static int enable_wifi_tethering(struct connman_technology *technology,
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;
@@ -3276,6 +4150,8 @@ static int enable_wifi_tethering(struct connman_technology *technology,
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);
diff --git a/resources/usr/share/dbus-1/system-services/net.connman.service b/resources/usr/share/dbus-1/system-services/net.connman.service
new file mode 100644
index 00000000..990eb66b
--- /dev/null
+++ b/resources/usr/share/dbus-1/system-services/net.connman.service
@@ -0,0 +1,6 @@
+[D-BUS Service]
+Name=net.connman
+Exec=/bin/false
+User=network_fw
+Group=network_fw
+SystemdService=connman.service
diff --git a/resources/var/lib/connman/settings b/resources/var/lib/connman/settings
new file mode 100644
index 00000000..ba476b5d
--- /dev/null
+++ b/resources/var/lib/connman/settings
@@ -0,0 +1,15 @@
+
+[global]
+OfflineMode=false
+
+[WiFi]
+Enable=false
+
+[Bluetooth]
+Enable=true
+
+[Wired]
+Enable=true
+
+[Cellular]
+Enable=true
diff --git a/scripts/500.connman_upgrade.sh b/scripts/500.connman_upgrade.sh
new file mode 100644
index 00000000..a21336e2
--- /dev/null
+++ b/scripts/500.connman_upgrade.sh
@@ -0,0 +1,9 @@
+#!/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
diff --git a/scripts/connman.in b/scripts/connman.in
index 0b9f63c5..f3d438f3 100644..100755
--- a/scripts/connman.in
+++ b/scripts/connman.in
@@ -1,6 +1,6 @@
#!/bin/sh
-DAEMON=@sbindir@/connmand
+DAEMON=@bindir@/connmand
DESC="Connection Manager"
. /lib/lsb/init-functions
diff --git a/scripts/connman_resolvconf.conf.in b/scripts/connman_resolvconf.conf.in
deleted file mode 100644
index 2d61dfe1..00000000
--- a/scripts/connman_resolvconf.conf.in
+++ /dev/null
@@ -1,2 +0,0 @@
-d @runstatedir@/connman - - - -
-L+ /etc/resolv.conf - - - - @runstatedir@/connman/resolv.conf
diff --git a/scripts/ipsec-script.c b/scripts/ipsec-script.c
new file mode 100755
index 00000000..6ba0d292
--- /dev/null
+++ b/scripts/ipsec-script.c
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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;
+}
diff --git a/scripts/libppp-plugin.c b/scripts/libppp-plugin.c
index 0dd8b471..0dd8b471 100644..100755
--- a/scripts/libppp-plugin.c
+++ b/scripts/libppp-plugin.c
diff --git a/scripts/openconnect-script.c b/scripts/openconnect-script.c
index 5e04144f..5e04144f 100644..100755
--- a/scripts/openconnect-script.c
+++ b/scripts/openconnect-script.c
diff --git a/scripts/openvpn-script.c b/scripts/openvpn-script.c
index 6ba0d292..6ba0d292 100644..100755
--- a/scripts/openvpn-script.c
+++ b/scripts/openvpn-script.c
diff --git a/src/6to4.c b/src/6to4.c
index 71a28827..71a28827 100644..100755
--- a/src/6to4.c
+++ b/src/6to4.c
diff --git a/src/agent-connman.c b/src/agent-connman.c
index fca7cc1f..e4850a8f 100644..100755
--- a/src/agent-connman.c
+++ b/src/agent-connman.c
@@ -253,6 +253,9 @@ static void request_input_append_passphrase(DBusMessageIter *iter,
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:
@@ -386,6 +389,9 @@ static void previous_passphrase_handler(DBusMessageIter *iter,
data.type = "wep";
break;
case CONNMAN_SERVICE_SECURITY_PSK:
+#if defined TIZEN_EXT
+ case CONNMAN_SERVICE_SECURITY_RSN:
+#endif
data.type = "psk";
break;
/*
diff --git a/src/agent.c b/src/agent.c
index 8f7b19ba..8f7b19ba 100644..100755
--- a/src/agent.c
+++ b/src/agent.c
diff --git a/src/backtrace.c b/src/backtrace.c
deleted file mode 100644
index 6a66c0ac..00000000
--- a/src/backtrace.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *
- * 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]);
-}
diff --git a/src/bridge.c b/src/bridge.c
index cd2d9cee..cd2d9cee 100644..100755
--- a/src/bridge.c
+++ b/src/bridge.c
diff --git a/src/clock.c b/src/clock.c
index 0fde2c34..f04cf175 100644..100755
--- a/src/clock.c
+++ b/src/clock.c
@@ -241,6 +241,11 @@ static DBusMessage *set_property(DBusConnection *conn,
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;
@@ -261,6 +266,7 @@ static DBusMessage *set_property(DBusConnection *conn,
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;
diff --git a/src/config.c b/src/config.c
index a8c3da89..75cd717f 100644..100755
--- a/src/config.c
+++ b/src/config.c
@@ -740,6 +740,9 @@ static bool load_service(GKeyFile *keyfile, const char *group,
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 {
@@ -755,14 +758,14 @@ static bool load_service(GKeyFile *keyfile, const char *group,
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);
@@ -1154,6 +1157,10 @@ static void provision_service_wifi(struct connman_config_service *config,
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",
@@ -1181,6 +1188,20 @@ static gboolean remove_virtual_config(gpointer user_data)
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)
{
@@ -1189,7 +1210,6 @@ static int try_provision_service(struct connman_config_service *config,
enum connman_service_type type;
const void *ssid;
unsigned int ssid_len;
- const char *str;
network = __connman_service_get_network(service);
if (!network) {
@@ -1220,10 +1240,6 @@ static int try_provision_service(struct connman_config_service *config,
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:
@@ -1368,8 +1384,19 @@ static int try_provision_service(struct connman_config_service *config,
__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
}
}
@@ -1465,6 +1492,13 @@ int __connman_config_provision_service(struct connman_service *service)
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);
}
diff --git a/src/connection.c b/src/connection.c
index 6b005e7f..64d48b7d 100644..100755
--- a/src/connection.c
+++ b/src/connection.c
@@ -657,8 +657,15 @@ static void connection_newgateway(int index, const char *gateway)
}
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);
@@ -786,6 +793,32 @@ static void add_host_route(int family, int index, const char *gateway,
}
}
+#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,
@@ -812,6 +845,28 @@ int __connman_connection_gateway_add(struct connman_service *service,
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);
@@ -856,6 +911,12 @@ int __connman_connection_gateway_add(struct connman_service *service,
}
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;
}
@@ -971,6 +1032,9 @@ bool __connman_connection_update_gateway(void)
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;
@@ -1008,6 +1072,12 @@ bool __connman_connection_update_gateway(void)
}
}
+#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,
diff --git a/src/connman-dbus.conf b/src/connman-dbus.conf
index 98a773ea..29106dc7 100644..100755
--- a/src/connman-dbus.conf
+++ b/src/connman-dbus.conf
@@ -6,6 +6,19 @@
<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">
diff --git a/src/connman-polkit.conf b/src/connman-polkit.conf
index b13d339b..03154faf 100644..100755
--- a/src/connman-polkit.conf
+++ b/src/connman-polkit.conf
@@ -7,6 +7,12 @@
<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>
diff --git a/src/connman-wait-online.service.in b/src/connman-wait-online.service.in
deleted file mode 100644
index c2ad5cc9..00000000
--- a/src/connman-wait-online.service.in
+++ /dev/null
@@ -1,15 +0,0 @@
-[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
diff --git a/src/connman.conf b/src/connman.conf
new file mode 100644
index 00000000..6c6d23b6
--- /dev/null
+++ b/src/connman.conf
@@ -0,0 +1,30 @@
+<!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>
diff --git a/src/connman.h b/src/connman.h
index 21b70802..4125463b 100644..100755
--- a/src/connman.h
+++ b/src/connman.h
@@ -125,7 +125,6 @@ int __connman_agent_request_peer_authorization(struct connman_peer *peer,
bool wps_requested,
const char *dbus_sender,
void *user_data);
-
#include <connman/log.h>
int __connman_log_init(const char *program, const char *debug,
@@ -135,8 +134,6 @@ void __connman_log_cleanup(gboolean backtrace);
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>
@@ -172,6 +169,9 @@ int __connman_inet_ipv6_send_rs(int index, int timeout,
__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,
@@ -371,6 +371,11 @@ const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig);
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);
@@ -401,7 +406,15 @@ enum connman_ipconfig_method __connman_ipconfig_get_method(
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,
@@ -451,6 +464,11 @@ enum __connman_dhcpv6_status {
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);
@@ -560,6 +578,10 @@ int __connman_device_request_hidden_scan(struct connman_device *device,
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);
@@ -579,6 +601,11 @@ int __connman_rfkill_init(void);
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);
@@ -660,6 +687,15 @@ int __connman_service_load_modifiable(struct connman_service *service);
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);
@@ -693,6 +729,10 @@ struct connman_network *__connman_service_get_network(struct connman_service *se
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,
@@ -716,6 +756,10 @@ enum connman_service_state __connman_service_ipconfig_get_state(
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);
@@ -727,6 +771,12 @@ int __connman_service_disconnect(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,
@@ -744,10 +794,19 @@ const char *__connman_service_type2string(enum connman_service_type type);
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);
@@ -763,6 +822,17 @@ void __connman_service_timeserver_changed(struct connman_service *service,
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);
@@ -806,6 +876,9 @@ void __connman_service_notify(struct connman_service *service,
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);
@@ -875,12 +948,21 @@ int __connman_rtnl_init(void);
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);
@@ -1062,3 +1144,12 @@ void __connman_machine_cleanup(void);
int __connman_util_get_random(uint64_t *val);
int __connman_util_init(void);
void __connman_util_cleanup(void);
+
+#ifdef TIZEN_EXT
+__attribute__ ((unused)) static int __tizentvextension = -1;
+#define TIZEN_TV_EXT (__builtin_expect(__tizentvextension != -1, 1) ? \
+ __tizentvextension : \
+ (__tizentvextension = connman_setting_get_bool("TizenTVExtension")))
+#else /* TIZEN_EXT */
+#define TIZEN_TV_EXT (0) /* Always False */
+#endif /* TIZEN_EXT */
diff --git a/src/connman.service.in b/src/connman.service.in
index 9f5c10fe..9eb75b24 100644..100755
--- a/src/connman.service.in
+++ b/src/connman.service.in
@@ -1,21 +1,19 @@
[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
diff --git a/src/connman.socket b/src/connman.socket
new file mode 100644
index 00000000..5d0a280f
--- /dev/null
+++ b/src/connman.socket
@@ -0,0 +1,13 @@
+[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
diff --git a/src/connman_tv.service.in b/src/connman_tv.service.in
new file mode 100644
index 00000000..9eb75b24
--- /dev/null
+++ b/src/connman_tv.service.in
@@ -0,0 +1,19 @@
+[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
diff --git a/src/counter.c b/src/counter.c
index 8ea6205b..8ea6205b 100644..100755
--- a/src/counter.c
+++ b/src/counter.c
diff --git a/src/dbus.c b/src/dbus.c
index d80a46ce..71728300 100644..100755
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -524,6 +524,35 @@ err:
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;
diff --git a/src/detect.c b/src/detect.c
index 6c039206..7f20870c 100644..100755
--- a/src/detect.c
+++ b/src/detect.c
@@ -67,8 +67,15 @@ static void detect_newlink(unsigned short type, int index,
}
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)
diff --git a/src/device.c b/src/device.c
index a563f464..3ec8f715 100644..100755
--- a/src/device.c
+++ b/src/device.c
@@ -1042,6 +1042,73 @@ void connman_device_regdom_notify(struct connman_device *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;
@@ -1078,7 +1145,15 @@ int __connman_device_request_scan(enum connman_service_type type)
}
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;
@@ -1108,7 +1183,11 @@ int __connman_device_request_hidden_scan(struct connman_device *device,
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;
@@ -1154,7 +1233,11 @@ static char *index2ident(int index, const char *prefix)
return str;
}
+#if defined TIZEN_EXT
+char *index2addr(int index)
+#else
static char *index2addr(int index)
+#endif
{
struct ifreq ifr;
struct ether_addr eth;
@@ -1394,6 +1477,9 @@ static void cleanup_devices(void)
DBG("cleaning up %s index %d", interfaces[i], index);
+#if defined TIZEN_EXT
+ if (strcmp(interfaces[i], "wlan0") != 0)
+#endif
connman_inet_ifdown(index);
/*
diff --git a/src/dhcp.c b/src/dhcp.c
index 1af1eb52..c428c1d4 100644..100755
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -67,6 +67,9 @@ static GHashTable *ipconfig_table;
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);
@@ -76,10 +79,16 @@ static void dhcp_free(struct connman_dhcp *dhcp)
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;
@@ -119,8 +128,14 @@ static bool apply_dhcp_invalidate_on_network(struct connman_dhcp *dhcp)
}
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;
@@ -193,6 +208,10 @@ static int ipv4ll_start_client(struct connman_dhcp *dhcp)
int index;
int err;
+#if defined TIZEN_EXT
+ DBG("dhcp %p", dhcp);
+#endif
+
if (dhcp->ipv4ll_client)
return -EALREADY;
@@ -202,12 +221,16 @@ static int ipv4ll_start_client(struct connman_dhcp *dhcp)
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);
@@ -242,7 +265,10 @@ static gboolean dhcp_retry_cb(gpointer user_data)
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));
@@ -382,18 +408,32 @@ static bool apply_lease_available_on_network(GDHCPClient *dhcp_client,
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);
@@ -458,6 +498,10 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
__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);
@@ -492,6 +536,10 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_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.
*
@@ -580,14 +628,25 @@ static int dhcp_initialize(struct connman_dhcp *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);
@@ -675,7 +734,9 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig,
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;
@@ -689,7 +750,9 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig,
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) {
@@ -721,7 +784,13 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig,
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)
diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index cbf7974f..c624cb00 100644..100755
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -197,10 +197,23 @@ static int set_duid(struct connman_service *service,
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);
@@ -322,9 +335,19 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data)
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);
}
@@ -332,9 +355,19 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data)
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);
@@ -392,7 +425,9 @@ static int dhcpv6_info_request(struct connman_dhcpv6 *dhcp)
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);
@@ -517,9 +552,19 @@ static int set_other_addresses(GDHCPClient *dhcp_client,
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);
}
@@ -527,9 +572,19 @@ static int set_other_addresses(GDHCPClient *dhcp_client,
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);
@@ -638,6 +693,9 @@ static void set_address(int ifindex, struct connman_ipconfig *ipconfig,
/* 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);
@@ -645,6 +703,11 @@ static void set_address(int ifindex, struct connman_ipconfig *ipconfig,
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));
}
@@ -1713,7 +1776,9 @@ static gboolean timeout_solicitation(gpointer user_data)
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;
@@ -1728,7 +1793,9 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp)
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);
@@ -1754,8 +1821,20 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp)
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,
@@ -2045,7 +2124,9 @@ static GDHCPClient *create_pd_client(struct connman_dhcpv6 *dhcp, int *err)
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);
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 40b4f159..3fa7bf46 100644..100755
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -41,6 +41,11 @@
#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
@@ -194,7 +199,11 @@ struct domain_rr {
* 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.
*/
@@ -213,12 +222,22 @@ static int cache_size;
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;
@@ -1642,6 +1661,31 @@ static int ns_resolv(struct server_data *server, struct request_data *req,
}
}
+#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,
@@ -2240,6 +2284,19 @@ static gboolean udp_server_event(GIOChannel *channel, GIOCondition condition,
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;
}
@@ -2550,6 +2607,177 @@ static void enable_fallback(bool enable)
}
}
+#if defined TIZEN_EXT
+
+static void destroy_server_sec(struct server_data *server)
+{
+ GList *list;
+ int fd;
+
+ if (server->channel)
+ fd = g_io_channel_unix_get_fd(server->channel);
+ else
+ fd = -1;
+
+ DBG("index %d server %s sock %d", server->index, server->server, fd);
+
+ server_list_sec = g_slist_remove(server_list_sec, server);
+
+ if (fd > 0)
+ close(fd);
+
+ server_destroy_socket(server);
+
+ if (server->protocol == IPPROTO_UDP && server->enabled)
+ DBG("Removing DNS server %s", server->server);
+
+ g_free(server->server);
+ for (list = server->domains; list; list = list->next) {
+ char *domain = list->data;
+
+ server->domains = g_list_remove(server->domains, domain);
+ g_free(domain);
+ }
+ g_free(server->server_addr);
+
+ /*
+ * We do not remove cache right away but delay it few seconds.
+ * The idea is that when IPv6 DNS server is added via RDNSS, it has a
+ * lifetime. When the lifetime expires we decrease the refcount so it
+ * is possible that the cache is then removed. Because a new DNS server
+ * is usually created almost immediately we would then loose the cache
+ * without any good reason. The small delay allows the new RDNSS to
+ * create a new DNS server instance and the refcount does not go to 0.
+ */
+ /* TODO: Need to check this */
+ /* g_timeout_add_seconds(3, try_remove_cache, NULL); */
+
+ g_free(server);
+}
+
+static void destroy_all_server_sec()
+{
+ GSList *list;
+
+ DBG("remove all dns server");
+
+ for (list = server_list_sec; list; list = list->next) {
+ struct server_data *server = list->data;
+ destroy_server_sec(server);
+ }
+ server_list_sec = NULL;
+}
+
+static gboolean sec_udp_idle_timeout(gpointer user_data)
+{
+ struct server_data *server = user_data;
+
+ DBG("");
+
+ if (server == NULL)
+ return FALSE;
+
+ destroy_server_sec(server);
+
+ return FALSE;
+}
+
+static struct server_data *create_server_sec(int index,
+ const char *domain, const char *server,
+ int protocol)
+{
+ struct server_data *data;
+ struct addrinfo hints, *rp;
+ int ret;
+
+ DBG("index %d server %s", index, server);
+
+ data = g_try_new0(struct server_data, 1);
+ if (data == NULL) {
+ connman_error("Failed to allocate server %s data", server);
+ return NULL;
+ }
+
+ data->index = index;
+ if (domain)
+ data->domains = g_list_append(data->domains, g_strdup(domain));
+ data->server = g_strdup(server);
+ data->protocol = protocol;
+
+ memset(&hints, 0, sizeof(hints));
+
+ switch (protocol) {
+ case IPPROTO_UDP:
+ hints.ai_socktype = SOCK_DGRAM;
+ break;
+
+ case IPPROTO_TCP:
+ hints.ai_socktype = SOCK_STREAM;
+ break;
+
+ default:
+ destroy_server_sec(data);
+ return NULL;
+ }
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST;
+
+ ret = getaddrinfo(data->server, "53", &hints, &rp);
+ if (ret) {
+ connman_error("Failed to parse server %s address: %s\n",
+ data->server, gai_strerror(ret));
+ freeaddrinfo(rp);
+ destroy_server_sec(data);
+ return NULL;
+ }
+
+ /* Do not blindly copy this code elsewhere; it doesn't loop over the
+ results using ->ai_next as it should. That's OK in *this* case
+ because it was a numeric lookup; we *know* there's only one. */
+
+ data->server_addr_len = rp->ai_addrlen;
+
+ switch (rp->ai_family) {
+ case AF_INET:
+ data->server_addr = (struct sockaddr *)
+ g_try_new0(struct sockaddr_in, 1);
+ break;
+ case AF_INET6:
+ data->server_addr = (struct sockaddr *)
+ g_try_new0(struct sockaddr_in6, 1);
+ break;
+ default:
+ connman_error("Wrong address family %d", rp->ai_family);
+ break;
+ }
+ if (data->server_addr == NULL) {
+ freeaddrinfo(rp);
+ destroy_server_sec(data);
+ return NULL;
+ }
+ memcpy(data->server_addr, rp->ai_addr, rp->ai_addrlen);
+ freeaddrinfo(rp);
+
+ if (server_create_socket(data) != 0) {
+ destroy_server_sec(data);
+ return NULL;
+ }
+
+ if (protocol == IPPROTO_UDP) {
+ /* Enable new servers by default */
+ data->enabled = TRUE;
+ DBG("Adding DNS server %s", data->server);
+
+ data->timeout = g_timeout_add_seconds(30, sec_udp_idle_timeout,
+ data);
+
+ server_list_sec = g_slist_append(server_list_sec, data);
+ }
+
+ return data;
+}
+#endif
+
static struct server_data *create_server(int index,
const char *domain, const char *server,
int protocol)
@@ -2840,6 +3068,10 @@ int __connman_dnsproxy_remove(int index, const char *domain,
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;
}
@@ -3288,6 +3520,23 @@ static gboolean client_timeout(gpointer user_data)
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)
@@ -3308,11 +3557,17 @@ static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition,
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;
}
@@ -3426,7 +3681,11 @@ static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition,
* 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);
@@ -3471,8 +3730,14 @@ static bool udp_listener_event(GIOChannel *channel, GIOCondition condition,
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;
}
@@ -3531,7 +3796,12 @@ static bool udp_listener_event(GIOChannel *channel, GIOCondition condition,
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;
@@ -3559,14 +3829,24 @@ static GIOChannel *get_listener(int family, int protocol, int index)
{
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);
@@ -3584,7 +3864,33 @@ static GIOChannel *get_listener(int family, int protocol, int 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");
@@ -3596,6 +3902,9 @@ static GIOChannel *get_listener(int family, int protocol, int index)
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,
@@ -3632,7 +3941,6 @@ static GIOChannel *get_listener(int family, int protocol, int index)
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) {
@@ -3643,22 +3951,30 @@ static GIOChannel *get_listener(int family, int protocol, int index)
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);
}
@@ -3691,40 +4007,68 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
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;
}
diff --git a/src/eduroam.config b/src/eduroam.config
index 768b7b40..768b7b40 100644..100755
--- a/src/eduroam.config
+++ b/src/eduroam.config
diff --git a/src/error.c b/src/error.c
index 4f24ae25..4f24ae25 100644..100755
--- a/src/error.c
+++ b/src/error.c
diff --git a/src/inet.c b/src/inet.c
index b887aa0b..008f3de7 100644..100755
--- a/src/inet.c
+++ b/src/inet.c
@@ -330,6 +330,61 @@ done:
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;
@@ -1282,6 +1337,37 @@ static int icmpv6_recv(int fd, struct xs_cb_data *data)
return -errno;
}
+#if defined TIZEN_EXT
+ /* Set Received Source Address from router as IPv6 Gateway Address */
+ char src_addr[INET6_ADDRSTRLEN];
+ if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
+ == NULL) {
+ xs_cleanup(data);
+ return -errno;
+ }
+ DBG("Received Source Address %s from router", src_addr);
+
+ /* icmpv6_recv() function can be called in two scenarios :
+ * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
+ * 2. When __connman_inet_ipv6_send_rs() is called from
+ * __connman_6to4_probe()
+ * In the second case it is not required to set DHCPv6 Gateway Address
+ * as DHCPv6 was not started and network structure was not passed as
+ * user_data. If it is tried to add Source Address as Gateway Address
+ * then it will lead to crash because of user_data being ip_address
+ * instead of network structure. So Adding Gateway Address in case 1st
+ * case only.
+ */
+ char *address = data->user_data;
+ int err = 0;
+ unsigned char buffer[sizeof(struct in6_addr)] = {0, };
+ /* Checking if user_data is an ip_address */
+ err = inet_pton(AF_INET, address, buffer);
+ /* Setting Received Source Address from
+ * router as Gateway Address */
+ if(err <= 0)
+ __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
+#endif
hdr = (struct nd_router_advert *)buf;
DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
sizeof(struct nd_router_advert));
@@ -1381,6 +1467,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
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("");
@@ -1459,6 +1548,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
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;
@@ -2651,7 +2743,8 @@ char **__connman_inet_get_running_interfaces(void)
g_free(ifr);
- if (count < numif) {
+ if (count < numif)
+ {
char **prev_result = result;
result = g_try_realloc(result, (count + 1) * sizeof(char *));
if (!result) {
diff --git a/src/inotify.c b/src/inotify.c
index c251c6ff..c251c6ff 100644..100755
--- a/src/inotify.c
+++ b/src/inotify.c
diff --git a/src/ipaddress.c b/src/ipaddress.c
index d63d95c3..d63d95c3 100644..100755
--- a/src/ipaddress.c
+++ b/src/ipaddress.c
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 25657733..d94b8734 100644..100755
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -52,6 +52,10 @@ struct connman_ipconfig {
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;
@@ -488,6 +492,16 @@ void __connman_ipconfig_newlink(int index, unsigned short type,
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);
@@ -1047,16 +1061,32 @@ void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig,
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;
@@ -1122,8 +1152,11 @@ static struct connman_ipconfig *create_ipv6config(int index)
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);
@@ -1353,6 +1386,12 @@ int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig)
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:
@@ -1639,6 +1678,11 @@ int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig)
if (ipdevice->config_ipv6 == ipconfig) {
ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
+#if defined TIZEN_EXT
+ if (ipdevice->config_ipv6->method ==
+ CONNMAN_IPCONFIG_METHOD_AUTO)
+ disable_ipv6(ipdevice->config_ipv6);
+#endif
connman_ipaddress_clear(ipdevice->config_ipv6->system);
__connman_ipconfig_unref(ipdevice->config_ipv6);
ipdevice->config_ipv6 = NULL;
@@ -1772,6 +1816,11 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
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;
}
@@ -1796,6 +1845,20 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
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,
@@ -1833,6 +1896,11 @@ 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;
}
@@ -2032,7 +2100,10 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
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:
@@ -2042,7 +2113,9 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
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:
diff --git a/src/ippool.c b/src/ippool.c
index cea1dccd..cea1dccd 100644..100755
--- a/src/ippool.c
+++ b/src/ippool.c
diff --git a/src/iptables.c b/src/iptables.c
index 5ef757a3..aaddf9d6 100644..100755
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -2350,7 +2350,7 @@ int __connman_iptables_commit(const char *table_name)
return -EINVAL;
repl = iptables_blob(table);
- if (!repl)
+ if(!repl)
return -ENOMEM;
if (debug_enabled)
diff --git a/src/ipv6pd.c b/src/ipv6pd.c
index 0d221f07..0d221f07 100644..100755
--- a/src/ipv6pd.c
+++ b/src/ipv6pd.c
diff --git a/src/log.c b/src/log.c
index 9bae4a3d..fa8ac31f 100644..100755
--- a/src/log.c
+++ b/src/log.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
+#include <execinfo.h>
#include <dlfcn.h>
#include "connman.h"
@@ -37,6 +38,132 @@
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
@@ -89,6 +216,7 @@ void connman_error(const char *format, ...)
vsyslog(LOG_ERR, format, ap);
va_end(ap);
+ fflush(log_file);
}
/**
@@ -107,13 +235,116 @@ void connman_debug(const char *format, ...)
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);
}
diff --git a/src/machine.c b/src/machine.c
index 14ea3667..14ea3667 100644..100755
--- a/src/machine.c
+++ b/src/machine.c
diff --git a/src/main.c b/src/main.c
index b78a0461..4bc2266b 100644..100755
--- a/src/main.c
+++ b/src/main.c
@@ -30,6 +30,8 @@
#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>
@@ -79,6 +81,10 @@ static struct {
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,
@@ -96,6 +102,10 @@ static struct {
.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"
@@ -114,6 +124,10 @@ static struct {
#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,
@@ -130,8 +144,11 @@ static const char *supported_options[] = {
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
};
@@ -246,6 +263,46 @@ static void check_config(GKeyFile *config)
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;
@@ -408,12 +465,19 @@ static void parse_config(GKeyFile *config)
}
g_clear_error(&error);
+
+#if defined TIZEN_EXT
+ check_Tizen_configuration(config);
+#endif
}
static int config_init(const char *file)
{
GKeyFile *config;
+#if defined TIZEN_EXT
+ set_nofile_inc();
+#endif
config = load_config(file);
check_config(config);
parse_config(config);
@@ -632,6 +696,11 @@ char **connman_setting_get_string_list(const char *key)
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;
}
@@ -768,8 +837,10 @@ int main(int argc, char *argv[])
__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);
@@ -781,8 +852,10 @@ int main(int argc, char *argv[])
g_source_remove(signal);
+#if !defined TIZEN_EXT
__connman_machine_cleanup();
__connman_rfkill_cleanup();
+#endif
__connman_wispr_cleanup();
__connman_wpad_cleanup();
__connman_dhcpv6_cleanup();
diff --git a/src/main.conf b/src/main.conf
index 68870b28..a2cc1e20 100644..100755
--- a/src/main.conf
+++ b/src/main.conf
@@ -19,6 +19,7 @@
# 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
@@ -26,6 +27,7 @@
# 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
@@ -52,6 +54,7 @@
# 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
@@ -59,6 +62,7 @@
# 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.
@@ -76,6 +80,7 @@
# 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
@@ -117,3 +122,5 @@
# other which is already connected.
# This setting has no effect if SingleConnectedTechnologies is enabled.
# AlwaysConnectedTechnologies =
+
+NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w
diff --git a/src/main_disable_eth.conf b/src/main_disable_eth.conf
new file mode 100755
index 00000000..c4ec3e38
--- /dev/null
+++ b/src/main_disable_eth.conf
@@ -0,0 +1,110 @@
+[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
diff --git a/src/main_ivi.conf b/src/main_ivi.conf
new file mode 100755
index 00000000..627bd061
--- /dev/null
+++ b/src/main_ivi.conf
@@ -0,0 +1,110 @@
+[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
diff --git a/src/main_tv.conf b/src/main_tv.conf
new file mode 100755
index 00000000..fd3afc90
--- /dev/null
+++ b/src/main_tv.conf
@@ -0,0 +1,116 @@
+[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
+
diff --git a/src/manager.c b/src/manager.c
index d15ce203..2e1367ff 100644..100755
--- a/src/manager.c
+++ b/src/manager.c
@@ -41,6 +41,9 @@ static DBusMessage *get_properties(DBusConnection *conn,
DBusMessageIter array, dict;
dbus_bool_t offlinemode;
const char *str;
+#if defined TIZEN_EXT
+ dbus_bool_t autoconnectmode;
+#endif
DBG("conn %p", conn);
@@ -63,6 +66,12 @@ static DBusMessage *get_properties(DBusConnection *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);
@@ -102,6 +111,20 @@ static DBusMessage *set_property(DBusConnection *conn,
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")) {
@@ -109,8 +132,20 @@ static DBusMessage *set_property(DBusConnection *conn,
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);
@@ -126,7 +161,9 @@ static DBusMessage *get_technologies(DBusConnection *conn,
{
DBusMessage *reply;
+#if !defined TIZEN_EXT
DBG("");
+#endif
reply = dbus_message_new_method_return(msg);
if (!reply)
diff --git a/src/nat.c b/src/nat.c
index fb557101..fb557101 100644..100755
--- a/src/nat.c
+++ b/src/nat.c
diff --git a/src/net.connman.service.in b/src/net.connman.service.in
index f7f6a7c0..990eb66b 100644..100755
--- a/src/net.connman.service.in
+++ b/src/net.connman.service.in
@@ -1,5 +1,6 @@
[D-BUS Service]
Name=net.connman
-Exec=@sbindir@/connmand -n
-User=root
+Exec=/bin/false
+User=network_fw
+Group=network_fw
SystemdService=connman.service
diff --git a/src/network.c b/src/network.c
index ed56210f..d38fc0af 100644..100755
--- a/src/network.c
+++ b/src/network.c
@@ -41,6 +41,18 @@
*/
#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;
@@ -92,8 +104,26 @@ struct connman_network {
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)
@@ -167,7 +197,11 @@ static void dhcp_success(struct connman_network *network)
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;
@@ -233,7 +267,11 @@ static int set_connected_manual(struct connman_network *network)
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;
@@ -287,7 +325,11 @@ static int manual_ipv6_set(struct connman_network *network,
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;
@@ -427,10 +469,13 @@ static void check_dhcpv6(struct nd_router_advert *reply,
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;
}
@@ -443,6 +488,9 @@ static void check_dhcpv6(struct nd_router_advert *reply,
*/
if (!network->connected) {
connman_network_unref(network);
+#if defined TIZEN_EXT
+ DBG("Network is not connected");
+#endif
return;
}
@@ -471,11 +519,21 @@ static void check_dhcpv6(struct nd_router_advert *reply,
* 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;
@@ -557,6 +615,11 @@ static void autoconf_ipv6_set(struct connman_network *network)
__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;
@@ -577,7 +640,8 @@ static void autoconf_ipv6_set(struct connman_network *network)
/* 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)
@@ -690,12 +754,22 @@ static void set_disconnected(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
@@ -905,7 +979,9 @@ static void network_destruct(struct connman_network *network)
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);
@@ -1147,6 +1223,15 @@ bool __connman_network_get_weakness(struct connman_network *network)
return false;
}
+#if defined TIZEN_EXT
+void connman_network_set_connecting(struct connman_network *network)
+{
+ DBG("set network connecting true");
+ network->connecting = TRUE;
+ return;
+}
+#endif
+
bool connman_network_get_connecting(struct connman_network *network)
{
return network->connecting;
@@ -1162,7 +1247,9 @@ bool connman_network_get_connecting(struct connman_network *network)
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;
@@ -1183,6 +1270,113 @@ bool connman_network_get_available(struct connman_network *network)
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
@@ -1212,6 +1406,14 @@ int connman_network_set_associating(struct connman_network *network,
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;
}
@@ -1221,8 +1423,13 @@ static void set_associate_error(struct connman_network *network)
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)
@@ -1241,6 +1448,10 @@ static void set_invalid_key_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);
}
@@ -1265,6 +1476,22 @@ static void set_blocked_error(struct connman_network *network)
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)
{
@@ -1319,9 +1546,16 @@ void connman_network_set_error(struct connman_network *network,
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);
@@ -1461,13 +1695,21 @@ int __connman_network_connect(struct connman_network *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;
@@ -1498,7 +1740,9 @@ int __connman_network_disconnect(struct connman_network *network)
return -EUNATCH;
network->connecting = false;
-
+#if defined TIZEN_EXT
+ DBG("ConnMan, Disconnect request");
+#endif
if (network->driver->disconnect)
err = network->driver->disconnect(network);
@@ -1552,12 +1796,38 @@ int __connman_network_clear_ipconfig(struct connman_network *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;
@@ -1585,6 +1855,14 @@ int __connman_network_enable_ipconfig(struct connman_network *network,
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;
@@ -1661,6 +1939,142 @@ int connman_network_set_ipaddress(struct connman_network *network,
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)
{
@@ -1682,8 +2096,14 @@ int connman_network_set_nameservers(struct connman_network *network,
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);
@@ -1799,6 +2219,9 @@ int connman_network_set_string(struct connman_network *network,
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")) {
@@ -1869,7 +2292,15 @@ const char *connman_network_get_string(struct connman_network *network,
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"))
@@ -1921,6 +2352,12 @@ int connman_network_set_bool(struct connman_network *network,
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;
}
@@ -1941,6 +2378,12 @@ bool connman_network_get_bool(struct connman_network *network,
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;
}
@@ -1965,6 +2408,16 @@ int connman_network_set_blob(struct connman_network *network,
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;
}
@@ -1989,6 +2442,15 @@ const void *connman_network_get_blob(struct connman_network *network,
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;
}
diff --git a/src/notifier.c b/src/notifier.c
index 5ba53242..5ba53242 100644..100755
--- a/src/notifier.c
+++ b/src/notifier.c
diff --git a/src/ntp.c b/src/ntp.c
index 0e80c3e5..11512a02 100644..100755
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -251,8 +251,9 @@ static void decode_msg(void *base, size_t len, struct timeval *tv,
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;
@@ -341,6 +342,66 @@ static void decode_msg(void *base, size_t len, struct timeval *tv,
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;
@@ -379,7 +440,8 @@ static void decode_msg(void *base, size_t len, struct timeval *tv,
}
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,
diff --git a/src/peer.c b/src/peer.c
index 340cbcc2..340cbcc2 100644..100755
--- a/src/peer.c
+++ b/src/peer.c
diff --git a/src/peer_service.c b/src/peer_service.c
index a457bff7..a457bff7 100644..100755
--- a/src/peer_service.c
+++ b/src/peer_service.c
diff --git a/src/plugin.c b/src/plugin.c
index 7d730582..7d730582 100644..100755
--- a/src/plugin.c
+++ b/src/plugin.c
diff --git a/src/provider.c b/src/provider.c
index 9c71a200..c0d69e49 100644..100755
--- a/src/provider.c
+++ b/src/provider.c
@@ -243,7 +243,11 @@ static int set_connected(struct connman_provider *provider,
}
__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);
@@ -573,8 +577,14 @@ int connman_provider_set_nameservers(struct connman_provider *provider,
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;
}
diff --git a/src/proxy.c b/src/proxy.c
index e1bc420a..e1bc420a 100644..100755
--- a/src/proxy.c
+++ b/src/proxy.c
diff --git a/src/resolver.c b/src/resolver.c
index 75ea5ba6..d6c20cdd 100644..100755
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -35,9 +35,6 @@
#include "connman.h"
-#define RESOLV_CONF_STATEDIR STATEDIR"/resolv.conf"
-#define RESOLV_CONF_ETC "/etc/resolv.conf"
-
#define RESOLVER_FLAG_PUBLIC (1 << 0)
/*
@@ -133,19 +130,11 @@ static int resolvfile_export(void)
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) {
@@ -312,8 +301,14 @@ static gboolean resolver_expire_cb(gpointer user_data)
struct connman_service *service;
service = __connman_service_lookup_from_index(entry->index);
if (service)
+#if defined TIZEN_EXT
+ __connman_service_nameserver_remove(service,
+ entry->server, true,
+ CONNMAN_IPCONFIG_TYPE_ALL);
+#else
__connman_service_nameserver_remove(service,
entry->server, true);
+#endif
}
remove_entries(list);
@@ -367,6 +362,11 @@ static int append_resolver(int index, const char *domain,
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;
@@ -409,8 +409,14 @@ static int append_resolver(int index, const char *domain,
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;
diff --git a/src/rfkill.c b/src/rfkill.c
index d9bed4d2..fce9d720 100644..100755
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -73,6 +73,7 @@ static enum connman_service_type convert_type(uint8_t type)
return CONNMAN_SERVICE_TYPE_UNKNOWN;
}
+#if !defined TIZEN_EXT
static enum rfkill_type convert_service_type(enum connman_service_type type)
{
switch (type) {
@@ -95,6 +96,7 @@ static enum rfkill_type convert_service_type(enum connman_service_type type)
return NUM_RFKILL_TYPES;
}
+#endif
static GIOStatus rfkill_process(GIOChannel *chan)
{
@@ -157,13 +159,20 @@ static guint watch = 0;
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;
@@ -186,6 +195,7 @@ int __connman_rfkill_block(enum connman_service_type type, bool block)
close(fd);
return err;
+#endif
}
int __connman_rfkill_init(void)
diff --git a/src/rtnl.c b/src/rtnl.c
index a094e257..35ae0a96 100644..100755
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -46,6 +46,12 @@
#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)
@@ -94,6 +100,7 @@ static bool ether_blacklisted(const char *name)
return false;
}
+#if !defined TIZEN_EXT
static bool wext_interface(char *ifname)
{
struct iwreq wrq;
@@ -115,6 +122,30 @@ static bool wext_interface(char *ifname)
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)
{
@@ -124,6 +155,14 @@ 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;
@@ -187,6 +226,8 @@ static void read_uevent(struct interface_data *interface)
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;
@@ -194,6 +235,7 @@ static void read_uevent(struct interface_data *interface)
connman_error("%s runs an unsupported 802.11 driver", name);
}
+#endif
out:
g_free(name);
@@ -419,6 +461,14 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
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],
@@ -441,12 +491,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
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;
@@ -471,6 +534,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
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
@@ -534,6 +616,13 @@ static void process_dellink(unsigned short type, int index, unsigned flags,
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;
}
@@ -1229,6 +1318,37 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr)
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,
@@ -1239,16 +1359,29 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr)
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 */
diff --git a/src/service.c b/src/service.c
index 02cd51f2..d0543ae5 100644..100755
--- a/src/service.c
+++ b/src/service.c
@@ -30,6 +30,8 @@
#include <gdbus.h>
#include <ctype.h>
#include <stdint.h>
+#include <pwd.h>
+#include <utmpx.h>
#include <connman/storage.h>
#include <connman/setting.h>
@@ -39,6 +41,13 @@
#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;
@@ -49,6 +58,10 @@ static unsigned int vpn_autoconnect_timeout = 0;
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;
@@ -63,6 +76,11 @@ struct connman_stats_counter {
struct connman_stats stats_roaming;
};
+struct connman_service_user {
+ uid_t favorite_user;
+ uid_t current_user;
+};
+
struct connman_service {
int refcount;
char *identifier;
@@ -85,6 +103,8 @@ struct connman_service {
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;
@@ -130,6 +150,28 @@ struct connman_service {
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);
@@ -145,6 +187,50 @@ struct find_data {
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;
@@ -253,6 +339,10 @@ enum connman_service_security __connman_service_string2security(const char *str)
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;
}
@@ -268,8 +358,14 @@ static const char *security2string(enum connman_service_security security)
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";
}
@@ -355,6 +451,116 @@ static enum connman_service_proxy_method string2proxymethod(const char *method)
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)
@@ -418,6 +624,25 @@ int __connman_service_load_modifiable(struct connman_service *service)
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;
@@ -552,6 +777,18 @@ static int service_load(struct connman_service *service)
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) {
@@ -597,6 +834,63 @@ static int service_load(struct connman_service *service)
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);
@@ -642,6 +936,13 @@ static int service_save(struct connman_service *service)
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);
@@ -697,12 +998,14 @@ static int service_save(struct connman_service *service)
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,
@@ -722,6 +1025,28 @@ static int service_save(struct connman_service *service)
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);
@@ -787,6 +1112,60 @@ static int service_save(struct connman_service *service)
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);
@@ -1053,6 +1432,9 @@ static int nameserver_add(struct connman_service *service,
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);
@@ -1067,14 +1449,115 @@ static int nameserver_add_all(struct connman_service *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++;
}
}
@@ -1100,6 +1583,9 @@ static int nameserver_remove(struct connman_service *service,
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);
@@ -1110,6 +1596,15 @@ static int nameserver_remove(struct connman_service *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);
@@ -1117,15 +1612,124 @@ static int nameserver_remove_all(struct connman_service *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++;
}
@@ -1139,13 +1743,19 @@ static int nameserver_remove_all(struct connman_service *service,
* 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;
@@ -1156,8 +1766,15 @@ int __connman_service_nameserver_append(struct connman_service *service,
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);
@@ -1173,6 +1790,16 @@ int __connman_service_nameserver_append(struct connman_service *service,
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 {
@@ -1187,8 +1814,14 @@ int __connman_service_nameserver_append(struct connman_service *service,
return 0;
}
+#if defined TIZEN_EXT
+int __connman_service_nameserver_remove(struct connman_service *service,
+ const char *nameserver, bool is_auto,
+ enum connman_ipconfig_type type)
+#else
int __connman_service_nameserver_remove(struct connman_service *service,
const char *nameserver, bool is_auto)
+#endif
{
char **servers, **nameservers;
bool found = false;
@@ -1246,8 +1879,14 @@ set_servers:
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;
@@ -1473,6 +2112,71 @@ static void reset_stats(struct connman_service *service)
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;
@@ -1511,9 +2215,15 @@ static void default_changed(void)
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 &&
@@ -1537,9 +2247,13 @@ static void state_changed(struct connman_service *service)
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);
@@ -1726,20 +2440,143 @@ static void append_nameservers(DBusMessageIter *iter,
}
}
+#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,
@@ -1761,10 +2598,46 @@ static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
{
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)
@@ -2338,6 +3211,86 @@ int __connman_service_iterate_services(service_iterate_cb cb, 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)
{
@@ -2345,6 +3298,23 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
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",
@@ -2358,6 +3328,13 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
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",
@@ -2403,6 +3380,21 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
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:
@@ -2635,6 +3627,54 @@ char **connman_service_get_timeservers(struct connman_service *service)
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)
{
@@ -2722,6 +3762,18 @@ const char *connman_service_get_proxy_autoconfig(struct connman_service *service
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)
{
@@ -2849,6 +3901,22 @@ void __connman_service_set_pac(struct connman_service *service,
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)
{
@@ -2968,7 +4036,9 @@ int __connman_service_check_passphrase(enum connman_service_security security,
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);
@@ -2976,6 +4046,9 @@ int __connman_service_check_passphrase(enum connman_service_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].
@@ -3019,7 +4092,14 @@ int __connman_service_set_passphrase(struct connman_service *service,
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)
@@ -3347,6 +4427,21 @@ static DBusMessage *set_property(DBusConnection *conn,
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);
@@ -3384,6 +4479,10 @@ static DBusMessage *set_property(DBusConnection *conn,
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)
@@ -3400,17 +4499,64 @@ static DBusMessage *set_property(DBusConnection *conn,
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;
@@ -3420,7 +4566,21 @@ static DBusMessage *set_property(DBusConnection *conn,
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) {
@@ -3443,7 +4603,12 @@ static DBusMessage *set_property(DBusConnection *conn,
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,
@@ -3646,8 +4811,10 @@ static void set_error(struct connman_service *service,
if (!service->path)
return;
+#if !defined TIZEN_EXT
if (!allow_property_changed(service))
return;
+#endif
str = error2string(service->error);
@@ -3694,6 +4861,14 @@ static void service_complete(struct connman_service *service)
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)
{
@@ -3856,6 +5031,17 @@ static GList *preferred_tech_list_get(void)
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;
}
}
@@ -3930,6 +5116,20 @@ static bool auto_connect_service(GList *services,
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)) {
@@ -3949,9 +5149,21 @@ static bool auto_connect_service(GList *services,
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;
@@ -3962,6 +5174,11 @@ static bool auto_connect_service(GList *services,
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));
@@ -3999,6 +5216,21 @@ static gboolean run_auto_connect(gpointer data)
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("");
@@ -4006,10 +5238,33 @@ void __connman_service_auto_connect(enum connman_service_connect_reason reason)
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));
}
@@ -4173,19 +5428,67 @@ static DBusMessage *connect_service(DBusConnection *conn,
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;
@@ -4202,6 +5505,7 @@ static DBusMessage *connect_service(DBusConnection *conn,
}
if (err == -EINPROGRESS)
return __connman_error_operation_timeout(msg);
+#endif
service->ignore = false;
@@ -4232,6 +5536,35 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
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);
@@ -4241,6 +5574,24 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
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 ||
@@ -4251,8 +5602,10 @@ bool __connman_service_remove(struct connman_service *service)
__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);
@@ -4283,13 +5636,62 @@ bool __connman_service_remove(struct connman_service *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;
}
@@ -4301,6 +5703,23 @@ static DBusMessage *remove_service(DBusConnection *conn,
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);
@@ -4510,6 +5929,30 @@ static DBusMessage *reset_counters(DBusConnection *conn,
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;
@@ -4522,17 +5965,23 @@ static void service_append_added_foreach(gpointer data, gpointer user_data)
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);
}
@@ -4620,6 +6069,10 @@ static void service_schedule_removed(struct connman_service *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;
@@ -4649,6 +6102,9 @@ static const GDBusMethodTable service_methods[] = {
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) },
{ },
};
@@ -4789,6 +6245,11 @@ static void service_initialize(struct connman_service *service)
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;
@@ -4798,6 +6259,14 @@ static void service_initialize(struct connman_service *service)
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
}
/**
@@ -5035,6 +6504,40 @@ char *connman_service_get_interface(struct connman_service *service)
}
/**
+ * __connman_service_is_user_allowed:
+ * @type: service type
+ * @uid: user id
+ *
+ * Check a user is allowed to operate a type of service
+ */
+bool __connman_service_is_user_allowed(enum connman_service_type type,
+ uid_t uid)
+{
+ GList *list;
+ uid_t owner_user = USER_NONE;
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *service = list->data;
+
+ if (service->type != type)
+ continue;
+
+ if (is_connected(service->state)) {
+ owner_user = service->user.favorite_user;
+ break;
+ }
+ }
+
+ if (uid == USER_NONE ||
+ (uid != USER_ROOT &&
+ owner_user != USER_NONE &&
+ owner_user != uid))
+ return false;
+
+ return true;
+}
+
+/**
* connman_service_get_network:
* @service: service structure
*
@@ -5129,6 +6632,53 @@ void __connman_service_mark_dirty(void)
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
@@ -5141,6 +6691,10 @@ int __connman_service_set_favorite_delayed(struct connman_service *service,
bool favorite,
bool delay_ordering)
{
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ return -EIO;
+#endif
if (service->hidden)
return -EOPNOTSUPP;
@@ -5285,7 +6839,14 @@ static void report_error_cb(void *user_context, bool retry,
/* 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();
}
@@ -5467,6 +7028,126 @@ static int service_update_preferred_order(struct connman_service *default_servic
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;
@@ -5475,15 +7156,24 @@ static void single_connected_tech(struct connman_service *allowed)
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);
}
@@ -5491,12 +7181,32 @@ static void single_connected_tech(struct connman_service *allowed)
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)
@@ -5640,6 +7350,11 @@ static int service_indicate_state(struct connman_service *service)
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:
@@ -5652,6 +7367,8 @@ static int service_indicate_state(struct connman_service *service)
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 &&
@@ -5664,8 +7381,20 @@ static int service_indicate_state(struct connman_service *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
@@ -5678,7 +7407,11 @@ static int service_indicate_state(struct connman_service *service)
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),
@@ -5693,6 +7426,10 @@ static int service_indicate_state(struct connman_service *service)
service_list_sort();
+#if defined TIZEN_EXT
+ __connman_service_connect_default(service);
+#endif
+
__connman_connection_update_gateway();
if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
@@ -5707,6 +7444,20 @@ static int service_indicate_state(struct connman_service *service)
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;
}
@@ -5723,6 +7474,23 @@ int __connman_service_indicate_error(struct connman_service *service,
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);
@@ -5825,6 +7593,15 @@ done:
__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
@@ -5976,6 +7753,18 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
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),
@@ -5989,14 +7778,25 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
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)
@@ -6033,6 +7833,19 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
__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);
}
@@ -6129,6 +7942,33 @@ static int service_connect(struct connman_service *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:
@@ -6153,7 +7993,11 @@ static int service_connect(struct connman_service *service)
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;
@@ -6167,13 +8011,25 @@ static int service_connect(struct connman_service *service)
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
@@ -6279,7 +8135,6 @@ int __connman_service_connect(struct connman_service *service,
DBG("service %p err %d", service, err);
service->connect_reason = reason;
-
if (err >= 0)
return 0;
@@ -6361,6 +8216,14 @@ int __connman_service_disconnect(struct connman_service *service)
__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);
@@ -6369,6 +8232,9 @@ int __connman_service_disconnect(struct connman_service *service)
__connman_ipconfig_disable(service->ipconfig_ipv4);
__connman_ipconfig_disable(service->ipconfig_ipv6);
+#if defined TIZEN_EXT
+ }
+#endif
__connman_stats_service_unregister(service);
@@ -6581,6 +8447,9 @@ static void service_ip_bound(struct connman_ipconfig *ipconfig,
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);
@@ -6592,9 +8461,18 @@ static void service_ip_bound(struct connman_ipconfig *ipconfig,
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);
@@ -6835,6 +8713,28 @@ unsigned int __connman_service_get_order(struct connman_service *service)
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;
@@ -6843,7 +8743,7 @@ unsigned int __connman_service_get_order(struct connman_service *service)
service->order = 10;
order = 10;
}
-
+#endif
DBG("service %p name %s order %d split %d", service, service->name,
order, service->do_split_routing);
@@ -6890,10 +8790,30 @@ static enum connman_service_security convert_wifi_security(const char *security)
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)
{
@@ -7067,6 +8987,19 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
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);
@@ -7090,6 +9023,13 @@ void __connman_service_update_from_network(struct connman_network *network)
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);
diff --git a/src/session.c b/src/session.c
index 9e3c5594..9e3c5594 100644..100755
--- a/src/session.c
+++ b/src/session.c
diff --git a/src/shared/netlink.c b/src/shared/netlink.c
index b32ab854..b32ab854 100644..100755
--- a/src/shared/netlink.c
+++ b/src/shared/netlink.c
diff --git a/src/shared/netlink.h b/src/shared/netlink.h
index 62bb3e01..62bb3e01 100644..100755
--- a/src/shared/netlink.h
+++ b/src/shared/netlink.h
diff --git a/src/shared/util.c b/src/shared/util.c
index df045c5b..df045c5b 100644..100755
--- a/src/shared/util.c
+++ b/src/shared/util.c
diff --git a/src/shared/util.h b/src/shared/util.h
index 293fb3a4..293fb3a4 100644..100755
--- a/src/shared/util.h
+++ b/src/shared/util.h
diff --git a/src/stats.c b/src/stats.c
index 663bc382..663bc382 100644..100755
--- a/src/stats.c
+++ b/src/stats.c
diff --git a/src/storage.c b/src/storage.c
index 5e877ef1..50c8e955 100644..100755
--- a/src/storage.c
+++ b/src/storage.c
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -71,6 +72,19 @@ static int storage_save(GKeyFile *keyfile, char *pathname)
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;
diff --git a/src/task.c b/src/task.c
index 953cc409..953cc409 100644..100755
--- a/src/task.c
+++ b/src/task.c
diff --git a/src/technology.c b/src/technology.c
index d2f0ae2b..5aea9f4f 100644..100755
--- a/src/technology.c
+++ b/src/technology.c
@@ -43,6 +43,16 @@ static GHashTable *rfkill_list;
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;
@@ -66,6 +76,7 @@ struct connman_technology {
*/
char *tethering_ident;
char *tethering_passphrase;
+ bool tethering_hidden;
bool enable_persistent; /* Save the tech state */
@@ -180,6 +191,9 @@ static void technology_save(struct connman_technology *technology)
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",
@@ -253,8 +267,7 @@ static int set_tethering(struct connman_technology *technology,
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;
@@ -546,6 +559,11 @@ static void append_properties(DBusMessageIter *iter,
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);
}
@@ -682,6 +700,10 @@ static void powered_changed(struct connman_technology *technology)
__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);
@@ -882,6 +904,21 @@ static DBusMessage *set_property(DBusConnection *conn,
DBG("property %s", name);
+ if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && technology->connected) {
+ uid_t uid;
+ if (connman_dbus_get_connection_unix_user_sync(conn,
+ dbus_message_get_sender(msg),
+ &uid) < 0) {
+ DBG("Can not get unix user id!");
+ return __connman_error_permission_denied(msg);
+ }
+
+ if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
+ DBG("Not allow this user to operate wifi technology now!");
+ return __connman_error_permission_denied(msg);
+ }
+ }
+
if (g_str_equal(name, "Tethering")) {
dbus_bool_t tethering;
int err;
@@ -958,6 +995,25 @@ static DBusMessage *set_property(DBusConnection *conn,
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;
@@ -997,9 +1053,38 @@ static void reply_scan_pending(struct connman_technology *technology, int err)
}
}
+#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,
@@ -1029,8 +1114,32 @@ 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,
@@ -1082,16 +1191,156 @@ static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
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}" }),
@@ -1100,12 +1349,28 @@ static const GDBusMethodTable technology_methods[] = {
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" })) },
{ },
};
@@ -1227,6 +1492,7 @@ static struct connman_technology *technology_get(enum connman_service_type type)
technology->refcount = 1;
technology->type = type;
+ technology->tethering_hidden = FALSE;
technology->path = g_strdup_printf("%s/technology/%s",
CONNMAN_PATH, str);
@@ -1532,12 +1798,13 @@ int __connman_technology_enabled(enum connman_service_type type)
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);
}
@@ -1550,10 +1817,10 @@ int __connman_technology_disabled(enum connman_service_type type)
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;
@@ -1732,6 +1999,10 @@ int __connman_technology_add_rfkill(unsigned int index,
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)
@@ -1739,11 +2010,12 @@ done:
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;
diff --git a/src/tethering.c b/src/tethering.c
index c929ba71..891ee51f 100644..100755
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -52,6 +52,9 @@
#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;
@@ -60,6 +63,7 @@ static GDHCPServer *tethering_dhcp_server = 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;
@@ -76,6 +80,164 @@ struct connman_private_network {
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;
@@ -161,6 +323,9 @@ static GDHCPServer *dhcp_server_start(const char *bridge,
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;
@@ -538,6 +703,9 @@ int __connman_tethering_init(void)
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;
}
@@ -558,5 +726,7 @@ void __connman_tethering_cleanup(void)
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);
}
diff --git a/src/timeserver.c b/src/timeserver.c
index 0e555a73..6325eceb 100644..100755
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -88,6 +88,15 @@ static void resolv_result(GResolvResultStatus status, char **results,
{
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) {
@@ -148,8 +157,13 @@ void __connman_timeserver_sync_next()
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;
}
diff --git a/src/timezone.c b/src/timezone.c
index e346b11a..e346b11a 100644..100755
--- a/src/timezone.c
+++ b/src/timezone.c
diff --git a/src/util.c b/src/util.c
index 732d4512..732d4512 100644..100755
--- a/src/util.c
+++ b/src/util.c
diff --git a/src/utsname.c b/src/utsname.c
index 1dd5e0f2..1dd5e0f2 100644..100755
--- a/src/utsname.c
+++ b/src/utsname.c
diff --git a/src/wispr.c b/src/wispr.c
index 03b38bb8..adf62303 100644..100755
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -879,7 +879,9 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
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) {
@@ -925,6 +927,11 @@ int __connman_wispr_start(struct connman_service *service,
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;
diff --git a/src/wpad.c b/src/wpad.c
index f066feee..b7f1f1e5 100644..100755
--- a/src/wpad.c
+++ b/src/wpad.c
@@ -161,7 +161,9 @@ int __connman_wpad_start(struct connman_service *service)
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++)
diff --git a/test/enable-tethering b/test/enable-tethering
index cbcd4e72..674b3c91 100755
--- a/test/enable-tethering
+++ b/test/enable-tethering
@@ -3,8 +3,17 @@
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])
@@ -15,7 +24,7 @@ bus = dbus.SystemBus()
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")
@@ -27,9 +36,17 @@ def technology_enable_tethering(path, tech_type, ssid, psk):
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))
@@ -41,11 +58,14 @@ technologies = manager.GetTechnologies()
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;
diff --git a/test/set-timezone b/test/set-timezone
deleted file mode 100755
index dfc1c981..00000000
--- a/test/set-timezone
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/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
diff --git a/tools/dbus-test.c b/tools/dbus-test.c
index ece5d193..ece5d193 100644..100755
--- a/tools/dbus-test.c
+++ b/tools/dbus-test.c
diff --git a/tools/dhcp-server-test.c b/tools/dhcp-server-test.c
index b7d2e540..b7d2e540 100644..100755
--- a/tools/dhcp-server-test.c
+++ b/tools/dhcp-server-test.c
diff --git a/tools/dhcp-test.c b/tools/dhcp-test.c
index c34e10a8..c34e10a8 100644..100755
--- a/tools/dhcp-test.c
+++ b/tools/dhcp-test.c
diff --git a/tools/dnsproxy-test.c b/tools/dnsproxy-test.c
index 551cae91..551cae91 100644..100755
--- a/tools/dnsproxy-test.c
+++ b/tools/dnsproxy-test.c
diff --git a/tools/iptables-test.c b/tools/iptables-test.c
index 2df53ccd..2df53ccd 100644..100755
--- a/tools/iptables-test.c
+++ b/tools/iptables-test.c
diff --git a/tools/iptables-unit.c b/tools/iptables-unit.c
index 426631a0..426631a0 100644..100755
--- a/tools/iptables-unit.c
+++ b/tools/iptables-unit.c
diff --git a/tools/manager-api.c b/tools/manager-api.c
index e082962d..e082962d 100644..100755
--- a/tools/manager-api.c
+++ b/tools/manager-api.c
diff --git a/tools/netlink-test.c b/tools/netlink-test.c
index 221e3490..221e3490 100644..100755
--- a/tools/netlink-test.c
+++ b/tools/netlink-test.c
diff --git a/tools/polkit-test.c b/tools/polkit-test.c
index ea1d24ae..ea1d24ae 100644..100755
--- a/tools/polkit-test.c
+++ b/tools/polkit-test.c
diff --git a/tools/private-network-test.c b/tools/private-network-test.c
index 3dd115ba..3dd115ba 100644..100755
--- a/tools/private-network-test.c
+++ b/tools/private-network-test.c
diff --git a/tools/resolv-test.c b/tools/resolv-test.c
index 8953acd3..8953acd3 100644..100755
--- a/tools/resolv-test.c
+++ b/tools/resolv-test.c
diff --git a/tools/session-api.c b/tools/session-api.c
index b97cfc01..b97cfc01 100644..100755
--- a/tools/session-api.c
+++ b/tools/session-api.c
diff --git a/tools/session-test.c b/tools/session-test.c
index 4319e5a4..4319e5a4 100644..100755
--- a/tools/session-test.c
+++ b/tools/session-test.c
diff --git a/tools/session-test.h b/tools/session-test.h
index 85129337..85129337 100644..100755
--- a/tools/session-test.h
+++ b/tools/session-test.h
diff --git a/tools/session-utils.c b/tools/session-utils.c
index 51cec5c3..51cec5c3 100644..100755
--- a/tools/session-utils.c
+++ b/tools/session-utils.c
diff --git a/tools/stats-tool.c b/tools/stats-tool.c
index efa39de2..efa39de2 100644..100755
--- a/tools/stats-tool.c
+++ b/tools/stats-tool.c
diff --git a/tools/supplicant-dbus.c b/tools/supplicant-dbus.c
index d409da2d..d409da2d 100644..100755
--- a/tools/supplicant-dbus.c
+++ b/tools/supplicant-dbus.c
diff --git a/tools/supplicant-dbus.h b/tools/supplicant-dbus.h
index 4452894b..4452894b 100644..100755
--- a/tools/supplicant-dbus.h
+++ b/tools/supplicant-dbus.h
diff --git a/tools/supplicant-test.c b/tools/supplicant-test.c
index a6408076..a6408076 100644..100755
--- a/tools/supplicant-test.c
+++ b/tools/supplicant-test.c
diff --git a/tools/supplicant.c b/tools/supplicant.c
index e2e6fea5..e2e6fea5 100644..100755
--- a/tools/supplicant.c
+++ b/tools/supplicant.c
diff --git a/tools/supplicant.h b/tools/supplicant.h
index 556dc7d9..556dc7d9 100644..100755
--- a/tools/supplicant.h
+++ b/tools/supplicant.h
diff --git a/tools/tap-test.c b/tools/tap-test.c
index fdc098aa..fdc098aa 100644..100755
--- a/tools/tap-test.c
+++ b/tools/tap-test.c
diff --git a/tools/web-test.c b/tools/web-test.c
index 55c58af5..55c58af5 100644..100755
--- a/tools/web-test.c
+++ b/tools/web-test.c
diff --git a/tools/wispr.c b/tools/wispr.c
index d5f9341f..d5f9341f 100644..100755
--- a/tools/wispr.c
+++ b/tools/wispr.c
diff --git a/tools/wpad-test.c b/tools/wpad-test.c
index 2ecbcdae..2ecbcdae 100644..100755
--- a/tools/wpad-test.c
+++ b/tools/wpad-test.c
diff --git a/unit/test-ippool.c b/unit/test-ippool.c
index 17fac9d9..17fac9d9 100644..100755
--- a/unit/test-ippool.c
+++ b/unit/test-ippool.c
diff --git a/vpn/connman-task.te b/vpn/connman-task.te
index dd777107..dd777107 100644..100755
--- a/vpn/connman-task.te
+++ b/vpn/connman-task.te
diff --git a/vpn/connman-vpn.service.in b/vpn/connman-vpn.service.in
index e98fb714..a8f2948f 100644..100755
--- a/vpn/connman-vpn.service.in
+++ b/vpn/connman-vpn.service.in
@@ -1,12 +1,18 @@
[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
diff --git a/vpn/main.c b/vpn/main.c
index ee88aacd..c18fee4f 100644..100755
--- a/vpn/main.c
+++ b/vpn/main.c
@@ -45,6 +45,7 @@
#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;
@@ -52,8 +53,10 @@ static unsigned int __terminated = 0;
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)
@@ -224,6 +227,21 @@ static GOptionEntry options[] = {
{ 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.
@@ -233,6 +251,16 @@ unsigned int connman_timeout_input_request(void)
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;
diff --git a/vpn/net.connman.vpn.service.in b/vpn/net.connman.vpn.service.in
index e473ea9e..8ce55c20 100644..100755
--- a/vpn/net.connman.vpn.service.in
+++ b/vpn/net.connman.vpn.service.in
@@ -1,5 +1,6 @@
[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
diff --git a/vpn/plugins/ipsec.c b/vpn/plugins/ipsec.c
new file mode 100644
index 00000000..36502dde
--- /dev/null
+++ b/vpn/plugins/ipsec.c
@@ -0,0 +1,925 @@
+/*
+ *
+ * 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)
diff --git a/vpn/plugins/ipsec.h b/vpn/plugins/ipsec.h
new file mode 100644
index 00000000..14b9596f
--- /dev/null
+++ b/vpn/plugins/ipsec.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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 */
diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c
index a0d22c4d..a0d22c4d 100644..100755
--- a/vpn/plugins/l2tp.c
+++ b/vpn/plugins/l2tp.c
diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c
index 87679bfa..87679bfa 100644..100755
--- a/vpn/plugins/openconnect.c
+++ b/vpn/plugins/openconnect.c
diff --git a/vpn/plugins/openvpn.c b/vpn/plugins/openvpn.c
index e3395097..d115df6e 100644..100755
--- a/vpn/plugins/openvpn.c
+++ b/vpn/plugins/openvpn.c
@@ -421,8 +421,10 @@ static int ov_connect(struct vpn_provider *provider,
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
diff --git a/vpn/plugins/pptp.c b/vpn/plugins/pptp.c
index 27b1d508..27b1d508 100644..100755
--- a/vpn/plugins/pptp.c
+++ b/vpn/plugins/pptp.c
diff --git a/vpn/plugins/vici-client.c b/vpn/plugins/vici-client.c
new file mode 100644
index 00000000..67e365a5
--- /dev/null
+++ b/vpn/plugins/vici-client.c
@@ -0,0 +1,1290 @@
+/*
+ *
+ * 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;
+}
diff --git a/vpn/plugins/vici-client.h b/vpn/plugins/vici-client.h
new file mode 100644
index 00000000..a33a8e46
--- /dev/null
+++ b/vpn/plugins/vici-client.h
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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 */
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index 9a423850..f6e24c4c 100644..100755
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -336,6 +336,56 @@ static DBusMessage *vpn_notify(struct connman_task *task,
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);
@@ -487,6 +537,12 @@ static int vpn_connect(struct vpn_provider *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);
diff --git a/vpn/plugins/vpn.h b/vpn/plugins/vpn.h
index cb94bdcd..1888d5ff 100644..100755
--- a/vpn/plugins/vpn.h
+++ b/vpn/plugins/vpn.h
@@ -40,9 +40,16 @@ enum vpn_state {
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,
diff --git a/vpn/plugins/vpnc.c b/vpn/plugins/vpnc.c
index af9dbe76..af9dbe76 100644..100755
--- a/vpn/plugins/vpnc.c
+++ b/vpn/plugins/vpnc.c
diff --git a/vpn/vpn-agent.c b/vpn/vpn-agent.c
index b0b582b7..b0b582b7 100644..100755
--- a/vpn/vpn-agent.c
+++ b/vpn/vpn-agent.c
diff --git a/vpn/vpn-agent.h b/vpn/vpn-agent.h
index c7328d7f..c7328d7f 100644..100755
--- a/vpn/vpn-agent.h
+++ b/vpn/vpn-agent.h
diff --git a/vpn/vpn-config.c b/vpn/vpn-config.c
index c88a99ab..5f0e749a 100644..100755
--- a/vpn/vpn-config.c
+++ b/vpn/vpn-config.c
@@ -203,7 +203,11 @@ static int load_provider(GKeyFile *keyfile, const char *group,
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 */
@@ -229,8 +233,14 @@ static int load_provider(GKeyFile *keyfile, const char *group,
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);
@@ -252,7 +262,11 @@ static int load_provider(GKeyFile *keyfile, const char *group,
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;
}
diff --git a/vpn/vpn-dbus.conf b/vpn/vpn-dbus.conf
index 0f0c8da4..7b7b6d19 100644..100755
--- a/vpn/vpn-dbus.conf
+++ b/vpn/vpn-dbus.conf
@@ -4,7 +4,12 @@
<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"/>
diff --git a/vpn/vpn-ipconfig.c b/vpn/vpn-ipconfig.c
index c096fa37..c096fa37 100644..100755
--- a/vpn/vpn-ipconfig.c
+++ b/vpn/vpn-ipconfig.c
diff --git a/vpn/vpn-manager.c b/vpn/vpn-manager.c
index 021d625f..021d625f 100644..100755
--- a/vpn/vpn-manager.c
+++ b/vpn/vpn-manager.c
diff --git a/vpn/vpn-polkit.conf b/vpn/vpn-polkit.conf
index a1dc6177..237d21be 100644..100755
--- a/vpn/vpn-polkit.conf
+++ b/vpn/vpn-polkit.conf
@@ -5,6 +5,10 @@
<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>
diff --git a/vpn/vpn-polkit.policy b/vpn/vpn-polkit.policy
index 0c427220..0c427220 100644..100755
--- a/vpn/vpn-polkit.policy
+++ b/vpn/vpn-polkit.policy
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index d2b3e3aa..67239e40 100644..100755
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -1803,6 +1803,7 @@ static void provider_create_all_from_type(const char *provider_type)
g_strfreev(providers);
}
+#if !defined TIZEN_EXT
char *__vpn_provider_create_identifier(const char *host, const char *domain)
{
char *ident;
@@ -1815,6 +1816,20 @@ char *__vpn_provider_create_identifier(const char *host, const char *domain)
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)
{
@@ -1868,7 +1883,11 @@ 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);
@@ -2057,7 +2076,11 @@ int __vpn_provider_create_from_config(GHashTable *settings,
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);
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index bdc5f5c1..bdc5f5c1 100644..100755
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
diff --git a/vpn/vpn-rtnl.c b/vpn/vpn-rtnl.c
index a7565dba..a7565dba 100644..100755
--- a/vpn/vpn-rtnl.c
+++ b/vpn/vpn-rtnl.c
diff --git a/vpn/vpn-rtnl.h b/vpn/vpn-rtnl.h
index aa640a66..aa640a66 100644..100755
--- a/vpn/vpn-rtnl.h
+++ b/vpn/vpn-rtnl.h
diff --git a/vpn/vpn.h b/vpn/vpn.h
index 8bf86bd1..26b13d70 100644..100755
--- a/vpn/vpn.h
+++ b/vpn/vpn.h
@@ -71,8 +71,11 @@ int __vpn_ipconfig_init(void);
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,
diff --git a/vpn/vpn.ver b/vpn/vpn.ver
index b8877064..b8877064 100644..100755
--- a/vpn/vpn.ver
+++ b/vpn/vpn.ver