Updated connman to version 1.35 94/166794/2
authorSeonah Moon <seonah1.moon@samsung.com>
Tue, 23 Jan 2018 05:50:50 +0000 (14:50 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Tue, 23 Jan 2018 05:50:55 +0000 (14:50 +0900)
Change-Id: I13526fbf80296a79be15548fc226a308941ac9ec
Signed-off-by: Taesub Kim <taesub.kim@samsung.com>
104 files changed:
1  2 
AUTHORS
Makefile.am
Makefile.plugins
README
TODO
client/commands.c
client/dbus_helpers.c
client/input.c
configure.ac
doc/agent-api.txt
doc/config-format.txt
doc/connman.conf.5.in
doc/overview-api.txt
doc/plugin-api.txt
doc/service-api.txt
doc/session-api.txt
doc/session-overview.txt
doc/technology-api.txt
doc/vpn-config-format.txt
doc/vpn-connection-api.txt
gdbus/client.c
gdbus/gdbus.h
gdbus/object.c
gdhcp/client.c
gdhcp/common.c
gdhcp/gdhcp.h
gdhcp/ipv4ll.c
gdhcp/server.c
gsupplicant/gsupplicant.h
gsupplicant/supplicant.c
gweb/gresolv.c
gweb/gweb.c
include/device.h
include/network.h
include/provider.h
include/service.h
include/session.h
include/technology.h
packaging/connman.spec
plugins/bluetooth.c
plugins/ethernet.c
plugins/gadget.c
plugins/neard.c
plugins/ofono.c
plugins/pacrunner.c
plugins/session_policy_local.c
plugins/vpn.c
plugins/wifi.c
scripts/connman.in
src/6to4.c
src/agent-connman.c
src/agent.c
src/bridge.c
src/config.c
src/connection.c
src/connman.h
src/device.c
src/dhcp.c
src/dhcpv6.c
src/dnsproxy.c
src/inet.c
src/ipconfig.c
src/ippool.c
src/iptables.c
src/log.c
src/main.c
src/main.conf
src/nat.c
src/network.c
src/ntp.c
src/peer.c
src/peer_service.c
src/provider.c
src/proxy.c
src/resolver.c
src/rfkill.c
src/rtnl.c
src/service.c
src/session.c
src/stats.c
src/storage.c
src/task.c
src/technology.c
src/tethering.c
src/timeserver.c
src/util.c
src/wispr.c
src/wpad.c
tools/iptables-unit.c
tools/session-test.h
tools/stats-tool.c
unit/test-ippool.c
vpn/connman-vpn.service.in
vpn/main.c
vpn/plugins/l2tp.c
vpn/plugins/openconnect.c
vpn/plugins/openvpn.c
vpn/plugins/pptp.c
vpn/plugins/vpn.c
vpn/plugins/vpn.h
vpn/plugins/vpnc.c
vpn/vpn-config.c
vpn/vpn-provider.c
vpn/vpn-provider.h

diff --combined AUTHORS
index 9f807f9,44c65f8..44c65f8
mode 100755,100644..100755
+++ b/AUTHORS
@@@ -90,3 -90,44 +90,44 @@@ Andreas Oberritter <obi@opendreambox.or
  Arman Uguray <armansito@chromium.org>
  Vinicius Costa Gomes <vcgomes@gmail.com>
  Marcus Folkesson <marcus.folkesson@gmail.com>
+ Michael Olbrich <m.olbrich@pengutronix.de>
+ Harish Jenny K N <harish_kandiga@mentor.com>
+ Jaakko Hannikainen <jaakko.hannikainen@intel.com>
+ Adam Moore <adam.moore@savantsystems.com>
+ Marko Sulejic <marko.sulejic@hale.at>
+ Marcin Niestrój <m.niestroj@grinn-global.com>
+ Frank Stevers <f.stevers@ultimaker.com>
+ Laurent Vaudoit <laurent.vaudoit@gmail.com>
+ Abtin Keshavarzian <abtink@nestlabs.com>
+ Naveen Singh <naveensingh0977@gmail.com>
+ Mylène Josserand <josserand.mylene@gmail.com>
+ John Ernberg <john.ernberg@actia.se>
+ Niraj Kumar Goit <niraj.g@samsung.com>
+ Wu Zheng <wu.zheng@intel.com>
+ Milind Ramesh Murhekar <m.murhekar@samsung.com>
+ Nishant Chaprana <n.chaprana@samsung.com>
+ Hendrik Donner <hendrik@rennod.org>
+ Ravi Prasad RK <ravi.rk@samsung.com>
+ Krisztian Litkey <kli@iki.fi>
+ Jose Blanquicet <blanquicet@gmail.com>
+ Frédéric Dalleau <frederic.dalleau@collabora.co.uk>
+ Yusuke Nakamura <yusuke1653381@gmail.com>
+ Maxime Chevallier <maxime.chevallier@smile.fr>
+ Sam Nazarko <email@samnazarko.co.uk>
+ Kristian Klausen <klausenbusk@hotmail.com>
+ MÃ¥ns RullgÃ¥rd <mans@mansr.com>
+ Michele Dionisio <michele.dionisio@gmail.com>
+ Alexander Kochetkov <al.kochet@gmail.com>
+ Ioan-Adrian Ratiu <adrian.ratiu@ni.com>
+ Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+ Bernhard Lichtinger <bernhard.lichtinger@lrz.de>
+ Andreas Smas <andreas@lonelycoder.com>
+ Ingo Albrecht <randomice@quantentunnel.de>
+ Scott Valentine <svalentine@ikayzo.com>
+ Craig McQueen <craig.mcqueen@innerrange.com>
+ Tobias Klauser <tklauser@distanz.ch>
+ Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+ Bjoern Thorwirth <external.bjoern.thorwirth@de.bosch.com>
+ Maxin B. John <maxin.john@intel.com>
+ Heghedus Razvan <razvan.heghedus@ni.com>
+ Guillaume Deroire <guillaume.deroire@hach.com>
diff --combined Makefile.am
index 82c13dd,e67a7a5..76c5419
mode 100755,100644..100755
@@@ -19,7 -19,8 +19,7 @@@ noinst_HEADERS = include/rtnl.h include
                        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)))
@@@ -42,6 -43,10 +42,6 @@@ els
  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
  
@@@ -59,30 -64,29 +59,30 @@@ if VP
  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 =
  
@@@ -94,23 -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 =
  
- sbin_PROGRAMS = src/connmand
 +if TIZEN_EXT
 +sbin_PROGRAMS =
 +else
+ sbin_PROGRAMS = src/connmand src/connmand-wait-online
 +endif
  
 -src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) $(backtrace_sources) \
 +src_connmand_SOURCES = $(gdhcp_sources) $(gweb_sources) \
                        $(builtin_sources) $(shared_sources) src/connman.ver \
                        src/main.c src/connman.h src/log.c \
                        src/error.c src/plugin.c src/task.c \
                        src/storage.c src/dbus.c src/config.c \
                        src/technology.c src/counter.c src/ntp.c \
                        src/session.c src/tethering.c src/wpad.c src/wispr.c \
-                       src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
+                       src/stats.c src/dnsproxy.c src/6to4.c \
                        src/ippool.c src/bridge.c src/nat.c src/ipaddress.c \
-                       src/inotify.c src/firewall.c src/ipv6pd.c src/peer.c \
+                       src/inotify.c src/ipv6pd.c src/peer.c \
                        src/peer_service.c src/machine.c src/util.c
  
  src_connmand_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
-                       @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ @GNUTLS_LIBS@ @LIBSYSTEMD_LIBS@ \
 -                      @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ \
++                      @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ @LIBSYSTEMD_LIBS@ \
                        -lresolv -ldl -lrt
  
 -src_connmand_LDFLAGS = -Wl,--export-dynamic \
 +src_connmand_LDFLAGS = -Wl,--export-dynamic -pie \
                                -Wl,--version-script=$(srcdir)/src/connman.ver
  
+ src_connmand_wait_online_SOURCES = src/connmand-wait-online.c
+ src_connmand_wait_online_LDADD = gdbus/libgdbus-internal.la \
+                       @GLIB_LIBS@ @DBUS_LIBS@
+ if XTABLES
+ src_connmand_SOURCES += src/iptables.c src/firewall-iptables.c
+ src_connmand_LDADD += @XTABLES_LIBS@
+ endif
+ if NFTABLES
+ src_connmand_SOURCES += src/firewall-nftables.c
+ src_connmand_LDADD +=  @NFTABLES_LIBS@
+ endif
  if VPN
  vpn_plugin_LTLIBRARIES =
  
@@@ -146,45 -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.c src/ipv6pd.c src/peer.c \
++                      src/inotify.c src/firewall-iptables.c src/ipv6pd.c src/peer.c \
 +                      src/peer_service.c src/machine.c src/util.c \
 +                      vpn/vpn-agent.c vpn/vpn-agent.h \
                        vpn/vpn-config.c
  
  vpn_connman_vpnd_LDADD = gdbus/libgdbus-internal.la $(builtin_vpn_libadd) \
 -                              @GLIB_LIBS@ @DBUS_LIBS@ @GNUTLS_LIBS@ \
 +                              @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ @GNUTLS_LIBS@ \
 +                              @LIBSYSTEMD_LIBS@ \
                                -lresolv -ldl
  
  vpn_connman_vpnd_LDFLAGS = -Wl,--export-dynamic \
                                -Wl,--version-script=$(srcdir)/vpn/vpn.ver
  endif
  
 -BUILT_SOURCES = $(local_headers) src/builtin.h $(service_files) \
 -      scripts/connman scripts/connman_resolvconf.conf
 +BUILT_SOURCES = $(local_headers) src/builtin.h $(service_files) scripts/connman
  
  if VPN
  BUILT_SOURCES += vpn/builtin.h
@@@ -192,8 -186,8 +207,8 @@@ endi
  
  CLEANFILES = src/connman.conf $(BUILT_SOURCES) $(service_files)
  
- statedir = $(localstatedir)/run/connman
- vpn_statedir = $(localstatedir)/run/connman-vpn
+ statedir = $(runstatedir)/connman
+ vpn_statedir = $(runstatedir)/connman-vpn
  
  if VPN
  vpn_plugindir = $(libdir)/connman/plugins-vpn
@@@ -222,7 -216,7 +237,7 @@@ build_vpn_plugindir = $(vpn_plugindir
  endif
  endif
  
- AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ @LIBSYSTEMD_CFLAGS@\
 -AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
++AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @LIBSYSTEMD_CFLAGS@\
                                @GNUTLS_CFLAGS@ $(builtin_cflags) \
                                -DCONNMAN_PLUGIN_BUILTIN \
                                -DSTATEDIR=\""$(statedir)"\" \
                                -DSCRIPTDIR=\""$(build_scriptdir)"\" \
                                -DSTORAGEDIR=\""$(storagedir)\"" \
                                -DVPN_STORAGEDIR=\""$(vpn_storagedir)\"" \
 -                              -DCONFIGDIR=\""$(configdir)\""
 +                              -DCONFIGDIR=\""$(configdir)\"" \
 +                              -fPIE
  
  if VPN
  AM_CPPFLAGS = -I$(builddir)/include -I$(srcdir)/gdbus
@@@ -240,7 -233,7 +255,7 @@@ els
  AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/gdbus
  endif
  
- src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
+ src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
                                @GNUTLS_CFLAGS@ $(builtin_cflags) \
                                -DCONNMAN_PLUGIN_BUILTIN \
                                -DSTATEDIR=\""$(statedir)"\" \
@@@ -256,7 -249,7 +271,7 @@@ EXTRA_DIST = src/genbuiltin src/connman
                                $(service_files_sources) scripts/connman.in
  
  if VPN
 -vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \
 +vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
                                $(builtin_vpn_cflags) \
                                -DCONNMAN_PLUGIN_BUILTIN \
                                -DVPN_STATEDIR=\""$(vpn_statedir)"\" \
  
  endif
  
+ if XTABLES
+ AM_CFLAGS += @XTABLES_CFLAGS@
+ src_connmand_CFLAGS += @XTABLES_CFLAGS@
+ endif
+ if NFTABLES
+ AM_CFLAGS += @NFTABLES_CFLAGS@
+ src_connmand_CFLAGS += @NFTABLES_CFLAGS@
+ endif
  EXTRA_DIST += vpn/vpn-dbus.conf vpn/vpn-polkit.conf
  
  script_DATA =
@@@ -280,8 -283,6 +305,6 @@@ include Makefile.plugin
  if CLIENT
  bin_PROGRAMS += client/connmanctl
  
- #MANUAL_PAGES = doc/connmanctl.1
  client_connmanctl_SOURCES = client/dbus_helpers.h client/dbus_helpers.c \
                        client/services.h client/services.c \
                        client/commands.h client/commands.c \
                        client/main.c
  
  client_connmanctl_LDADD = gdbus/libgdbus-internal.la @DBUS_LIBS@ @GLIB_LIBS@ \
 -                              -lreadline -ldl
 +                              -lreadline -ldl -lncurses
  endif
  
  noinst_PROGRAMS += unit/test-ippool
  
 -unit_test_ippool_SOURCES = $(backtrace_sources) src/log.c src/dbus.c \
 -                                      src/error.c src/ippool.c unit/test-ippool.c
 +unit_test_ippool_SOURCES = src/log.c src/dbus.c src/error.c \
 +                                      src/ippool.c unit/test-ippool.c
  unit_test_ippool_LDADD = gdbus/libgdbus-internal.la \
                                @GLIB_LIBS@ @DBUS_LIBS@ -ldl
  
@@@ -316,9 -317,9 +339,9 @@@ noinst_PROGRAMS += tools/supplicant-tes
                        tools/dhcp-test tools/dhcp-server-test \
                        tools/addr-test tools/web-test tools/resolv-test \
                        tools/dbus-test tools/polkit-test \
-                       tools/iptables-test tools/tap-test tools/wpad-test \
+                       tools/tap-test tools/wpad-test \
                        tools/stats-tool tools/private-network-test \
-                       tools/session-test tools/iptables-unit \
+                       tools/session-test \
                        tools/dnsproxy-test tools/netlink-test
  
  tools_supplicant_test_SOURCES = tools/supplicant-test.c \
@@@ -349,28 -350,34 +372,34 @@@ tools_dbus_test_LDADD = gdbus/libgdbus-
  
  tools_polkit_test_LDADD = @DBUS_LIBS@
  
- tools_iptables_test_SOURCES = src/log.c src/iptables.c tools/iptables-test.c
- tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl
  tools_private_network_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
  
 -tools_session_test_SOURCES = $(backtrace_sources) src/log.c src/dbus.c src/error.c \
 +tools_session_test_SOURCES = src/log.c src/dbus.c src/error.c \
                tools/session-test.c tools/session-utils.c tools/manager-api.c \
                tools/session-api.c tools/session-test.h
  tools_session_test_LDADD = gdbus/libgdbus-internal.la \
                                @GLIB_LIBS@ @DBUS_LIBS@ -ldl
  
+ if XTABLES
+ noinst_PROGRAMS += tools/iptables-test tools/iptables-unit
+ tools_iptables_test_SOURCES = $(backtrace_sources) src/log.c src/iptables.c \
+                               tools/iptables-test.c
+ tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl
  tools_iptables_unit_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
                -DIPTABLES_SAVE=\""${IPTABLES_SAVE}"\"
 -tools_iptables_unit_SOURCES = $(backtrace_sources) src/log.c \
 +tools_iptables_unit_SOURCES = src/log.c \
-                src/iptables.c src/firewall.c src/nat.c tools/iptables-unit.c
+               src/iptables.c src/firewall-iptables.c src/nat.c \
+               tools/iptables-unit.c
  tools_iptables_unit_LDADD = gdbus/libgdbus-internal.la \
                                @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ -ldl
+ endif
  
  tools_dnsproxy_test_SOURCES = tools/dnsproxy-test.c
  tools_dnsproxy_test_LDADD = @GLIB_LIBS@
  
- tools_netlink_test_SOURCES =$(shared_sources) tools/netlink-test.c
+ tools_netlink_test_SOURCES = $(shared_sources) tools/netlink-test.c
  tools_netlink_test_LDADD = @GLIB_LIBS@
  
  endif
@@@ -412,14 -419,23 +441,22 @@@ EXTRA_DIST += doc/overview-api.txt doc/
                                doc/vpn-config-format.txt \
                                doc/vpn-connection-api.txt \
                                doc/vpn-manager-api.txt doc/vpn-overview.txt \
-                               doc/session-policy-format.txt
+                               doc/session-policy-format.txt \
+                               doc/connmanctl.1.in doc/connman.conf.5.in \
+                               doc/connman-service.config.5.in \
+                               doc/connman-vpn.conf.5.in \
+                               doc/connman-vpn-provider.config.5.in \
+                               doc/connman.8.in doc/connman-vpn.8.in
  
  EXTRA_DIST += src/main.conf \
 -              src/eduroam.config \
 -              scripts/connman_resolvconf.conf.in
 +              src/eduroam.config
  
- #MANUAL_PAGES += doc/connman.8 doc/connman.conf.5
 -MANUAL_PAGES += doc/connmanctl.1 doc/connman.conf.5 \
 -              doc/connman-service.config.5 doc/connman-vpn.conf.5 \
 -              doc/connman-vpn-provider.config.5 \
 -              doc/connman.8 doc/connman-vpn.8
++#MANUAL_PAGES += doc/connmanctl.1 doc/connman.conf.5 \
++#             doc/connman-service.config.5 doc/connman-vpn.conf.5 \
++#             doc/connman-vpn-provider.config.5 \
++#             doc/connman.8 doc/connman-vpn.8
  
- dist_man_MANS = $(MANUAL_PAGES)
nodist_man_MANS = $(MANUAL_PAGES)
  
  pkgconfigdir = $(libdir)/pkgconfig
  
@@@ -429,7 -445,6 +466,7 @@@ DISTCHECK_CONFIGURE_FLAGS = --disable-d
                                --enable-hh2serial-gps \
                                --enable-openconnect \
                                --enable-openvpn \
 +                              --enable-ipsec \
                                --enable-vpnc \
                                --enable-session-policy-local \
                                --enable-nmcompat \
@@@ -443,9 -458,11 +480,11 @@@ MAINTAINERCLEANFILES = Makefile.in 
  
  
  src/builtin.h: src/genbuiltin $(builtin_sources)
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
        $(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
  
  vpn/builtin.h: src/genbuiltin $(builtin_vpn_sources)
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
        $(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_vpn_modules) > $@
  
  src/connman.conf: src/connman-dbus.conf src/connman-polkit.conf
@@@ -462,6 -479,7 +501,7 @@@ if POLKI
  else
        $(AM_V_GEN)cp $(srcdir)/vpn/vpn-dbus.conf $@
  endif
+ CLEANFILES += vpn/connman-vpn-dbus.conf
  endif
  
  if SELINUX
@@@ -479,14 -497,36 +519,31 @@@ EXTRA_DIST += vpn/connman-task.t
  do_subst = $(AM_V_GEN)$(SED) \
                -e 's,[@]prefix[@],$(prefix),g' \
                -e 's,[@]sbindir[@],$(sbindir),g' \
-               -e 's,[@]sysconfdir[@],$(sysconfdir),g'
+               -e 's,[@]sysconfdir[@],$(sysconfdir),g' \
+               -e 's,[@]storagedir[@],$(storagedir),g' \
+               -e 's,[@]vpn_storagedir[@],$(vpn_storagedir),g' \
 -              -e 's,[@]localstatedir[@],$(localstatedir),g' \
 -              -e 's,[@]runstatedir[@],$(runstatedir),g'
++              -e 's,[@]localstatedir[@],$(localstatedir),g'
+ %.1 : %.1.in
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(do_subst) < $< > $@
+ %.5 : %.5.in
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(do_subst) < $< > $@
+ %.8 : %.8.in
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(do_subst) < $< > $@
  
  %.service: %.service.in Makefile
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
        $(do_subst) < $< > $@
  
  scripts/connman: scripts/connman.in Makefile
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
        $(do_subst) < $< > $@
  
 -scripts/connman_resolvconf.conf: scripts/connman_resolvconf.conf.in
 -      $(AM_V_at)$(MKDIR_P) $(dir $@)
 -      $(do_subst) < $< > $@
 -
  include/connman/version.h: include/version.h
        $(AM_V_at)$(MKDIR_P) include/connman
        $(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@
@@@ -496,4 -536,4 +553,4 @@@ include/connman/%.h: $(abs_top_srcdir)/
        $(AM_V_GEN)$(LN_S) $< $@
  
  clean-local:
-       @$(RM) -rf include/connman
+       @$(RM) -rf include/connman $(MANUAL_PAGES)
diff --combined Makefile.plugins
index cc732d9,dce8b28..1eb0c3f
mode 100755,100644..100755
@@@ -26,9 -26,12 +26,12 @@@ builtin_modules += wif
  builtin_sources += plugins/wifi.c $(gsupplicant_sources)
  endif
  
+ if IWD
+ builtin_modules += iwd
+ builtin_sources += plugins/iwd.c
+ endif
  if BLUETOOTH
- builtin_modules += bluetooth_legacy
- builtin_sources += plugins/bluetooth_legacy.c
  builtin_modules += bluetooth
  builtin_sources += plugins/bluetooth.c
  endif
@@@ -55,18 -58,6 +58,18 @@@ builtin_modules += dunde
  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
@@@ -108,25 -99,6 +111,25 @@@ vpn_plugins_openvpn_la_LDFLAGS = $(plug
  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
@@@ -244,12 -216,6 +247,12 @@@ script_PROGRAMS += scripts/openvpn-scri
  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 --combined README
index 531f396,cff3131..cff3131
mode 100755,100644..100755
--- 1/README
--- 2/README
+++ b/README
@@@ -131,6 -131,15 +131,15 @@@ For a working system, certain configura
                detected and only a runtime dependency. It is not needed to
                build ConnMan.
  
+       --enable-iwd
+               Enable support for Wireless daemon for Linux
+               The IWD project does not have initial release so far,
+               therefore by default IWD support is not enabled.
+               It is safe to enable this option along WiFi support.
        --disable-pacrunner
  
                Disable support for PACrunner proxy handling
@@@ -346,6 -355,22 +355,22 @@@ network. While the same setup works wel
  uplink.
  
  
+ GnuTLS
+ ======
+ When using GnuTLS be aware that depending on the configuration of
+ GnuTLS does either an lazy or eager initialization of an internal
+ entropy pool using /dev/urandom. On eager initialization the loading
+ of ConnMan will be delayed by the link loader until the entropy pool
+ is filled. On smaller system this can easily delay the startup of
+ ConnMan by several seconds (we had reports of 25 seconds and more
+ delay).
+ GnuTLS allows to switch back to lazy evaluation when the environment
+ variable GNUTLS_NO_EXPLICIT_INIT. For more details please read
+ the man page to gnutls_global_init(3).
  Online check
  ============
  
@@@ -360,11 -385,17 +385,17 @@@ from ipv4.connman.net (for IPv4 connect
  (for IPv6 connectivity). The used URL looks like this
  http://ipv{4|6}.connman.net/online/status.html
  
+ See connman.conf(5) for the EnableOnlineCheck option, if you need to
+ disable the feature.
  During the online check procedure, ConnMan will temporarily install
  a host route to both the ipv4.connman.net and ipv6.connman.net so that
  the online check query can be directed via the correct network
  interface which the connected service is using. This host route is
- automatically removed when the online check is done.
+ automatically removed when the online check is done. Note that the server
+ expressly does not log any connection information, including IPv4/6
+ addresses of connecting clients. The server runtime logs cycle in RAM
+ memory depending on amount of connections processed.
  
  ConnMan sends this very minimal information in http header when doing
  the online check request (example):
diff --combined TODO
index dac2ea2,c1694e3..c1694e3
mode 100755,100644..100755
--- 1/TODO
--- 2/TODO
+++ b/TODO
@@@ -85,17 -85,6 +85,6 @@@ Cor
     utilize the information already provided by netlink in src/device.c.
  
  
- - Simplify gateway selection code
-    Priority: Low
-    Complexity: C4
-    The service list is always sorted according to preference with the
-    first service always owning the default route. See if update_order and
-    find_default_gateway in src/connection.c can be modified to use the
-    sorted service list instead of walking through the gateway_hash.
  - Support D-Bus ObjectManager
  
     Priority: Medium
     ObjectManager common to Linux desktops can be implemented.
  
  
+ Tethering
+ =========
+ - Verify if bridge has been correctly created and configured
+    Priority: Low
+    Complexity: C1
+    When enabling tethering check if there was any error while creating and
+    configuring the bridge before continue. It has been done only for WiFi
+    technology, for other tethering technologies it should be evaluated
+    and implemented in case it is advantageous.
  WiFi
  ====
  
    wifi's technology set_regdom implementation. Removing autoscan fallback.
    (Note: should be done around the end 2012)
  
  Bluetooth
  =========
  
- - Remove Bluez 4.x support
-   Priority: Low
-   Complexity: C1
-   Remove plugins/bluetooth-legacy.c support in about 6 month (July 2013) or
-   when Bluez 4.x usage becomes minimal.
  
  Cellular
  ========
@@@ -200,23 -197,9 +197,9 @@@ VP
  Tools
  =====
  
- - Add Clock API and MoveBefore/MoveAfter support to connmanctl
+ - Add Clock API support to connmanctl
  
     Priority: Low
     Complexity: C2
  
-    The connmanctl command line tool should support Clock API and Service API
-    MoveBefore/MoveAfter.
- User Interface
- ==============
- - GNOME3 UI
-    Priority: Low
-    Complexity: C4
-    A GNOME3 shell user interface would make it easier for mainstream distros
-    users to use ConnMan. Continue/restart the work at
-    https://github.com/connectivity/gnome-extension-connman
+    The connmanctl command line tool should support Clock API.
diff --combined client/commands.c
index 3f7e001,583095b..746e158
mode 100755,100644..100755
@@@ -46,6 -46,7 +46,7 @@@
  
  static DBusConnection *connection;
  static GHashTable *service_hash;
+ static GHashTable *vpnconnection_hash;
  static GHashTable *peer_hash;
  static GHashTable *technology_hash;
  static char *session_notify_path;
@@@ -265,6 -266,33 +266,33 @@@ static int cmd_state(char *args[], int 
                        state_print, NULL, NULL, NULL);
  }
  
+ static int clock_print(DBusMessageIter *iter, const char *error,
+               void *user_data)
+ {
+       DBusMessageIter entry;
+       if (error) {
+               fprintf(stderr, "Error: %s", error);
+               return 0;
+       }
+       dbus_message_iter_recurse(iter, &entry);
+       __connmanctl_dbus_print(&entry, "  ", " = ", "\n");
+       fprintf(stdout, "\n");
+       return 0;
+ }
+ static int cmd_clock(char *args[], int num, struct connman_option *options)
+ {
+       if (num > 1)
+               return -E2BIG;
+       return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+                       CONNMAN_PATH, "net.connman.Clock", "GetProperties",
+                       clock_print, NULL, NULL, NULL);
+ }
  static int services_list(DBusMessageIter *iter, const char *error,
                void *user_data)
  {
@@@ -495,8 -523,13 +523,13 @@@ struct tether_properties 
  
  static int tether_update(struct tether_properties *tether)
  {
-       if (tether->ssid_result == 0 && tether->passphrase_result == 0)
-               return tether_set("wifi", tether->set_tethering);
+       int ret;
+       if (tether->ssid_result == 0 && tether->passphrase_result == 0) {
+               ret = tether_set("wifi", tether->set_tethering);
+               g_free(tether);
+               return ret;
+       }
  
        if (tether->ssid_result != -EINPROGRESS &&
                        tether->passphrase_result != -EINPROGRESS) {
@@@ -725,6 -758,131 +758,131 @@@ static int cmd_disconnect(char *args[]
                                        disconnect_return, path, NULL, NULL);
  }
  
+ struct move_service {
+       char *service;
+       char *target;
+ };
+ static int move_before_return(DBusMessageIter *iter, const char *error,
+               void *user_data)
+ {
+       struct move_service *services = user_data;
+       char *service;
+       char *target;
+       if (!error) {
+               service = strrchr(services->service, '/');
+               service++;
+               target = strrchr(services->target, '/');
+               target++;
+               fprintf(stdout, "Moved %s before %s\n", service, target);
+       } else
+               fprintf(stderr, "Error %s: %s\n", services->service, error);
+       g_free(services->service);
+       g_free(services->target);
+       g_free(user_data);
+       return 0;
+ }
+ static void move_before_append_args(DBusMessageIter *iter, void *user_data)
+ {
+       char *path = user_data;
+       dbus_message_iter_append_basic(iter,
+                               DBUS_TYPE_OBJECT_PATH, &path);
+       return;
+ }
+ static int cmd_service_move_before(char *args[], int num,
+               struct connman_option *options)
+ {
+       const char *iface = "net.connman.Service";
+       struct move_service *services;
+       if (num > 3)
+               return -E2BIG;
+       if (num < 3)
+               return -EINVAL;
+       if (check_dbus_name(args[1]) == false)
+               return -EINVAL;
+       services = g_new(struct move_service, 1);
+       services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
+       services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
+       return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+                                       services->service, iface, "MoveBefore",
+                                       move_before_return, services,
+                                       move_before_append_args,
+                                       services->target);
+ }
+ static int move_after_return(DBusMessageIter *iter, const char *error,
+               void *user_data)
+ {
+       struct move_service *services = user_data;
+       char *service;
+       char *target;
+       if (!error) {
+               service = strrchr(services->service, '/');
+               service++;
+               target = strrchr(services->target, '/');
+               target++;
+               fprintf(stdout, "Moved %s after %s\n", service, target);
+       } else
+               fprintf(stderr, "Error %s: %s\n", services->service, error);
+       g_free(services->service);
+       g_free(services->target);
+       g_free(user_data);
+       return 0;
+ }
+ static void move_after_append_args(DBusMessageIter *iter, void *user_data)
+ {
+       char *path = user_data;
+       dbus_message_iter_append_basic(iter,
+                               DBUS_TYPE_OBJECT_PATH, &path);
+       return;
+ }
+ static int cmd_service_move_after(char *args[], int num,
+               struct connman_option *options)
+ {
+       const char *iface = "net.connman.Service";
+       struct move_service *services;
+       if (num > 3)
+               return -E2BIG;
+       if (num < 3)
+               return -EINVAL;
+       if (check_dbus_name(args[1]) == false)
+               return -EINVAL;
+       services = g_new(struct move_service, 1);
+       services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
+       services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
+       return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+                                       services->service, iface, "MoveAfter",
+                                       move_after_return, services,
+                                       move_after_append_args,
+                                       services->target);
+ }
  static int config_return(DBusMessageIter *iter, const char *error,
                void *user_data)
  {
@@@ -1738,6 -1896,8 +1896,8 @@@ static int session_config(char *args[]
        int index = 0, res = 0;
        struct config_append append;
        char c;
+       char *ifname;
+       dbus_bool_t source_ip_rule;
  
        while (index < num && args[index]) {
                append.opts = &args[index];
                                        DBUS_TYPE_STRING, &args[index + 1]);
                        append.values = 2;
                        break;
+               case 'i':
+                       if (index + 1 < num)
+                               ifname = args[index + 1];
+                       else
+                               ifname = "";
+                       res = __connmanctl_dbus_session_change(connection,
+                                       session_path, session_config_return,
+                                       "AllowedInterface", "AllowedInterface",
+                                       DBUS_TYPE_STRING, &ifname);
+                       append.values = 2;
+                       break;
+               case 's':
+                       if (!args[index + 1]) {
+                               res = -EINVAL;
+                               break;
+                       }
+                       switch (parse_boolean(args[index + 1])) {
+                       case 1:
+                               source_ip_rule = TRUE;
+                               break;
+                       case 0:
+                               source_ip_rule = FALSE;
+                               break;
+                       default:
+                               res = -EINVAL;
+                               break;
+                       }
+                       res = __connmanctl_dbus_session_change(connection,
+                                       session_path, session_config_return,
+                                       "SourceIPRule", "SourceIPRule",
+                                       DBUS_TYPE_BOOLEAN, &source_ip_rule);
+                       append.values = 2;
+                       break;
  
                default:
                        res = -EINVAL;
@@@ -1838,22 -2033,21 +2033,21 @@@ static int cmd_exit(char *args[], int n
        return 1;
  }
  
- static char *lookup_service(const char *text, int state)
+ static char *lookup_key_from_table(GHashTable *hash, const char *text,
+                                       int state)
  {
        static int len = 0;
        static GHashTableIter iter;
        gpointer key, value;
  
        if (state == 0) {
-               g_hash_table_iter_init(&iter, service_hash);
+               g_hash_table_iter_init(&iter, hash);
                len = strlen(text);
        }
  
-       while (g_hash_table_iter_next(&iter, &key, &value)) {
-               const char *service = key;
-               if (strncmp(text, service, len) == 0)
-                       return strdup(service);
-       }
+       while (g_hash_table_iter_next(&iter, &key, &value))
+               if (strncmp(text, key, len) == 0)
+                       return strdup(key);
  
        return NULL;
  }
@@@ -1865,7 -2059,7 +2059,7 @@@ static char *lookup_service_arg(const c
                return NULL;
        }
  
-       return lookup_service(text, state);
+       return lookup_key_from_table(service_hash, text, state);
  }
  
  static char *lookup_peer(const char *text, int state)
@@@ -2009,6 -2203,16 +2203,16 @@@ static char *lookup_agent(const char *t
        return lookup_on_off(text, state);
  }
  
+ static char *lookup_vpnconnection_arg(const char *text, int state)
+ {
+       if (__connmanctl_input_calc_level() > 1) {
+               __connmanctl_input_lookup_end();
+               return NULL;
+       }
+       return lookup_key_from_table(vpnconnection_hash, text, state);
+ }
  static struct connman_option service_options[] = {
        {"properties", 'p', "[<service>]      (obsolete)"},
        { NULL, }
@@@ -2042,6 -2246,8 +2246,8 @@@ static struct connman_option monitor_op
  static struct connman_option session_options[] = {
        {"bearers", 'b', "<technology1> [<technology2> [...]]"},
        {"type", 't', "local|internet|any"},
+       {"ifname", 'i', "[<interface_name>]"},
+       {"srciprule", 's', "yes|no"},
        { NULL, }
  };
  
@@@ -2087,7 -2293,7 +2293,7 @@@ static char *lookup_monitor(const char 
  static char *lookup_config(const char *text, int state)
  {
        if (__connmanctl_input_calc_level() < 2)
-               return lookup_service(text, state);
+               return lookup_key_from_table(service_hash, text, state);
  
        return lookup_options(config_options, text, state);
  }
@@@ -2189,30 -2395,12 +2395,30 @@@ static struct _peer_service *fill_in_pe
  
        service = dbus_malloc0(sizeof(*service));
  
 +#if defined TIZEN_EXT
 +      if (!service)
 +              return NULL;
 +#endif
 +
        if (bjr_query_len && bjr_response_len) {
                service->bjr_query = dbus_malloc0(bjr_query_len);
 +#if defined TIZEN_EXT
 +              if(!service->bjr_query) {
 +                      dbus_free(service);
 +                      return NULL;
 +              }
 +#endif
                memcpy(service->bjr_query, bjr_query, bjr_query_len);
                service->bjr_query_len = bjr_query_len;
  
                service->bjr_response = dbus_malloc0(bjr_response_len);
 +#if defined TIZEN_EXT
 +              if(!service->bjr_response) {
 +                      dbus_free(service->bjr_query);
 +                      dbus_free(service);
 +                      return NULL;
 +              }
 +#endif
                memcpy(service->bjr_response, bjr_response, bjr_response_len);
                service->bjr_response_len = bjr_response_len;
        } else if (upnp_service && version) {
                service->version = version;
        } else if (wfd_ies && wfd_ies_len) {
                service->wfd_ies = dbus_malloc0(wfd_ies_len);
 +#if defined TIZEN_EXT
 +              if (!service->wfd_ies) {
 +                      dbus_free(service);
 +                      return NULL;
 +              }
 +#endif
                memcpy(service->wfd_ies, wfd_ies, wfd_ies_len);
                service->wfd_ies_len = wfd_ies_len;
        } else {
@@@ -2400,6 -2582,8 +2606,8 @@@ static const struct 
          "Shows if the system is online or offline", NULL },
        { "technologies", NULL,           NULL,            cmd_technologies,
          "Display technologies", NULL },
+       { "clock",        NULL,           NULL,            cmd_clock,
+         "Get System Clock Properties", NULL },
        { "enable",       "<technology>|offline", NULL,    cmd_enable,
          "Enables given technology or offline mode",
          lookup_technology_offline },
          "Connect a given service or peer", lookup_service_arg },
        { "disconnect",   "<service/peer>", NULL,          cmd_disconnect,
          "Disconnect a given service or peer", lookup_service_arg },
+       { "move-before",   "<service> <target service>  ", NULL,
+         cmd_service_move_before, "Move <service> before <target service>",
+         lookup_service_arg },
+       { "move-after",   "<service> <target service>   ", NULL,
+         cmd_service_move_after, "Move <service> after <target service>",
+         lookup_service_arg },
        { "config",       "<service>",    config_options,  cmd_config,
          "Set service configuration options", lookup_config },
        { "monitor",      "[off]",        monitor_options, cmd_monitor,
          "Monitor signals from interfaces", lookup_monitor },
        { "agent", "on|off",              NULL,            cmd_agent,
          "Agent mode", lookup_agent },
-       {"vpnconnections", "[<connection>]", NULL,         cmd_vpnconnections,
-        "Display VPN connections", NULL },
+       { "vpnconnections", "[<connection>]", NULL,        cmd_vpnconnections,
+         "Display VPN connections", lookup_vpnconnection_arg },
        { "vpnagent",     "on|off",     NULL,            cmd_vpnagent,
          "VPN Agent mode", lookup_agent },
        { "session",      "on|off|connect|disconnect|config", session_options,
@@@ -2633,6 -2823,72 +2847,72 @@@ static int populate_service_hash(DBusMe
        return 0;
  }
  
+ static void add_vpnconnection_id(const char *path)
+ {
+       g_hash_table_replace(vpnconnection_hash, g_strdup(path),
+                       GINT_TO_POINTER(TRUE));
+ }
+ static void remove_vpnconnection_id(const char *path)
+ {
+       g_hash_table_remove(vpnconnection_hash, path);
+ }
+ static void vpnconnection_added(DBusMessageIter *iter)
+ {
+       char *path = NULL;
+       dbus_message_iter_get_basic(iter, &path);
+       add_vpnconnection_id(get_path(path));
+ }
+ static void vpnconnection_removed(DBusMessageIter *iter)
+ {
+       char *path = NULL;
+       dbus_message_iter_get_basic(iter, &path);
+       remove_vpnconnection_id(get_path(path));
+ }
+ static void add_vpnconnections(DBusMessageIter *iter)
+ {
+       DBusMessageIter array;
+       char *path = NULL;
+       while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
+               dbus_message_iter_recurse(iter, &array);
+               if (dbus_message_iter_get_arg_type(&array) !=
+                                               DBUS_TYPE_OBJECT_PATH)
+                       return;
+               dbus_message_iter_get_basic(&array, &path);
+               add_vpnconnection_id(get_path(path));
+               dbus_message_iter_next(iter);
+       }
+ }
+ static int populate_vpnconnection_hash(DBusMessageIter *iter, const char *error,
+                               void *user_data)
+ {
+       DBusMessageIter array;
+       if (error) {
+               fprintf(stderr, "Error getting VPN connections: %s", error);
+               return 0;
+       }
+       if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+               return 0;
+       dbus_message_iter_recurse(iter, &array);
+       add_vpnconnections(&array);
+       return 0;
+ }
  static void add_peer_id(const char *path)
  {
        g_hash_table_replace(peer_hash, g_strdup(path), GINT_TO_POINTER(TRUE));
@@@ -2785,6 -3041,20 +3065,20 @@@ static DBusHandlerResult monitor_comple
                return handled;
        }
  
+       if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
+                                       "ConnectionAdded")) {
+               dbus_message_iter_init(message, &iter);
+               vpnconnection_added(&iter);
+               return handled;
+       }
+       if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
+                                       "ConnectionRemoved")) {
+               dbus_message_iter_init(message, &iter);
+               vpnconnection_removed(&iter);
+               return handled;
+       }
        if (dbus_message_is_signal(message, "net.connman.Manager",
                                                "PeersChanged")) {
                dbus_message_iter_init(message, &iter);
@@@ -2828,10 -3098,14 +3122,14 @@@ void __connmanctl_monitor_completions(D
  
        if (!dbus_conn) {
                g_hash_table_destroy(service_hash);
+               g_hash_table_destroy(vpnconnection_hash);
                g_hash_table_destroy(technology_hash);
  
                dbus_bus_remove_match(connection,
                        "type='signal',interface='net.connman.Manager'", NULL);
+               dbus_bus_remove_match(connection,
+                       "type='signal',interface='net.connman.vpn.Manager'",
+                       NULL);
                dbus_connection_remove_filter(connection,
                                        monitor_completions_changed,
                                        manager_enabled);
        service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                                g_free, NULL);
  
+       vpnconnection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                               g_free, NULL);
        peer_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                                g_free, NULL);
  
                                populate_service_hash, NULL, NULL, NULL);
  
        __connmanctl_dbus_method_call(connection,
+                               VPN_SERVICE, CONNMAN_PATH,
+                               "net.connman.vpn.Manager", "GetConnections",
+                               populate_vpnconnection_hash, NULL, NULL, NULL);
+       __connmanctl_dbus_method_call(connection,
                                CONNMAN_SERVICE, CONNMAN_PATH,
                                "net.connman.Manager", "GetPeers",
                                populate_peer_hash, NULL, NULL, NULL);
        dbus_bus_add_match(connection,
                        "type='signal',interface='net.connman.Manager'", &err);
  
+       if (dbus_error_is_set(&err)) {
+               fprintf(stderr, "Error: %s\n", err.message);
+               return;
+       }
+       dbus_bus_add_match(connection,
+                       "type='signal',interface='net.connman.vpn.Manager'",
+                       &err);
        if (dbus_error_is_set(&err))
                fprintf(stderr, "Error: %s\n", err.message);
  }
diff --combined client/dbus_helpers.c
index d905746,6ca407d..6ca407d
mode 100755,100644..100755
@@@ -22,6 -22,7 +22,7 @@@
  
  #include <stdio.h>
  #include <errno.h>
+ #include <inttypes.h>
  #include <glib.h>
  
  #include "input.h"
@@@ -38,6 -39,7 +39,7 @@@ void __connmanctl_dbus_print(DBusMessag
        dbus_uint16_t u16;
        dbus_uint32_t u;
        dbus_int32_t i;
+       dbus_uint64_t u64;
        double d;
  
        char *str;
                        fprintf(stdout, "%d", i);
                        break;
  
+               case DBUS_TYPE_UINT64:
+                       dbus_message_iter_get_basic(iter, &u64);
+                       fprintf(stdout, "%"PRIu64, u64);
+                       break;
                case DBUS_TYPE_DOUBLE:
                        dbus_message_iter_get_basic(iter, &d);
                        fprintf(stdout, "%f", d);
@@@ -145,6 -152,7 +152,7 @@@ static void dbus_method_reply(DBusPendi
        __connmanctl_save_rl();
  
        reply = dbus_pending_call_steal_reply(call);
+       dbus_pending_call_unref(call);
        if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
                DBusError err;
  
diff --combined client/input.c
index 4e5e496,78319ff..d9d2b7b
mode 100755,100644..100755
@@@ -103,8 -103,9 +103,9 @@@ static void rl_handler(char *input
        }
  
        if (len > 0) {
-               add_history(input);
+               HIST_ENTRY *previous = history_get(where_history());
+               if(!previous || strcmp(previous->line, input))
+                       add_history(input);
  
                err = __connmanctl_commands(connection, trim_args, len);
  
  
        g_strfreev(args);
        g_free(trim_args);
+       free(input);
  }
  
  static gboolean input_handler(GIOChannel *channel, GIOCondition condition,
@@@ -271,9 -273,7 +273,9 @@@ int __connmanctl_input_init(int argc, c
                __connmanctl_monitor_completions(NULL);
  
                rl_callback_handler_remove();
 +#if !defined TIZEN_EXT
                rl_message("");
 +#endif
        }
  
        dbus_connection_unref(connection);
diff --combined configure.ac
index a999c90,4baa685..01ecd95
mode 100755,100644..100644
@@@ -1,5 -1,7 +1,7 @@@
  AC_PREREQ(2.60)
- AC_INIT(connman, 1.29)
+ AC_INIT(connman, 1.35)
+ AC_CONFIG_MACRO_DIR([m4])
  
  AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
  AC_CONFIG_HEADERS([config.h])
@@@ -31,6 -33,8 +33,8 @@@ m4_ifdef([AC_LIBTOOL_TAGS], [AC_LIBTOOL
  AC_DISABLE_STATIC
  AC_PROG_LIBTOOL
  
+ gl_CONFIGMAKE_PREP
  AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization],
                        [disable code optimization through compiler]), [
        if (test "${enableval}" = "no"); then
@@@ -61,20 -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}])
  
@@@ -83,7 -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
@@@ -103,7 -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
  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}])
  
@@@ -147,7 -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
@@@ -167,7 -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)
        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)
@@@ -192,7 -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)
        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)
@@@ -216,6 -182,9 +220,6 @@@ AC_CHECK_LIB(resolv, ns_initparse, dumm
                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))
  
@@@ -254,11 -223,6 +258,11 @@@ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.2
  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)
@@@ -293,10 -257,41 +297,33 @@@ if (test -n "${path_systemdunit}"); the
  fi
  AM_CONDITIONAL(SYSTEMD, test -n "${path_systemdunit}")
  
- PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, dummy=yes,
-                               AC_MSG_ERROR(Xtables library is required))
- AC_SUBST(XTABLES_CFLAGS)
- AC_SUBST(XTABLES_LIBS)
 -AC_ARG_WITH([tmpfilesdir], AC_HELP_STRING([--with-tmpfilesdir=DIR],
 -      [path to systemd tmpfiles.d directory]), [path_tmpfiles=${withval}],
 -              [path_tmpfiles="`$PKG_CONFIG --variable=tmpfilesdir systemd`"])
 -if (test -n "${path_tmpfiles}"); then
 -      SYSTEMD_TMPFILESDIR="${path_tmpfiles}"
 -      AC_SUBST(SYSTEMD_TMPFILESDIR)
 -fi
 -
+ AC_ARG_WITH(firewall, AC_HELP_STRING([--with-firewall=TYPE],
+                       [specify which firewall type is used iptables or nftables [default=iptables]]),
+               [firewall_type=${withval}],
+               [firewall_type="iptables"])
+ if (test "${firewall_type}" != "iptables" -a \
+               "${firewall_type}" != "nftables"); then
+       AC_MSG_ERROR(neither nftables nor iptables support enabled)
+ fi
+ found_iptables="no"
+ if (test "${firewall_type}" = "iptables"); then
+       PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, [found_iptables="yes"],
+                       AC_MSG_ERROR(Xtables library is required))
+       AC_SUBST(XTABLES_CFLAGS)
+       AC_SUBST(XTABLES_LIBS)
+ fi
+ AM_CONDITIONAL(XTABLES, test "${found_iptables}" != "no")
+ found_nftables="no"
+ if (test "${firewall_type}" = "nftables"); then
+       PKG_CHECK_MODULES(NFTABLES, [libnftnl >= 1.0.4 libmnl >= 1.0.0], [found_nftables="yes"],
+               AC_MSG_ERROR([libnftnl >= 1.0.4 or libmnl >= 1.0.0 not found]))
+       AC_SUBST(NFTABLES_CFLAGS)
+       AC_SUBST(NFTABLES_LIBS)
+ fi
+ AM_CONDITIONAL(NFTABLES, test "${found_nftables}" != "no")
  
  AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test],
                [enable test/example scripts]), [enable_test=${enableval}])
@@@ -345,6 -340,11 +372,11 @@@ AC_ARG_ENABLE(wifi, AC_HELP_STRING([--d
                                        [enable_wifi=${enableval}])
  AM_CONDITIONAL(WIFI, test "${enable_wifi}" != "no")
  
+ AC_ARG_ENABLE(iwd, AC_HELP_STRING([--enable-iwd],
+                               [enable iwd support]),
+                                       [enable_iwd=${enableval}])
+ AM_CONDITIONAL(IWD, test "${enable_iwd}" = "yes")
  AC_ARG_ENABLE(bluetooth, AC_HELP_STRING([--disable-bluetooth],
                                [disable Bluetooth support]),
                                        [enable_bluetooth=${enableval}])
@@@ -382,7 -382,7 +414,7 @@@ AM_CONDITIONAL(TOOLS, test "${enable_to
  
  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 -414,7 +446,7 @@@ f
  
  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,9 -429,8 +461,9 @@@ f
  
  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 --combined doc/agent-api.txt
index 2ddd19a,aa7271d..aa7271d
mode 100755,100644..100755
@@@ -119,7 -119,7 +119,7 @@@ Fields             string Nam
                string PreviousPassphrase
  
                        The previous passphrase successfully saved, i.e.
-                       which lead to a successfull connection. This field is
+                       which led to a successfull connection. This field is
                        provided as an informational argument when connecting
                        with it does not work anymore, for instance when it
                        has been changed on the AP. Such argument appears when
@@@ -166,10 -166,10 +166,10 @@@ Arguments       string Typ
                        would be the network name or SSID.
  
                        All "mandatory" fields must be returned, while the
-                       "optional" can be returned if available.
+                       "optional" ones can be returned if available.
  
                        Nothing needs to be returned for "informational", as it
-                       is here only to provide an information so a value is
+                       is here only to provide an information. A value is
                        attached to it.
  
                array{string} Alternates
diff --combined doc/config-format.txt
index b16f4e4,ed3123a..ed3123a
mode 100755,100644..100755
@@@ -83,6 -83,16 +83,16 @@@ The following options are valid if Typ
    passphrase. The PrivateKeyPassphrase field is ignored when this field is set
    to fsid.
  - Identity: Identity string for EAP.
+ - AnonymousIdentity: Anonymous Identity string for EAP.
+ - SubjectMatch: Substring to be matched against the subject of the
+   authentication server certificate for EAP.
+ - AltSubjectMatch: Semicolon separated string of entries to be matched against
+   the alternative subject name of the authentication server certificate for EAP.
+ - DomainSuffixMatch: Constraint for server domain name. If set, this FQDN is
+   used as a suffix match requirement for the authentication server certificate
+   for EAP.
+ - DomainMatch: This FQDN is used as a full match requirement for the
+   authentication server certificate for EAP.
  - Phase2: Phase2 (inner authentication with TLS tunnel) authentication method.
    Prefix the value with "EAP-" to indicate the usage of an EAP-based inner
    authentication method (should only be used with EAP = TTLS).
diff --combined doc/connman.conf.5.in
index c1ca75c,95b177f..fdc8e9e
mode 100755,100644..100644
@@@ -1,25 -1,19 +1,19 @@@
  .\" connman.conf(5) manual page
  .\"
- .\" Copyright (C) 2012 Intel Corporation
+ .\" Copyright (C) 2012,2015 Intel Corporation
  .\"
- .TH "connman.conf" "5" "21 August 2012" ""
+ .TH "connman.conf" "5" "2015-10-15" ""
  .SH NAME
  main.conf \- ConnMan configuration file
  .SH SYNOPSIS
- /etc/connman/main.conf
- .br
- or
- .br
- \fI<SYSCONFDIR>\fP/connman/main.conf
- .br
- where <SYSCONFDIR> depends on your distribution or build.
+ .B @sysconfdir@/connman/main.conf
  .SH DESCRIPTION
  .P
- .I main.conf
+ .B main.conf
  is a configuration file for ConnMan. The configuration file is
  optional but it can be used to set up various aspects of ConnMan's
  behavior. The location of the file may be changed through use of
- the "\-\-config=" argument for \fBconnman\fP (8).
+ the \fB\-\-config= \fRargument for \fBconnman\fP(8).
  .SH "FILE FORMAT"
  .P
  The configuration file format is key file format.
@@@ -33,47 -27,53 +27,53 @@@ Description of sections and available k
  .SS [General]
  This section is the only mandatory section of the configuration file.
  .TP
- .B InputRequestTimeout=\fPsecs\fP
+ .BI InputRequestTimeout= secs
  Set input request timeout. Default is 120 seconds
  The request for inputs like passphrase will timeout
  after certain amount of time. Use this setting to
  increase the value in case of different user
  interface designs.
  .TP
- .B BrowserLaunchTimeout=\fPsecs\fP
+ .BI BrowserLaunchTimeout= secs
  Set browser launch timeout. Default is 300 seconds
  The request for launching a browser for portal pages
  will timeout after certain amount of time. Use this
  setting to increase the value in case of different
  user interface designs.
  .TP
- .B BackgroundScanning=\fPtrue|false\fP
+ .BI BackgroundScanning=true\ \fR|\fB\ false
  Enable background scanning. Default is true.
  Background scanning will start every 5 minutes unless
  the scan list is empty. In that case, a simple backoff
  mechanism starting from 10s up to 5 minutes will run.
  .TP
- .B FallbackTimeservers=\fPserver1,server2,...\fP
+ .BI FallbackTimeservers= server\fR[,...]
  List of Fallback timeservers separated by ",".
  These timeservers are used for NTP sync when there are
  no timeserver set by the user or by the service.
  These can contain mixed combination of fully qualified
  domain names, IPv4 and IPv6 addresses.
  .TP
- .B FallbackNameservers=\fPserver1,server2,...\fP
+ .BI FallbackNameservers= server\fR[,...]
  List of fallback nameservers separated by "," appended
  to the list of nameservers given by the service. The
  nameserver entries must be in numeric format, host
  names are ignored.
  .TP
- .B DefaultAutoConnectTechnologies=\fPtechnology1,technology2,...\fP
+ .BI DefaultAutoConnectTechnologies= technology\fR[,...]
  List of technologies that are marked autoconnectable
  by default, separated by commas ",". The default value
  for this entry when empty is ethernet,wifi,cellular.
  Services that are automatically connected must have been
  set up and saved to storage beforehand.
  .TP
- .B PreferredTechnologies=\fPtechnology1,technology2,...\fP
+ .BI AlwaysConnectedTechnologies= technology\fR[,...]
+ List of technoolgies which are always connected regardless
+ of PreferredTechnologies setting (AutoConnect = true). The
+ default value is empty and this feature is disabled unless
+ explicitely enabled in the config file.
+ .TP
+ .BI PreferredTechnologies= technology\fR[,...]
  List of preferred technologies from the most preferred
  one to the least preferred one separated by commas ",".
  Services of the listed technology type will be tried one
@@@ -86,19 -86,19 +86,19 @@@ of a preferred technology type in stat
  the default route when compared to either a non-preferred
  type or a preferred type further down in the list.
  .TP
- .B NetworkInterfaceBlacklist=\fPinterface1,interface2,...\fP
+ .BI NetworkInterfaceBlacklist= interface\fR[,...]
  List of blacklisted network interfaces separated by ",".
  Found interfaces will be compared to the list and will
  not be handled by connman, if their first characters
  match any of the list entries. Default value is
  vmnet,vboxnet,virbr,ifb.
  .TP
- .B AllowHostnameUpdates=\fPtrue|false\fP
+ .BI AllowHostnameUpdates=true\ \fR|\fB\ false
  Allow connman to change the system hostname. This can
  happen for example if we receive DHCP hostname option.
  Default value is true.
  .TP
- .B SingleConnectedTechnology=\fPtrue|false\fP
+ .BI SingleConnectedTechnology=true\ \fR|\fB\ false
  Keep only a single connected technology at any time. When a new
  service is connected by the user or a better one is found according
  to PreferredTechnologies, the new service is kept connected and all
@@@ -110,7 -110,7 +110,7 @@@ user will be used until going out of ne
  setting enabled applications will notice more network breaks than
  normal. Default value is false.
  .TP
- .B TetheringTechnologies=\fPtechnology1,technology2,...\fP
+ .BI TetheringTechnologies= technology\fR[,...]
  List of technologies that are allowed to enable tethering separated by ",".
  The default value is wifi,bluetooth,gadget. Only those technologies listed
  here are used for tethering. If one wants to tether ethernet,
@@@ -122,14 -122,37 +122,37 @@@ normal operation of these networks. Du
  tethered by default. Do not activate ethernet tethering unless you
  really know what you are doing.
  .TP
- .B PersistentTetheringMode=\fPtrue|false\fP
+ .BI PersistentTetheringMode=true\ \fR|\fB\ false
  Restore earlier tethering status when returning from offline mode,
  re-enabling a technology, and after restarts and reboots.
  Default value is false.
  .TP
- .B Enable6to4=\fPtrue|false\fP
+ .BI Enable6to4=true\ \fR|\fB\ false
  Automatically enable Anycast 6to4 if possible. This is not recommended, as the
  use of 6to4 will generally lead to a severe degradation of connection quality.
  See RFC6343.  Default value is false (as recommended by RFC6343 section 4.1).
 -Enable or disable use of HTTP GET as an online status check.
+ .TP
+ .BI VendorClassID= string
+ Set DHCP option 60 (Vendor Class ID) to the given string. This option can
+ be used by DHCP servers to identify specific clients without having to
+ rely on MAC address ranges, etc
+ .TP
+ .BI EnableOnlineCheck=true\ \fR|\fB\ false
++Enable or disable use of HTTP GET as on online status check.
+ When a service is in a READY state, and is selected as default,
+ ConnMan will issue an HTTP GET request to verify that end-to-end
+ connectivity is successful. Only then the service will be
+ transitioned to ONLINE state.
+ If this setting is false, the default service will remain in READY state.
+ Default value is true.
+ .SH "EXAMPLE"
+ The following example configuration disables hostname updates and enables
+ ethernet tethering.
+ .PP
+ .nf
+ [General]
+ AllowHostnameUpdates = false
+ TetheringTechnologies = ethernet,wifi,bluetooth,gadget
+ .fi
  .SH "SEE ALSO"
- .BR Connman (8)
+ .BR connman (8)
diff --combined doc/overview-api.txt
index f126887,fd51d70..fd51d70
mode 100755,100644..100755
@@@ -265,8 -265,8 +265,8 @@@ the "idle" state since the service is n
  
                +---------------+
                | idle          |<-------------------------------+
-               +---------------+                                |
-                     |                                          |
+               +---------------+                 A              |
+                     |               clear error |              |
                      |                      +-------------+     |
                      +----------------------| failure     |     |
                      | service.Connect()    +-------------+     |
                      |                                          |
                      +------------------------------------------+
  
- The different states should no be used by the user interface to trigger
+ The different states should not be used by the user interface to trigger
  advanced actions. The state transitions are provided for the sole purpose
  to give the user feedback on what is currently going on. Especially in
  cases where networks are flaky or DHCP servers take a long time these
diff --combined doc/plugin-api.txt
index 616938b,ea5ec0a..ea5ec0a
mode 100755,100644..100755
@@@ -37,7 -37,7 +37,7 @@@ Technology infrastructur
  
  A Technology in ConnMan is an abstract representation of the different
  kinds of technologies it supports such as WiFi, Ethernet, Bluetooth and
- Celullar. The technologies support are added to ConnMan through plugins, such
+ Celullar. The technologies supported are added to ConnMan through plugins, such
  as plugins/bluetooth.c for the Bluetooth Technology or plugins/wifi.c for the
  WiFi Technology. Each new technology plugin needs to register itself as a
  Technology with ConnMan. As an example we will take a look at the Bluetooth
@@@ -65,7 -65,7 +65,7 @@@ plugin initialization function, bluetoo
  
        connman_technology_driver_register(&tech_driver);
  
- In this document the error check is supressed for the sake of simplicity.
+ In this document the error check is suppressed for the sake of simplicity.
  All plugins should check return values in driver registration functions.
  
  After this call ConnMan becomes aware of the new Technology plugin and will
@@@ -74,7 -74,7 +74,7 @@@ the Bluetooth plugin for example probe(
  adapter is recognized. A Technology is only probed if there exists at least
  one device of such technology plugged into the system.
  
- Complementary, the technology must be unregistered on the plugin exit function
+ Complementary, the technology must be unregistered by the plugin exit function
  through 'connman_technology_driver_unregister()'.
  
  Device infrastructure
@@@ -101,7 -101,7 +101,7 @@@ And to register the driver
  'connman_device_driver_register()' is called during the plugin initialization
  process, not necessarily at the plugin init function.
  
- In this document the error check is supressed for the sake of simplicity.
+ In this document the error check is suppressed for the sake of simplicity.
  All plugins should check return values in driver registration functions.
  
  Additionally code to handle the detection of new devices needs to be written
@@@ -130,7 -130,7 +130,7 @@@ its API documentation
  Network infrastructure
  ======================
  
- The Connection Manager provides a mean to plugins handle the specifics of
+ The Connection Manager provides a means to plugins to handle the specifics of
  establishing/handling a connection for each type of Technology. For the
  bluetooth plugin a connman_network_driver needs to be registered:
  
@@@ -147,12 -147,12 +147,12 @@@ And then call the register function
  
        connman_network_driver_register(&network_driver);
  
- In this document the error check is supressed for the sake of simplicity.
+ In this document the error check is suppressed for the sake of simplicity.
  All plugins should check return values in driver registration functions.
  
  The next step would be the probe of a Network entity, for the bluetooth
  plugin this would happen when a new device that supports the PAN NAP role is
- paired with the system. ConnMan then call connman_device_add_network() to
+ paired with the system. ConnMan then calls connman_device_add_network() to
  associate the new Network with the existing Device entity (the local Bluetooth
  Adapter).
  
diff --combined doc/service-api.txt
index 7d9889e,6cdb0bb..4fe4093
mode 100755,100644..100755
@@@ -30,13 -30,12 +30,12 @@@ Methods            dict GetProperties()  [depreca
  
                void ClearProperty(string name)
  
-                       Clears the value of the specified property.
+                       Clears the value of the specified property. Only
+                       the readonly Error property can be cleared using
+                       this method call. When cleared the service is reset
+                       to the idle state.
  
-                       Properties cannot be cleared for hidden WiFi service
-                       entries or provisioned services.
-                       Possible Errors: [service].Error.InvalidArguments
-                                        [service].Error.InvalidProperty
+                       Possible Errors: [service].Error.InvalidProperty
  
                void Connect()
  
@@@ -92,8 -91,9 +91,9 @@@
                        to false, but that is currently not supported.
  
                        In the case a connection attempt failed and the
-                       service is in the State=failure, this method can
-                       also be used to reset the service.
+                       service is in the state "failure", "idle" or
+                       "disconnect", this method can also be used
+                       to reset the service.
  
                        Calling this method on Ethernet devices, hidden WiFi
                        services or provisioned services will cause an error
  
                        Possible Errors: None
  
 +              boolean GetUserFavorite() [experimental]
 +
 +                      This function is used to check whether this service
 +                      is favorite to the current user.
 +
 +                      Possible Errors: None
 +
  Signals               PropertyChanged(string name, variant value)
  
                        This signal indicates a changed value of the given
@@@ -198,32 -191,6 +198,32 @@@ Properties       string State [readonly
                        and also "wps".
  
                        This property might be only present for WiFi
 +                      services.
 +
 +              string BSSID [readonly]
 +
 +                      If the service type is WiFi, then this property
 +                      indicates the BSSID of the service.
 +
 +              uint32 MaxRate [readonly]
 +
 +                      If the service type is WiFi, then this property
 +                      indicates the Maximum speed(bps) of the service.
 +
 +              uint16 Frequency [readonly]
 +
 +                      If the service type is WiFi, then this property
 +                      indicates the frequency band(MHz) of the service.
 +
 +              string EncryptionMode [readonly]
 +
 +                      If the service type is WiFi, then this property
 +                      indicates the key encryption mode.
 +
 +                      Possible values are "none", "wep", "tkip", "aes"
 +                      and "mixed".
 +
 +                      This property might be only present for WiFi
                        services.
  
                uint8 Strength [readonly]
                        This value will be set to true if the service is
                        configured externally via a configuration file.
  
-                       The only valid operation are Connect() and of
-                       course Disconnect(). The Remove() method will
-                       result in an error.
+                       The only valid operations are Connect(), Disconnect()
+                       and changing the AutoConnect property. The Remove()
+                       method will result in an error.
  
                boolean AutoConnect [readwrite]
  
  
                        string Method [readonly]
  
-                               Possible values are "dhcp", "manual"
+                               Possible values are "dhcp", "manual", "auto"
                                and "off".
  
+                               It could be "auto" in case address was got
+                               through IPv4LL after DHCP failed. In this
+                               case also IPv4.Configuration will become
+                               "auto" to allow user to ask for a DHCP
+                               address at any time.
                                The value "fixed" indicates an IP address
                                that can not be modified. For example
                                cellular networks return fixed information.
diff --combined doc/session-api.txt
index 3aac535,e8da522..e8da522
mode 100755,100644..100755
@@@ -182,3 -182,26 +182,26 @@@ Settings string State [readonly
                        (This setting will be removed when the unique process
                        identification problem is solved.)
  
+               string AllowedInterface [readwrite] [experimental]
+                       This field is used to bind a session to a specific
+                       network interface. If this field is empty, the first
+                       interface from a list of available ones will be used.
+                       Also "*" string matches any interface.
+                       Only one interface may be specified.
+                       If a specified network interface is not available
+                       (e.g. because AllowedBearers filters it out), the
+                       session will not go online.
+               boolean SourceIPRule [readwrite] [experimental]
+                       If set to true the session will create source IP
+                       address rule in the firewall, which redirects traffic
+                       to that session's routing table.
+                       Each session maintains a dedicated routing table, with
+                       a default route. When the source IP rule is enabled,
+                       an application can select which session/interface to
+                       send traffic on, using bind-before-connect mechanism.
diff --combined doc/session-overview.txt
index 2393167,976c351..976c351
mode 100755,100644..100755
@@@ -92,3 -92,34 +92,34 @@@ The default session configuration does 
  routing. Sessions are still useful in this setup, because the
  notification of sessions is still available, e.g. the online/offline
  notification.
+ Multiple per-session routing tables
+ ===================================
+ Sessions can be used in an environment with multiple network interfaces,
+ where an application needs to direct outside traffic through a selected
+ interface(s). ConnMan can maintain multiple sessions in a connected
+ stated, and the application can dynamically, on a per-socket basis,
+ select which session is used to route traffic.
+ Example use cases are:
+ - monitoring liveness of multiple connected interfaces, by sending
+   end-to-end heartbeat traffic on all of them in parallel.
+ - prioritising traffic - e.g. sensitive data can be transferred over a slow,
+   but secure connection, while big, public downloads use a second session
+ By default, ConnMan maintains only one online service. So it is impossible
+ to send external traffic (routed through a gateway) on multiple interfaces.
+ In order to enable this functionality, an application needs to issue the
+ following API calls:
+ - create multiple sessions, one for each interface to be used
+ - set each session's AllowedInterface config field to the required interface
+   name (eth0, eth1, wlan0, ppp0, etc.)
+ - set each session's SourceIPRule config field to true
+ - connect each session (or the service it is using)
+ That will instruct ConnMan to create multiple routing tables, with default
+ routes in them. After that, the application can issue a bind() call on each
+ socket, using required interface's source IP address. The bind() call must
+ be made before a connect() call on a socket.
diff --combined doc/technology-api.txt
index 14245eb,f22e9b2..fb6bd31
mode 100755,100644..100755
@@@ -45,18 -45,6 +45,18 @@@ Signals             PropertyChanged(string name, v
                        This signal indicates a changed value of the given
                        property.
  
 +              DhcpConnected(string aptype, string ipaddr,
 +                                      string macaddr, string hostname)
 +
 +                      This signal indicates a station information that
 +                      has connected to the AP(Access Point).
 +
 +              DhcpLeaseDeleted(string aptype, string ipaddr,
 +                                      string macaddr, string hostname)
 +
 +                      This signal indicates a station information that
 +                      has disconnected to the AP(Access Point).
 +
  Properties    boolean Powered [readwrite]
  
                        Boolean representing the power state of the
  
                        Boolean representing if a technology is connected.
  
-                       This is just a convience property for allowing the
+                       This is just a convenience property for allowing the
                        UI to easily show if this technology has an active
                        connection or not.
  
                        If this property is True it means that at least one
                        service of this technology is in ready state.
  
+                       In case of P2P technology, this property indicates
+                       if the peer is fully connected to another peer.
                string Name [readonly]
  
                        Name of this technology.
                        This property is only valid for the WiFi technology,
                        and is then mapped to the WPA pre-shared key clients
                        will have to use in order to establish a connection.
 +
 +              boolean Hidden [readwrite]
 +
 +                      This option allows to enable or disable the support
 +                      for the hidden Wi-Fi tethering.
@@@ -88,7 -88,8 +88,8 @@@ OpenVPN VPN supports following options 
                                           --auth-user-pass value (O)
   OpenVPN.TLSRemote      --tls-remote     Accept connections only from a host
                                           with X509 name or common name equal
-                                          to name parameter (O)
+                                          to name parameter (O). Deprecated in
+                                          OpenVPN 2.3+.
   OpenVPN.TLSAuth        sub-option of --tls-remote (O)
   OpenVPN.TLSAuthDir     sub-option of --tls-remote (O)
   OpenVPN.Cipher         --cipher         Encrypt packets with cipher algorithm
   OpenVPN.ConfigFile     --config         OpenVPN config file that can contain
                                           extra options not supported by OpenVPN
                                           plugin (O)
+  OpenVPN.DeviceType     --dev-type       Whether the VPN should use a tun (OSI
+                                          layer 3) or tap (OSI layer 2) device.
+                                          Value is "tun" (default) or "tap" (O)
  
  VPNC VPN supports following options (see vpnc(8) for details):
   Option name         VPNC config value     Description
   VPNC.Xauth.Password Xauth password        your password (cleartext) (O)
   VPNC.IKE.Authmode   IKE Authmode          IKE Authentication mode (O)
   VPNC.IKE.DHGroup    IKE DH Group          name of the IKE DH Group (O)
-  VPNC.PFS Perfect    Forward Secrecy       Diffie-Hellman group to use for PFS (O)
+  VPNC.PFS            Perfect Forward Secrecy    Diffie-Hellman group to use for
+                                               PFS (O)
   VPNC.Domain         Domain                Domain name for authentication (O)
   VPNC.Vendor         Vendor                vendor of your IPSec gateway (O)
   VPNC.LocalPort      Local Port            local ISAKMP port number to use
-  VPNC.CiscoPort      Cisco UDP Encapsulation Port  Local UDP port number to use (O)
-  VPNC.AppVersion     Application Version   Application Version to report (O)
+  VPNC.CiscoPort      Cisco UDP Encapsulation Port    Local UDP port number to
+                                                    use (O)
+  VPNC.AppVersion     Application version   Application Version to report (O)
   VPNC.NATTMode       NAT Traversal Mode    Which NAT-Traversal Method to use (O)
-  VPNC.DPDTimeout     DPD idle timeout (our side)  Send DPD packet after timeout (O)
+  VPNC.DPDTimeout     DPD idle timeout (our side)    Send DPD packet after
+                                                   timeout (O)
   VPNC.SingleDES      Enable Single DES     enables single DES encryption (O)
-  VPNC.NoEncryption   Enable no encryption  enables using no encryption for data traffic (O)
+  VPNC.NoEncryption   Enable no encryption  enables using no encryption for data
+                                          traffic (O)
+  VPNC.DeviceType     Interface mode        Whether the VPN should use a tun (OSI
+                                            layer 3) or tap (OSI layer 2) device.
+                                            Value is "tun" (default) or "tap" (O)
  
  L2TP VPN supports following options (see xl2tpd.conf(5) and pppd(8) for details)
   Option name         xl2tpd config value    Description
                                              if not set here (O)
   L2TP.Password       -                      L2TP password, asked from the user
                                              if not set here (O)
-  L2TP.BPS            bps                    Max bandwith to use (O)
-  L2TP.TXBPS          tx bps                 Max transmit bandwith to use (O)
-  L2TP.RXBPS          rx bps                 Max receive bandwith to use (O)
+  L2TP.BPS            bps                    Max bandwidth to use (O)
+  L2TP.TXBPS          tx bps                 Max transmit bandwidth to use (O)
+  L2TP.RXBPS          rx bps                 Max receive bandwidth to use (O)
   L2TP.LengthBit      length bit             Use length bit (O)
   L2TP.Challenge      challenge              Use challenge authentication (O)
   L2TP.DefaultRoute   defaultroute           Default route (O)
   PPPD.RefuseMSCHAP2  refuse-mschapv2        Deny mschapv2 auth (O)
   PPPD.NoBSDComp      nobsdcomp              Disables BSD compression (O)
   PPPD.NoPcomp        nopcomp                Disable protocol compression (O)
-  PPPD.UseAccomp      accomp                 Disable address/control compression (O)
+  PPPD.UseAccomp      noaccomp               Disable address/control
+                                           compression (O)
   PPPD.NoDeflate      nodeflate              Disable deflate compression (O)
   PPPD.ReqMPPE        require-mppe           Require the use of MPPE (O)
   PPPD.ReqMPPE40      require-mppe-40        Require the use of MPPE 40 bit (O)
   PPPD.ReqMPPE128     require-mppe-128       Require the use of MPPE 128 bit (O)
   PPPD.ReqMPPEStateful mppe-stateful         Allow MPPE to use stateful mode (O)
-  PPPD.NoVJ           no-vj-comp             No Van Jacobson compression (O)
+  PPPD.NoVJ           novj                   No Van Jacobson compression (O)
  
  
  PPTP VPN supports following options (see pptp(8) and pppd(8) for details)
   PPPD.RequirMPPE40   require-mppe-40      Require the use of MPPE 40 bit (O)
   PPPD.RequirMPPE128  require-mppe-128     Require the use of MPPE 128 bit (O)
   PPPD.RequirMPPEStateful mppe-stateful    Allow MPPE to use stateful mode (O)
-  PPPD.NoVJ           no-vj-comp           No Van Jacobson compression (O)
+  PPPD.NoVJ           novj                 No Van Jacobson compression (O)
  
 +IPsec VPN supports following options (see swanctl.conf(5) for details):
 + Option name                   IPSec config value    Description
 + IPsec.Version                 Version               IKE major version to use for connection (M)
 + IPsec.LeftAddrs               local_addrs           Local address(es) to use for IKE communication (M)
 + IPsec.RightAddrs              remote_addrs          Remote address(es) to use for IKE communication (M)
 +
 +
 + IPsec.LocalAuth               local.auth            Authentication to perform locally (M)
 + IPsec.LocalCerts              local.certs           Certificate candidate to use for authentication (O)
 + IPsec.LocalID                 local.id              IKE identity to use for authentication round (O)
 + IPsec.LocalXauthID            local.xauth_id        Client XAuth username used in the XAuth exchange (O)
 + IPsec.LocalXauthAuth          local-xauth.auth      Xauth round authentication to perform locally (O)
 + IPsec.LocalXauthXauthID       local-xauth.xauth_id  Xauth round client XAuth username used in the XAuth exchange (O)
 +
 + IPsec.RemoteAuth              remote.auth           Authentication to expect from remote (M)
 + IPsec.RemoteCerts             remote.certs          Certificate candidate to use for authentication (O)
 + IPsec.RemoteID                remote.id             IKE identity to use for authentication round (O)
 + IPsec.RemoteXauthAuth         remote-xauth.auth     Xauth round authentication to expect from remote (O)
 + IPsec.ChildrenLocalTs         children.local_ts     local selectors to include in CHILD_SA (O)
 + IPsec.ChildrenRemoteTs        children.remote_ts    Remote selectors to include in CHILD_SA (O)
 +
 + IPsec.IKEData                 secret.data           IKE PSK raw shared key data
 + IPsec.IKEOwners               secret.Owners         list of shared key owner identities
 + IPsec.XauthData               secret.data           XAUTH raw shared key data
 + IPsec.XauthOwners             secret.Owners         list of shared key owner identities
 +
 + IPsec.CertType                cert.type             certificate type, X509|X509_AC|X509_CRL
 + IPsec.CertFlag                cert.flag             X.509 certificate flag, NONE|CA|AA|OCSP
 + IPsec.CertData                cert.data             PEM or DER encoded certificate data
  
  Example
  =======
index 4367699,a814a38..a814a38
mode 100755,100644..100755
@@@ -144,7 -144,8 +144,8 @@@ Properties string State [readonly
  
                        string Netmask
  
-                               The netmask of the route.
+                               The netmask of the route. For IPv6 routes,
+                               this is the prefix length.
  
                        string Gateway
  
  
                        string Netmask
  
-                               The netmask of the route.
+                               The netmask of the route. For IPv6 routes,
+                               this is the prefix length.
  
                        string Gateway
  
diff --combined gdbus/client.c
index 6e4dc66,a011e19..9748ae2
mode 100755,100644..100755
@@@ -58,10 -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;
@@@ -731,7 -729,6 +731,7 @@@ gboolean g_dbus_proxy_set_property_basi
        return TRUE;
  }
  
 +#if !defined TIZEN_EXT
  gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
                                const char *name, int type, const void *value,
                                size_t size, GDBusResultFunction function,
  
        return TRUE;
  }
 +#endif
  
  struct method_call_data {
        GDBusReturnFunction function;
@@@ -857,28 -853,30 +857,30 @@@ gboolean g_dbus_proxy_method_call(GDBus
        if (client == NULL)
                return FALSE;
  
-       data = g_try_new0(struct method_call_data, 1);
-       if (data == NULL)
-               return FALSE;
-       data->function = function;
-       data->user_data = user_data;
-       data->destroy = destroy;
        msg = dbus_message_new_method_call(client->service_name,
                                proxy->obj_path, proxy->interface, method);
-       if (msg == NULL) {
-               g_free(data);
+       if (msg == NULL)
                return FALSE;
-       }
  
        if (setup) {
                DBusMessageIter iter;
  
                dbus_message_iter_init_append(msg, &iter);
-               setup(&iter, data->user_data);
+               setup(&iter, user_data);
        }
  
+       if (!function)
+               return g_dbus_send_message(client->dbus_conn, msg);
+       data = g_try_new0(struct method_call_data, 1);
+       if (data == NULL)
+               return FALSE;
+       data->function = function;
+       data->user_data = user_data;
+       data->destroy = destroy;
        if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
                                        &call, METHOD_CALL_TIMEOUT) == FALSE) {
                dbus_message_unref(msg);
@@@ -1077,10 -1075,6 +1079,6 @@@ static void parse_managed_objects(GDBus
  
                dbus_message_iter_next(&dict);
        }
- #if !defined TIZEN_EXT
-       if (client->ready)
-               client->ready(client, client->ready_data);
- #endif
  }
  
  static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
        parse_managed_objects(client, reply);
  
  done:
++#if !defined TIZEN_EXT
+       if (client->ready)
+               client->ready(client, client->ready_data);
++#endif
        dbus_message_unref(reply);
  
        dbus_pending_call_unref(client->get_objects_call);
@@@ -1370,7 -1367,6 +1373,7 @@@ gboolean g_dbus_client_set_signal_watch
        return TRUE;
  }
  
 +#if !defined TIZEN_EXT
  gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
                                GDBusClientFunction ready, void *user_data)
  {
  
        return TRUE;
  }
 +#endif
  
  gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
                                        GDBusProxyFunction proxy_added,
diff --combined gdbus/gdbus.h
index 633db0c,69fbc10..70190b7
mode 100755,100644..100755
@@@ -31,11 -31,6 +31,6 @@@ extern "C" 
  #include <dbus/dbus.h>
  #include <glib.h>
  
- typedef enum GDBusMethodFlags GDBusMethodFlags;
- typedef enum GDBusSignalFlags GDBusSignalFlags;
- typedef enum GDBusPropertyFlags GDBusPropertyFlags;
- typedef enum GDBusSecurityFlags GDBusSecurityFlags;
  typedef struct GDBusArgInfo GDBusArgInfo;
  typedef struct GDBusMethodTable GDBusMethodTable;
  typedef struct GDBusSignalTable GDBusSignalTable;
@@@ -115,6 -110,16 +110,16 @@@ enum GDBusSecurityFlags 
        G_DBUS_SECURITY_FLAG_ALLOW_INTERACTION = (1 << 2),
  };
  
+ enum GDbusPropertyChangedFlags {
+       G_DBUS_PROPERTY_CHANGED_FLAG_FLUSH = (1 << 0),
+ };
+ typedef enum GDBusMethodFlags GDBusMethodFlags;
+ typedef enum GDBusSignalFlags GDBusSignalFlags;
+ typedef enum GDBusPropertyFlags GDBusPropertyFlags;
+ typedef enum GDBusSecurityFlags GDBusSecurityFlags;
+ typedef enum GDbusPropertyChangedFlags GDbusPropertyChangedFlags;
  struct GDBusArgInfo {
        const char *name;
        const char *signature;
@@@ -300,6 -305,10 +305,10 @@@ void g_dbus_pending_property_error(GDBu
  void g_dbus_emit_property_changed(DBusConnection *connection,
                                const char *path, const char *interface,
                                const char *name);
+ void g_dbus_emit_property_changed_full(DBusConnection *connection,
+                               const char *path, const char *interface,
+                               const char *name,
+                               GDbusPropertyChangedFlags flags);
  gboolean g_dbus_get_properties(DBusConnection *connection, const char *path,
                                const char *interface, DBusMessageIter *iter);
  
@@@ -330,12 -339,10 +339,12 @@@ gboolean g_dbus_proxy_set_property_basi
                                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);
@@@ -345,9 -352,7 +354,9 @@@ gboolean g_dbus_proxy_method_call(GDBus
                                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);
@@@ -374,10 -379,8 +383,10 @@@ gboolean g_dbus_client_set_disconnect_w
                                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 --combined gdbus/object.c
index c7ed02f,a220101..c333d5b
mode 100755,100644..100755
@@@ -258,7 -258,8 +258,8 @@@ static DBusHandlerResult process_messag
  
        reply = method->function(connection, message, iface_user_data);
  
-       if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY) {
+       if (method->flags & G_DBUS_METHOD_FLAG_NOREPLY ||
+                                       dbus_message_get_no_reply(message)) {
                if (reply != NULL)
                        dbus_message_unref(reply);
                return DBUS_HANDLER_RESULT_HANDLED;
@@@ -1247,10 -1248,8 +1248,10 @@@ static struct generic_data *object_path
  
        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;
@@@ -1722,9 -1721,10 +1723,10 @@@ static void process_property_changes(st
        }
  }
  
- void g_dbus_emit_property_changed(DBusConnection *connection,
+ void g_dbus_emit_property_changed_full(DBusConnection *connection,
                                const char *path, const char *interface,
-                               const char *name)
+                               const char *name,
+                               GDbusPropertyChangedFlags flags)
  {
        const GDBusPropertyTable *property;
        struct generic_data *data;
        iface->pending_prop = g_slist_prepend(iface->pending_prop,
                                                (void *) property);
  
-       add_pending(data);
+       if (flags & G_DBUS_PROPERTY_CHANGED_FLAG_FLUSH)
+               process_property_changes(data);
+       else
+               add_pending(data);
+ }
+ void g_dbus_emit_property_changed(DBusConnection *connection, const char *path,
+                               const char *interface, const char *name)
+ {
+       g_dbus_emit_property_changed_full(connection, path, interface, name, 0);
  }
  
  gboolean g_dbus_get_properties(DBusConnection *connection, const char *path,
diff --combined gdhcp/client.c
index d3794bd,3e67fcd..5a455f0
mode 100755,100644..100755
  #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,
@@@ -177,10 -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, ...)
@@@ -505,9 -480,6 +505,9 @@@ static int send_request(GDHCPClient *dh
        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)
@@@ -1297,7 -1269,7 +1297,7 @@@ static int dhcp_l2_socket(int ifindex
                .filter = (struct sock_filter *) filter_instr,
        };
  
-       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IP));
+       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (fd < 0)
                return -errno;
  
@@@ -1544,21 -1516,6 +1544,21 @@@ static gboolean request_timeout(gpointe
  {
        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);
  
@@@ -1671,8 -1628,7 +1671,7 @@@ static uint32_t get_lease(struct dhcp_p
                return 3600;
  
        lease_seconds = get_be32(option);
-       /* paranoia: must not be prone to overflows */
-       lease_seconds &= 0x0fffffff;
        if (lease_seconds < 10)
                lease_seconds = 10;
  
@@@ -1720,8 -1676,10 +1719,10 @@@ static gboolean continue_rebound(gpoint
        switch_listening_mode(dhcp_client, L2);
        send_request(dhcp_client);
  
-       if (dhcp_client->t2_timeout> 0)
+       if (dhcp_client->t2_timeout> 0) {
                g_source_remove(dhcp_client->t2_timeout);
+               dhcp_client->t2_timeout = 0;
+       }
  
        /*recalculate remaining rebind time*/
        dhcp_client->T2 >>= 1;
@@@ -1859,6 -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;
@@@ -2268,6 -2291,8 +2269,8 @@@ static gboolean listener_event(GIOChann
                if (dhcp_client->type == G_DHCP_IPV6) {
                        re = dhcpv6_recv_l3_packet(&packet6, buf, sizeof(buf),
                                                dhcp_client->listener_sockfd);
+                       if (re < 0)
+                           return TRUE;
                        pkt_len = re;
                        pkt = packet6;
                        xid = packet6->transaction_id[0] << 16 |
                        return TRUE;
        }
  
-       if (!message_type && !client_id)
-               /* No message type / client id option, ignore package */
-               return TRUE;
        debug(dhcp_client, "received DHCP packet xid 0x%04x "
                "(current state %d)", ntohl(xid), dhcp_client->state);
  
  
                        dhcp_client->lease_seconds = get_lease(&packet);
  
 +#if defined TIZEN_EXT
 +                      dhcp_client->dhcp_lease_seconds = dhcp_client->lease_seconds;
 +#endif
 +
                        get_request(dhcp_client, &packet);
  
                        switch_listening_mode(dhcp_client, L_NONE);
  
                        remove_timeouts(dhcp_client);
  
 +#if defined TIZEN_EXT
 +                      if (dhcp_client->init_reboot) {
 +                              g_dhcp_client_set_address_known(dhcp_client, FALSE);
 +                              dhcp_client->timeout = g_idle_add_full(
 +                                                              G_PRIORITY_HIGH,
 +                                                              restart_dhcp_timeout,
 +                                                              dhcp_client,
 +                                                              NULL);
 +
 +                              break;
 +                      }
 +#endif
                        dhcp_client->timeout = g_timeout_add_seconds_full(
                                                        G_PRIORITY_HIGH, 3,
                                                        restart_dhcp_timeout,
@@@ -2661,11 -2666,6 +2660,11 @@@ static gboolean ipv4ll_announce_timeout
        GDHCPClient *dhcp_client = dhcp_data;
        uint32_t ip;
  
 +#if defined TIZEN_EXT
 +      if (!dhcp_client)
 +              return FALSE;
 +#endif
 +
        debug(dhcp_client, "request timeout (retries %d)",
               dhcp_client->retry_times);
  
@@@ -2717,11 -2717,6 +2716,11 @@@ int g_dhcp_client_start(GDHCPClient *dh
        uint32_t addr;
        uint64_t rand;
  
 +#if defined TIZEN_EXT
 +      int discover_retry = 0;
 +      int timeout = 0;
 +#endif
 +
        remove_timeouts(dhcp_client);
  
        if (dhcp_client->type == G_DHCP_IPV6) {
                return 0;
        }
  
 +#if defined TIZEN_EXT
 +      if (g_ascii_strncasecmp(dhcp_client->interface, "wlan", 4)
 +                      == 0) {
 +              discover_retry = DISCOVER_RETRIES_WIFI;
 +              timeout = DISCOVER_TIMEOUT_WIFI;
 +      } else {
 +              discover_retry = DISCOVER_RETRIES;
 +              timeout = DISCOVER_TIMEOUT;
 +      }
 +
 +      debug(dhcp_client, "[DHCPC] Discover retry/total : [%d]/[%d] timeout [%d]",
 +                      dhcp_client->retry_times, discover_retry, timeout);
 +#endif
 +
 +
        if (dhcp_client->type == G_DHCP_IPV4LL) {
                dhcp_client->state = INIT_SELECTING;
                ipv4ll_start(dhcp_client);
                return 0;
        }
  
 -      if (dhcp_client->retry_times == DISCOVER_RETRIES) {
 +#if defined TIZEN_EXT
 +              if (dhcp_client->retry_times == discover_retry) {
 +#else
 +              if (dhcp_client->retry_times == DISCOVER_RETRIES) {
 +#endif
                if (dhcp_client->no_lease_cb)
                        dhcp_client->no_lease_cb(dhcp_client,
                                                dhcp_client->no_lease_data);
  
                dhcp_client->timeout = g_timeout_add_seconds_full(
                                                                G_PRIORITY_HIGH,
 +#if defined TIZEN_EXT
 +                                                              timeout,
 +#else
                                                                REQUEST_TIMEOUT,
 +#endif
                                                                reboot_timeout,
                                                                dhcp_client,
                                                                NULL);
        send_discover(dhcp_client, addr);
  
        dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
 +#if defined TIZEN_EXT
 +                                                      timeout,
 +#else
                                                        DISCOVER_TIMEOUT,
 +#endif
                                                        discover_timeout,
                                                        dhcp_client,
                                                        NULL);
@@@ -3034,19 -3002,8 +3033,19 @@@ char *g_dhcp_client_get_server_address(
        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)
  {
@@@ -3160,13 -3117,14 +3159,14 @@@ GDHCPClientError g_dhcp_client_set_id(G
        return G_DHCP_CLIENT_ERROR_NONE;
  }
  
- /* Now only support send hostname */
+ /* Now only support send hostname and vendor class ID */
  GDHCPClientError g_dhcp_client_set_send(GDHCPClient *dhcp_client,
                unsigned char option_code, const char *option_value)
  {
        uint8_t *binary_option;
  
-       if (option_code == G_DHCP_HOST_NAME && option_value) {
+       if ((option_code == G_DHCP_HOST_NAME ||
+               option_code == G_DHCP_VENDOR_CLASS_ID) && option_value) {
                binary_option = alloc_dhcp_string_option(option_code,
                                                        option_value);
                if (!binary_option)
@@@ -3272,9 -3230,6 +3272,9 @@@ void g_dhcp_client_unref(GDHCPClient *d
        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,
@@@ -3310,19 -3265,3 +3310,19 @@@ GSList *g_dhcpv6_copy_prefixes(GSList *
  
        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 --combined gdhcp/common.c
index 6d457ac,6f81671..b8c5091
mode 100755,100644..100755
@@@ -46,6 -46,7 +46,7 @@@ static const DHCPOption client_options[
        { OPTION_IP | OPTION_LIST,      0x06 }, /* domain-name-servers */
        { OPTION_STRING,                0x0c }, /* hostname */
        { OPTION_STRING,                0x0f }, /* domain-name */
+       { OPTION_U16,                   0x1a }, /* mtu */
        { OPTION_IP | OPTION_LIST,      0x2a }, /* ntp-servers */
        { OPTION_U32,                   0x33 }, /* dhcp-lease-time */
        /* Options below will not be exposed to user */
@@@ -181,71 -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)
  {
@@@ -554,15 -490,20 +555,20 @@@ int dhcpv6_send_packet(int index, struc
        if (fd < 0)
                return -errno;
  
-       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+               int err = errno;
+               close(fd);
+               return -err;
+       }
  
        memset(&src, 0, sizeof(src));
        src.sin6_family = AF_INET6;
        src.sin6_port = htons(DHCPV6_CLIENT_PORT);
  
        if (bind(fd, (struct sockaddr *) &src, sizeof(src)) <0) {
+               int err = errno;
                close(fd);
-               return -errno;
+               return -err;
        }
  
        memset(&dst, 0, sizeof(dst));
@@@ -636,7 -577,7 +642,7 @@@ int dhcp_send_raw_packet(struct dhcp_pa
                                offsetof(struct ip_udp_dhcp_packet, udp),
        };
  
-       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IP));
+       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (fd < 0)
                return -errno;
  
        dest.sll_halen = 6;
        memcpy(dest.sll_addr, dest_arp, 6);
        if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
+               int err = errno;
                close(fd);
-               return -errno;
+               return -err;
        }
  
        packet.ip.protocol = IPPROTO_UDP;
         */
        n = sendto(fd, &packet, IP_UPD_DHCP_SIZE, 0,
                        (struct sockaddr *) &dest, sizeof(dest));
-       close(fd);
+       if (n < 0) {
+               int err = errno;
+               close(fd);
+               return -err;
+       }
  
-       if (n < 0)
-               return -errno;
+       close(fd);
  
        return n;
  }
@@@ -705,15 -650,20 +715,20 @@@ int dhcp_send_kernel_packet(struct dhcp
        if (fd < 0)
                return -errno;
  
-       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+               int err = errno;
+               close(fd);
+               return -err;
+       }
  
        memset(&client, 0, sizeof(client));
        client.sin_family = AF_INET;
        client.sin_port = htons(source_port);
        client.sin_addr.s_addr = htonl(source_ip);
        if (bind(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
+               int err = errno;
                close(fd);
-               return -errno;
+               return -err;
        }
  
        memset(&client, 0, sizeof(client));
        client.sin_port = htons(dest_port);
        client.sin_addr.s_addr = htonl(dest_ip);
        if (connect(fd, (struct sockaddr *) &client, sizeof(client)) < 0) {
+               int err = errno;
                close(fd);
-               return -errno;
+               return -err;
        }
  
        n = write(fd, dhcp_pkt, DHCP_SIZE);
+       if (n < 0) {
+               int err = errno;
+               close(fd);
+               return -err;
+       }
  
        close(fd);
  
-       if (n < 0)
-               return -errno;
        return n;
  }
  
@@@ -746,12 -699,17 +764,17 @@@ int dhcp_l3_socket(int port, const cha
        if (fd < 0)
                return -errno;
  
-       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
+               int err = errno;
+               close(fd);
+               return -err;
+       }
  
        if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
                                interface, strlen(interface) + 1) < 0) {
+               int err = errno;
                close(fd);
-               return -1;
+               return -err;
        }
  
        if (family == AF_INET) {
diff --combined gdhcp/gdhcp.h
index fd6ce54,eaf6a74..f51a8b0
mode 100755,100644..100755
@@@ -77,7 -77,9 +77,9 @@@ typedef enum 
  #define G_DHCP_DNS_SERVER     0x06
  #define G_DHCP_DOMAIN_NAME    0x0f
  #define G_DHCP_HOST_NAME      0x0c
+ #define G_DHCP_MTU            0x1a
  #define G_DHCP_NTP_SERVER     0x2a
+ #define G_DHCP_VENDOR_CLASS_ID        0x3c
  #define G_DHCP_CLIENT_ID      0x3d
  
  #define G_DHCPV6_CLIENTID     1
@@@ -151,11 -153,6 +153,11 @@@ GDHCPClientError g_dhcp_client_set_send
                                                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,
@@@ -214,9 -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);
@@@ -237,16 -231,10 +239,16 @@@ void g_dhcp_server_set_save_lease(GDHCP
                                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 --combined gdhcp/ipv4ll.c
index c43971f,d900198..d900198
mode 100755,100644..100755
@@@ -72,7 -72,7 +72,7 @@@ int ipv4ll_send_arp_packet(uint8_t* sou
        uint32_t ip_target;
        int fd, n;
  
-       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_ARP));
+       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (fd < 0)
                return -errno;
  
@@@ -85,8 -85,9 +85,9 @@@
        dest.sll_halen = ETH_ALEN;
        memset(dest.sll_addr, 0xFF, ETH_ALEN);
        if (bind(fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
+               int err = errno;
                close(fd);
-               return -errno;
+               return -err;
        }
  
        ip_source = htonl(source_ip);
@@@ -116,7 -117,7 +117,7 @@@ int ipv4ll_arp_socket(int ifindex
        int fd;
        struct sockaddr_ll sock;
  
-       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_ARP));
+       fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (fd < 0)
                return fd;
  
        sock.sll_ifindex = ifindex;
  
        if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) {
+               int err = errno;
                close(fd);
-               return -errno;
+               return -err;
        }
  
        return fd;
diff --combined gdhcp/server.c
index 83132a7,f7795f7..44ce771
mode 100755,100644..100755
@@@ -66,7 -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;
  };
@@@ -215,9 -214,6 +215,6 @@@ static struct dhcp_lease *add_lease(GDH
        g_hash_table_insert(dhcp_server->nip_lease_hash,
                                GINT_TO_POINTER((int) lease->lease_nip), lease);
  
-       if (dhcp_server->lease_added_cb)
-               dhcp_server->lease_added_cb(lease->lease_mac, yiaddr);
        return lease;
  }
  
@@@ -403,7 -399,6 +400,7 @@@ GDHCPServer *g_dhcp_server_new(GDHCPTyp
        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;
  
@@@ -618,6 -613,9 +615,9 @@@ static void send_ACK(GDHCPServer *dhcp_
        send_packet_to_client(dhcp_server, &packet);
  
        add_lease(dhcp_server, 0, packet.chaddr, packet.yiaddr);
+       if (dhcp_server->lease_added_cb)
+               dhcp_server->lease_added_cb(packet.chaddr, packet.yiaddr);
  }
  
  static void send_NAK(GDHCPServer *dhcp_server,
@@@ -652,12 -650,9 +652,12 @@@ static gboolean listener_event(GIOChann
        struct dhcp_packet packet;
        struct dhcp_lease *lease;
        uint32_t requested_nip = 0;
 -      uint8_t type, *server_id_option, *request_ip_option;
 +      uint8_t type, *server_id_option, *request_ip_option, *host_name;
        int re;
  
 +      GDHCPOptionType option_type;
 +      char *option_value;
 +
        if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
                dhcp_server->listener_watch = 0;
                return FALSE;
  
                if (lease && requested_nip == lease->lease_nip) {
                        debug(dhcp_server, "Sending ACK");
 +
 +                      host_name = dhcp_get_option(&packet, DHCP_HOST_NAME);
 +                      option_type = dhcp_get_code_type(DHCP_HOST_NAME);
 +                      option_value = malloc_option_value_string(host_name,
 +                                                              option_type);
                        send_ACK(dhcp_server, &packet,
                                lease->lease_nip);
 +
 +                      if (dhcp_server->save_ack_lease_func)
 +                              dhcp_server->save_ack_lease_func(
 +                                                      option_value,
 +                                                      lease->lease_mac,
 +                                                      lease->lease_nip);
 +                      g_free(option_value);
 +
                        break;
                }
  
@@@ -846,15 -828,6 +846,15 @@@ void g_dhcp_server_set_lease_added_cb(G
        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)
index 123f3b2,db61595..8860626
mode 100755,100644..100755
@@@ -56,13 -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)
@@@ -102,10 -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 {
@@@ -138,12 -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;
        const char *eap;
        const char *passphrase;
        const char *identity;
+       const char *anonymous_identity;
        const char *ca_cert_path;
+       const char *subject_match;
+       const char *altsubject_match;
+       const char *domain_suffix_match;
+       const char *domain_match;
        const char *client_cert_path;
        const char *private_key_path;
        const char *private_key_passphrase;
        dbus_bool_t use_wps;
        const char *pin_wps;
        const char *bgscan;
 +      int ignore_broadcast_ssid;
 +#if defined TIZEN_EXT
 +      unsigned char *bssid;
 +#endif
  };
  
  typedef struct _GSupplicantSSID GSupplicantSSID;
  
 +/*
 + * Max number of SSIDs that can be scanned.
 + * In wpa_s 0.7x the limit is 4.
 + * In wps_s 0.8 or later it is 16.
 + * The value is only used if wpa_supplicant does not return any max limit
 + * for number of scannable SSIDs.
 + */
 +#define WPAS_MAX_SCAN_SSIDS 4
 +
  struct scan_ssid {
        unsigned char ssid[32];
        uint8_t ssid_len;
@@@ -291,9 -268,6 +296,9 @@@ int g_supplicant_interface_disconnect(G
                                        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);
  
@@@ -363,23 -337,6 +368,24 @@@ GSupplicantInterface *g_supplicant_peer
  bool g_supplicant_peer_is_client(GSupplicantPeer *peer);
  bool g_supplicant_peer_has_requested_connection(GSupplicantPeer *peer);
  
- void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network);
 +#if defined TIZEN_EXT
 +/*
 +* Description: Network client requires additional wifi specific info
 +*/
 +const unsigned char *g_supplicant_network_get_bssid(
 +                                              GSupplicantNetwork *network);
 +unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network);
 +const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network);
 +bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network);
 +bool g_supplicant_network_is_hs20AP(GSupplicantNetwork *network);
 +const char *g_supplicant_network_get_eap(GSupplicantNetwork *network);
 +const char *g_supplicant_network_get_identity(GSupplicantNetwork *network);
 +const char *g_supplicant_network_get_phase2(GSupplicantNetwork *network);
 +unsigned int g_supplicant_network_get_keymgmt(GSupplicantNetwork *network);
++const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
++                                              unsigned int *wifi_vsie_len);
 +#endif
 +
  struct _GSupplicantCallbacks {
        void (*system_ready) (void);
        void (*system_killed) (void);
        void (*p2p_support) (GSupplicantInterface *interface);
        void (*scan_started) (GSupplicantInterface *interface);
        void (*scan_finished) (GSupplicantInterface *interface);
+       void (*ap_create_fail) (GSupplicantInterface *interface);
        void (*network_added) (GSupplicantNetwork *network);
        void (*network_removed) (GSupplicantNetwork *network);
 +#if defined TIZEN_EXT
 +      void (*network_merged) (GSupplicantNetwork *network);
 +#endif
        void (*network_changed) (GSupplicantNetwork *network,
                                        const char *property);
+       void (*network_associated) (GSupplicantNetwork *network);
 +#if defined TIZEN_EXT
 +      void (*system_power_off) (void);
 +      void (*assoc_failed) (void *user_data);
 +#endif
 +      void (*add_station) (const char *mac);
 +      void (*remove_station) (const char *mac);
        void (*peer_found) (GSupplicantPeer *peer);
        void (*peer_lost) (GSupplicantPeer *peer);
        void (*peer_changed) (GSupplicantPeer *peer,
        void (*peer_request) (GSupplicantPeer *peer);
        void (*debug) (const char *str);
        void (*disconnect_reasoncode)(GSupplicantInterface *interface,
-                                                               int reasoncode);
+                               int reasoncode);
        void (*assoc_status_code)(GSupplicantInterface *interface,
                                int reasoncode);
  };
diff --combined gsupplicant/supplicant.c
index 243dcd0,4f79012..5e9f509
mode 100755,100644..100644
@@@ -143,6 -143,7 +143,7 @@@ static GHashTable *bss_mapping
  static GHashTable *peer_mapping;
  static GHashTable *group_mapping;
  static GHashTable *pending_peer_connection;
+ static GHashTable *config_file_table;
  
  struct _GSupplicantWpsCredentials {
        unsigned char ssid[32];
        char *key;
  };
  
+ struct added_network_information {
+       char * ssid;
+       GSupplicantSecurity security;
+       char * passphrase;
+       char * private_passphrase;
+ };
  struct _GSupplicantInterface {
        char *path;
        char *network_path;
        unsigned int max_scan_ssids;
        bool p2p_support;
        bool p2p_finding;
+       bool ap_create_in_progress;
        dbus_bool_t ready;
        GSupplicantState state;
        dbus_bool_t scanning;
        GHashTable *network_table;
        GHashTable *peer_table;
        GHashTable *group_table;
-       GHashTable *net_mapping;
        GHashTable *bss_mapping;
        void *data;
        const char *pending_peer_path;
+       GSupplicantNetwork *current_network;
+       struct added_network_information network_info;
 +#if defined TIZEN_EXT
 +      int disconnect_reason;
 +#endif
  };
  
  struct g_supplicant_bss {
        dbus_bool_t privacy;
        dbus_bool_t psk;
        dbus_bool_t ieee8021x;
-       GSList *vsie_list;
 +#if defined TIZEN_EXT
 +      dbus_bool_t ft_psk;
 +      dbus_bool_t ft_ieee8021x;
++      char *wifi_vsie;
++      unsigned int wifi_vsie_len;
 +      dbus_bool_t hs20;
 +#endif
        unsigned int wps_capabilities;
  };
  
@@@ -233,14 -234,6 +244,15 @@@ struct _GSupplicantNetwork 
        unsigned int wps_capabilities;
        GHashTable *bss_table;
        GHashTable *config_table;
-       GSList *vsie_list;
 +#if defined TIZEN_EXT
 +      bool isHS20AP;
 +      char *eap;
 +      char *identity;
 +      char *phase2;
 +      unsigned int keymgmt;
++      char *wifi_vsie;
++      unsigned int wifi_vsie_len;
 +#endif
  };
  
  struct _GSupplicantPeer {
@@@ -266,12 -259,53 +278,53 @@@ struct _GSupplicantGroup 
        GSList *members;
  };
  
+ struct interface_data {
+       GSupplicantInterface *interface;
+       char *path; /* Interface path cannot be taken from interface (above) as
+                    * it might have been freed already.
+                    */
+       GSupplicantInterfaceCallback callback;
+       void *user_data;
+       bool network_remove_in_progress;
+       GSupplicantSSID *ssid;
+ };
+ struct interface_create_data {
+       char *ifname;
+       char *driver;
+       char *bridge;
+       GSupplicantInterface *interface;
+       GSupplicantInterfaceCallback callback;
+       void *user_data;
+ };
+ struct interface_connect_data {
+       GSupplicantInterface *interface;
+       char *path;
+       GSupplicantInterfaceCallback callback;
+       void *user_data;
+       union {
+               GSupplicantSSID *ssid;
+               GSupplicantPeerParams *peer;
+       };
+ };
+ struct interface_scan_data {
+       GSupplicantInterface *interface;
+       char *path;
+       GSupplicantInterfaceCallback callback;
+       GSupplicantScanParams *scan_params;
+       void *user_data;
+ };
+ static int network_remove(struct interface_data *data);
  static inline void debug(const char *format, ...)
  {
        char str[256];
        va_list ap;
  
-       if (!callbacks_pointer->debug)
+       if (!callbacks_pointer || !callbacks_pointer->debug)
                return;
  
        va_start(ap, format);
@@@ -327,12 -361,6 +380,12 @@@ static const char *security2string(GSup
                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;
@@@ -369,6 -397,70 +422,70 @@@ static GSupplicantState string2state(co
        return G_SUPPLICANT_STATE_UNKNOWN;
  }
  
+ static bool compare_network_parameters(GSupplicantInterface *interface,
+                               GSupplicantSSID *ssid)
+ {
+       if (memcmp(interface->network_info.ssid, ssid->ssid, ssid->ssid_len))
+               return FALSE;
+       if (interface->network_info.security != ssid->security)
+               return FALSE;
+       if (interface->network_info.passphrase &&
+                       g_strcmp0(interface->network_info.passphrase,
+                               ssid->passphrase) != 0) {
+               return FALSE;
+       }
+       if (interface->network_info.private_passphrase &&
+                       g_strcmp0(interface->network_info.private_passphrase,
+                               ssid->private_key_passphrase) != 0) {
+               return FALSE;
+       }
+       return TRUE;
+ }
+ static void remove_network_information(GSupplicantInterface * interface)
+ {
+       g_free(interface->network_info.ssid);
+       g_free(interface->network_info.passphrase);
+       g_free(interface->network_info.private_passphrase);
+       interface->network_info.ssid = NULL;
+       interface->network_info.passphrase = NULL;
+       interface->network_info.private_passphrase = NULL;
+ }
+ static int store_network_information(GSupplicantInterface * interface,
+                               GSupplicantSSID *ssid)
+ {
+       interface->network_info.ssid = g_malloc(ssid->ssid_len + 1);
+       if (interface->network_info.ssid != NULL) {
+               memcpy(interface->network_info.ssid, ssid->ssid,
+                       ssid->ssid_len);
+               interface->network_info.ssid[ssid->ssid_len] = '\0';
+       } else {
+               return -ENOMEM;
+       }
+       interface->network_info.security = ssid->security;
+       if ((ssid->security == G_SUPPLICANT_SECURITY_WEP ||
+               ssid->security == G_SUPPLICANT_SECURITY_PSK ||
+               ssid->security == G_SUPPLICANT_SECURITY_NONE) &&
+               ssid->passphrase) {
+               interface->network_info.passphrase = g_strdup(ssid->passphrase);
+       }
+       if (ssid->security == G_SUPPLICANT_SECURITY_IEEE8021X &&
+                       ssid->private_key_passphrase) {
+               interface->network_info.private_passphrase =
+                       g_strdup(ssid->private_key_passphrase);
+       }
+       return 0;
+ }
  static void callback_system_ready(void)
  {
        if (system_ready)
@@@ -433,7 -525,6 +550,7 @@@ static void callback_interface_removed(
        callbacks_pointer->interface_removed(interface);
  }
  
 +#if !defined TIZEN_EXT
  static void callback_p2p_support(GSupplicantInterface *interface)
  {
        SUPPLICANT_DBG("");
        if (callbacks_pointer && callbacks_pointer->p2p_support)
                callbacks_pointer->p2p_support(interface);
  }
 +#endif
  
  static void callback_scan_started(GSupplicantInterface *interface)
  {
        callbacks_pointer->scan_started(interface);
  }
  
+ static void callback_ap_create_fail(GSupplicantInterface *interface)
+ {
+       if (!callbacks_pointer)
+               return;
+       if (!callbacks_pointer->ap_create_fail)
+               return;
+       callbacks_pointer->ap_create_fail(interface);
+ }
  static void callback_scan_finished(GSupplicantInterface *interface)
  {
        if (!callbacks_pointer)
@@@ -490,30 -591,6 +618,30 @@@ static void callback_network_removed(GS
        callbacks_pointer->network_removed(network);
  }
  
 +#if defined TIZEN_EXT
 +static void callback_network_merged(GSupplicantNetwork *network)
 +{
 +      if (!callbacks_pointer)
 +              return;
 +
 +      if (!callbacks_pointer->network_merged)
 +              return;
 +
 +      callbacks_pointer->network_merged(network);
 +}
 +
 +static void callback_assoc_failed(void *user_data)
 +{
 +      if (!callbacks_pointer)
 +              return;
 +
 +      if (!callbacks_pointer->assoc_failed)
 +              return;
 +
 +      callbacks_pointer->assoc_failed(user_data);
 +}
 +#endif
 +
  static void callback_network_changed(GSupplicantNetwork *network,
                                        const char *property)
  {
        callbacks_pointer->network_changed(network, property);
  }
  
+ static void callback_network_associated(GSupplicantNetwork *network)
+ {
+       if (!callbacks_pointer)
+               return;
+       if (!callbacks_pointer->network_associated)
+               return;
+       callbacks_pointer->network_associated(network);
+ }
  static void callback_peer_found(GSupplicantPeer *peer)
  {
        if (!callbacks_pointer)
@@@ -616,7 -704,6 +755,6 @@@ static void remove_interface(gpointer d
        GSupplicantInterface *interface = data;
  
        g_hash_table_destroy(interface->bss_mapping);
-       g_hash_table_destroy(interface->net_mapping);
        g_hash_table_destroy(interface->network_table);
        g_hash_table_destroy(interface->peer_table);
        g_hash_table_destroy(interface->group_table);
        g_free(interface->wps_cred.key);
        g_free(interface->path);
        g_free(interface->network_path);
 +#if defined TIZEN_EXT
 +      interface->network_path = NULL;
 +#endif
        g_free(interface->ifname);
        g_free(interface->driver);
        g_free(interface->bridge);
+       remove_network_information(interface);
        g_free(interface);
  }
  
@@@ -663,15 -748,6 +802,15 @@@ static void remove_network(gpointer dat
        g_free(network->path);
        g_free(network->group);
        g_free(network->name);
-       g_slist_free_full(network->vsie_list, g_free);
 +#if defined TIZEN_EXT
 +      g_free(network->eap);
 +      g_free(network->identity);
 +      g_free(network->phase2);
 +#endif
 +#if defined TIZEN_EXT
++      g_free(network->wifi_vsie);
 +#endif
 +
        g_free(network);
  }
  
@@@ -680,9 -756,6 +819,9 @@@ static void remove_bss(gpointer data
        struct g_supplicant_bss *bss = data;
  
        g_free(bss->path);
-       g_slist_free_full(bss->vsie_list, g_free);
 +#if defined TIZEN_EXT
++      g_free(bss->wifi_vsie);
 +#endif
        g_free(bss);
  }
  
@@@ -704,6 -777,7 +843,7 @@@ static void remove_peer(gpointer data
        g_free(peer->path);
        g_free(peer->name);
        g_free(peer->identifier);
+       g_free(peer->widi_ies);
  
        g_free(peer);
  }
@@@ -881,20 -955,59 +1021,59 @@@ static void interface_capability(const 
                                key, dbus_message_iter_get_arg_type(iter));
  }
  
+ struct set_apscan_data
+ {
+       unsigned int ap_scan;
+       GSupplicantInterface *interface;
+ };
  static void set_apscan(DBusMessageIter *iter, void *user_data)
  {
-       unsigned int ap_scan = *(unsigned int *)user_data;
+       struct set_apscan_data *data = user_data;
+       unsigned int ap_scan = data->ap_scan;
  
        dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &ap_scan);
  }
  
+ static void set_apscan_complete(const char *error,
+               DBusMessageIter *iter, void *user_data)
+ {
+       struct set_apscan_data *data = user_data;
+       GSupplicantInterface *interface = data->interface;
+       if (error) {
+               interface->ap_create_in_progress = false;
+               SUPPLICANT_DBG("Set AP scan error %s", error);
+               goto error;
+       }
+       interface->ap_create_in_progress = true;
+ error:
+       dbus_free(data);
+ }
  int g_supplicant_interface_set_apscan(GSupplicantInterface *interface,
                                                        unsigned int ap_scan)
  {
-       return supplicant_dbus_property_set(interface->path,
+       struct set_apscan_data *data;
+       int ret;
+       data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
+       data->ap_scan = ap_scan;
+       data->interface = interface;
+       ret = supplicant_dbus_property_set(interface->path,
                        SUPPLICANT_INTERFACE ".Interface",
-                               "ApScan", DBUS_TYPE_UINT32_AS_STRING,
-                                       set_apscan, NULL, &ap_scan, NULL);
+                       "ApScan", DBUS_TYPE_UINT32_AS_STRING,
+                       set_apscan, set_apscan_complete, data, NULL);
+       if (ret < 0)
+               dbus_free(data);
+       return ret;
  }
  
  void g_supplicant_interface_set_data(GSupplicantInterface *interface,
@@@ -988,9 -1101,6 +1167,9 @@@ unsigned int g_supplicant_interface_get
        if (!interface)
                return 0;
  
 +      if (interface->max_scan_ssids == 0)
 +              return WPAS_MAX_SCAN_SSIDS;
 +
        return interface->max_scan_ssids;
  }
  
@@@ -1191,48 -1301,6 +1370,48 @@@ const char *g_supplicant_peer_get_name(
        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)
  {
@@@ -1315,118 -1383,16 +1494,105 @@@ bool g_supplicant_peer_has_requested_co
        return peer->connection_requested;
  }
  
- void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network)
 +#if defined TIZEN_EXT
 +/*
 + * Description: Network client requires additional wifi specific info
 + */
 +const unsigned char *g_supplicant_network_get_bssid(GSupplicantNetwork *network)
 +{
 +      if (network == NULL || network->best_bss == NULL)
 +              return NULL;
 +
 +      return (const unsigned char *)network->best_bss->bssid;
 +}
 +
 +unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network)
 +{
 +      if (network == NULL || network->best_bss == NULL)
 +              return 0;
 +
 +      return network->best_bss->maxrate;
 +}
 +
 +const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
 +{
 +      if (network == NULL || network->best_bss == NULL)
 +              return NULL;
 +
 +      if (network->best_bss->security == G_SUPPLICANT_SECURITY_PSK ||
 +          network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
 +              unsigned int pairwise;
 +
 +              pairwise = network->best_bss->rsn_pairwise |
 +                              network->best_bss->wpa_pairwise;
 +
 +              if ((pairwise & G_SUPPLICANT_PAIRWISE_CCMP) &&
 +                  (pairwise & G_SUPPLICANT_PAIRWISE_TKIP))
 +                      return "mixed";
 +              else if (pairwise & G_SUPPLICANT_PAIRWISE_CCMP)
 +                      return "aes";
 +              else if (pairwise & G_SUPPLICANT_PAIRWISE_TKIP)
 +                      return "tkip";
 +
 +      } else if (network->best_bss->security == G_SUPPLICANT_SECURITY_WEP)
 +              return "wep";
 +      else if (network->best_bss->security == G_SUPPLICANT_SECURITY_NONE)
 +              return "none";
 +
 +      return NULL;
 +}
 +
 +bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network)
 +{
 +      if (network == NULL || network->best_bss == NULL)
 +              return 0;
 +
 +      if (network->best_bss->rsn_selected) {
 +              const char *mode = g_supplicant_network_get_enc_mode(network);
 +              if (g_strcmp0(mode, "aes") == 0 ||
 +                              g_strcmp0(mode, "mixed") == 0)
 +                      return true;
 +              else
 +                      return false;
 +      } else
 +              return false;
 +}
 +
-       GSList *vsie_list = NULL;
-       if (!network)
++const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
++                                              unsigned int *wifi_vsie_len)
 +{
-       if (g_slist_length(network->vsie_list) > 0) {
-               GSList *list = NULL;
-               unsigned char *vsie = NULL;
-               for (list = network->vsie_list; list; list = list->next) {
-                       unsigned char *ie = (unsigned char *)list->data;
-                       vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
-                       if (vsie) {
-                               memcpy(vsie, ie, ie[1]+2);
-                               vsie_list = g_slist_append(vsie_list, vsie);
-                       } else
-                               SUPPLICANT_DBG("Failed to allocate memory");
-               }
++      if (!network) {
++              *wifi_vsie_len = 0;
 +              return NULL;
-       return vsie_list;
 +      }
 +
++      *wifi_vsie_len = network->wifi_vsie_len;
++      return network->wifi_vsie;
 +}
 +#endif
 +
  static void merge_network(GSupplicantNetwork *network)
  {
        GString *str;
        const char *ssid, *mode, *key_mgmt;
 +#if defined TIZEN_EXT
 +      GSupplicantInterface *interface;
 +      const char *isHS20AP;
 +      const char *eap, *identity, *phase2;
 +#endif
        unsigned int i, ssid_len;
        char *group;
  
        ssid = g_hash_table_lookup(network->config_table, "ssid");
        mode = g_hash_table_lookup(network->config_table, "mode");
        key_mgmt = g_hash_table_lookup(network->config_table, "key_mgmt");
 +#if defined TIZEN_EXT
 +      isHS20AP = g_hash_table_lookup(network->config_table, "isHS20AP");
 +      eap = g_hash_table_lookup(network->config_table, "eap");
 +      identity = g_hash_table_lookup(network->config_table, "identity");
 +      phase2 = g_hash_table_lookup(network->config_table, "phase2");
 +      interface = network->interface;
 +#endif
  
        SUPPLICANT_DBG("ssid %s mode %s", ssid, mode);
  
                return;
  
        for (i = 0; i < ssid_len; i++)
 +#if defined TIZEN_EXT
 +      {
 +              if (ssid[i] != '"')
 +#endif
                g_string_append_printf(str, "%02x", ssid[i]);
 +#if defined TIZEN_EXT
 +      }
 +#endif
  
        if (g_strcmp0(mode, "0") == 0)
                g_string_append_printf(str, "_managed");
  
        if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
                g_string_append_printf(str, "_psk");
 +#if defined TIZEN_EXT
 +      else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
 +              g_string_append_printf(str, "_ieee8021x");
 +      else
 +              g_string_append_printf(str, "_none");
 +#endif
  
        group = g_string_free(str, FALSE);
  
        SUPPLICANT_DBG("%s", group);
  
 +#if defined TIZEN_EXT
 +      if (g_strcmp0(isHS20AP, "1") == 0) {
 +              network->isHS20AP = 1;
 +              if (network->eap)
 +                      g_free(network->eap);
 +              network->eap = g_strdup(eap);
 +
 +              if (network->identity)
 +                      g_free(network->identity);
 +              network->identity = g_strdup(identity);
 +
 +              if (network->phase2)
 +                      g_free(network->phase2);
 +              network->phase2 = g_strdup(phase2);
 +      } else
 +              network->isHS20AP = 0;
 +
 +      if (interface)
 +              interface->network_path = g_strdup(network->path);
 +
 +      network->group = g_strdup(group);
 +      callback_network_merged(network);
 +#endif
 +
        g_free(group);
  
        g_hash_table_destroy(network->config_table);
@@@ -1544,10 -1473,6 +1710,6 @@@ static void interface_network_added(DBu
        if (g_strcmp0(path, "/") == 0)
                return;
  
-       network = g_hash_table_lookup(interface->net_mapping, path);
-       if (network)
-               return;
        network = g_try_new0(GSupplicantNetwork, 1);
        if (!network)
                return;
  
  static void interface_network_removed(DBusMessageIter *iter, void *user_data)
  {
-       GSupplicantInterface *interface = user_data;
-       GSupplicantNetwork *network;
-       const char *path = NULL;
-       dbus_message_iter_get_basic(iter, &path);
-       if (!path)
-               return;
-       network = g_hash_table_lookup(interface->net_mapping, path);
-       if (!network)
-               return;
-       g_hash_table_remove(interface->net_mapping, path);
+       SUPPLICANT_DBG("");
+       return;
  }
  
  static char *create_name(unsigned char *ssid, int ssid_len)
@@@ -1656,7 -1570,7 +1807,7 @@@ static char *create_group(struct g_supp
        return g_string_free(str, FALSE);
  }
  
- static void add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
+ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
  {
        GSupplicantInterface *interface = bss->interface;
        GSupplicantNetwork *network;
        SUPPLICANT_DBG("New group created: %s", group);
  
        if (!group)
-               return;
+               return -ENOMEM;
  
        network = g_hash_table_lookup(interface->network_table, group);
        if (network) {
        network = g_try_new0(GSupplicantNetwork, 1);
        if (!network) {
                g_free(group);
-               return;
+               return -ENOMEM;
        }
  
        network->interface = interface;
        network->frequency = bss->frequency;
        network->best_bss = bss;
  
-       if (g_slist_length(bss->vsie_list) > 0) {
-               GSList *list = NULL;
-               unsigned char *vsie = NULL;
-               for (list = bss->vsie_list; list; list = list->next) {
-                       unsigned char *ie = (unsigned char *)list->data;
-                       vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
-                       if (vsie) {
-                               memcpy(vsie, ie, ie[1]+2);
-                               network->vsie_list = g_slist_append(network->vsie_list, vsie);
-                       } else
-                               SUPPLICANT_DBG("Failed to allocate memory.");
 +#if defined TIZEN_EXT
 +      network->keymgmt = bss->keymgmt;
 +
++      if (bss->wifi_vsie_len > 0) {
++              SUPPLICANT_DBG("vsie len: %d", bss->wifi_vsie_len);
++              network->wifi_vsie = (char *)g_try_malloc0(bss->wifi_vsie_len);
++              if(network->wifi_vsie) {
++                      network->wifi_vsie_len = bss->wifi_vsie_len;
++                      memcpy(network->wifi_vsie, bss->wifi_vsie, network->wifi_vsie_len);
++              } else {
++                      SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
 +              }
 +      }
 +
 +      network->isHS20AP = bss->hs20;
 +#endif
 +
        SUPPLICANT_DBG("New network %s created", network->name);
  
        network->bss_table = g_hash_table_new_full(g_str_hash, g_str_equal,
@@@ -1736,7 -1629,12 +1883,12 @@@ done
                network->wps_capabilities |= bss->wps_capabilities;
        }
  
-       if (bss->signal > network->signal) {
+       /*
+        * Do not change best BSS if we are connected. It will be done through
+        * CurrentBSS property in case of misalignment with wpa_s or roaming.
+        */
+       if (network != interface->current_network &&
+                               bss->signal > network->signal) {
                network->signal = bss->signal;
                network->best_bss = bss;
                callback_network_changed(network, "Signal");
        g_hash_table_replace(network->bss_table, bss->path, bss);
  
        g_hash_table_replace(bss_mapping, bss->path, interface);
+       return 0;
  }
  
  static void bss_rates(DBusMessageIter *iter, void *user_data)
@@@ -1893,6 -1793,6 +2047,9 @@@ static void bss_process_ies(DBusMessage
  {
        struct g_supplicant_bss *bss = user_data;
        const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
++#if defined TIZEN_EXT
++      const unsigned char WIFI_OUI[] = {0x00, 0x16, 0x32};
++#endif
        unsigned char *ie, *ie_end;
        DBusMessageIter array;
        unsigned int value;
  #define WPS_PBC           0x04
  #define WPS_PIN           0x00
  #define WPS_CONFIGURED    0x02
 +#if defined TIZEN_EXT
 +#define VENDOR_SPECIFIC_INFO 0xDD
 +#endif
  
        dbus_message_iter_recurse(iter, &array);
        dbus_message_iter_get_fixed_array(&array, &ie, &ie_len);
  
        for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
                                                        ie += ie[1] + 2) {
 -
 +#if defined TIZEN_EXT
-               unsigned char *vsie;
-               int vsie_len = 0;
-               if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
-                       SUPPLICANT_DBG("IE: match vendor specific data");
-                       vsie_len = ie[1]+2;     // tag number size(1), tag length size(1)
-                       vsie = (unsigned char *)g_try_malloc0(vsie_len);
-                       if (vsie) {
-                               memcpy(vsie, ie, vsie_len);
-                               bss->vsie_list = g_slist_append(bss->vsie_list, vsie);
-                       } else
-                               SUPPLICANT_DBG("Failed to allocate memory");
-                       continue;
++              if((ie[0] == VENDOR_SPECIFIC_INFO) && (memcmp(ie+2, WIFI_OUI, sizeof(WIFI_OUI)) == 0)) {
++                              SUPPLICANT_DBG("IE: match WIFI_OUI");
++                              bss->wifi_vsie = (char *)g_try_malloc0(ie[1] + 2);   // tag number size(1), tag length size(1)
++                              if (bss->wifi_vsie) {
++                                      bss->wifi_vsie_len = ie[1] + 2;
++                                      memcpy(bss->wifi_vsie, ie, bss->wifi_vsie_len);
++                              } else {
++                                      SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
++                              }
++                              continue;
 +              }
 +#endif
                if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN ||
                        memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0)
                        continue;
@@@ -1985,51 -1866,23 +2138,51 @@@ static void bss_compute_security(struc
  
        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
@@@ -2131,12 -1984,6 +2284,12 @@@ static void bss_property(const char *ke
                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
@@@ -2200,7 -2047,8 +2353,8 @@@ static void interface_bss_added_with_ke
        supplicant_dbus_property_foreach(iter, bss_property, bss);
  
        bss_compute_security(bss);
-       add_or_replace_bss_to_network(bss);
+       if (add_or_replace_bss_to_network(bss) < 0)
+               SUPPLICANT_DBG("add_or_replace_bss_to_network failed");
  }
  
  static void interface_bss_added_without_keys(DBusMessageIter *iter,
                                        bss_property, bss, NULL);
  
        bss_compute_security(bss);
-       add_or_replace_bss_to_network(bss);
+       if (add_or_replace_bss_to_network(bss) < 0)
+                       SUPPLICANT_DBG("add_or_replace_bss_to_network failed");
  }
  
  static void update_signal(gpointer key, gpointer value,
@@@ -2245,6 -2094,75 +2400,75 @@@ static void update_network_signal(GSupp
        SUPPLICANT_DBG("New network signal %d", network->signal);
  }
  
+ static void interface_current_bss(GSupplicantInterface *interface,
+                                               DBusMessageIter *iter)
+ {
+       GSupplicantNetwork *network;
+       struct g_supplicant_bss *bss;
+       const char *path;
+       dbus_message_iter_get_basic(iter, &path);
+       if (g_strcmp0(path, "/") == 0) {
+               interface->current_network = NULL;
+               return;
+       }
+       interface_bss_added_without_keys(iter, interface);
+       network = g_hash_table_lookup(interface->bss_mapping, path);
+       if (!network)
+               return;
+       bss = g_hash_table_lookup(network->bss_table, path);
+       if (!bss)
+               return;
+       interface->current_network = network;
+       if (bss != network->best_bss) {
+               /*
+                * This is the case where either wpa_s got associated
+                * to a BSS different than the one ConnMan considers
+                * the best, or we are roaming.
+                */
+               SUPPLICANT_DBG("Update best BSS for %s", network->name);
+               network->best_bss = bss;
+               if (network->signal != bss->signal) {
+                       SUPPLICANT_DBG("New network signal %d dBm",
+                                               bss->signal);
+                       network->signal = bss->signal;
+                       callback_network_changed(network, "Signal");
+               }
+       }
+       /*
+        * wpa_s could notify about CurrentBSS in any state once
+        * it got associated. It is not sure such notification will
+        * arrive together with transition to ASSOCIATED state.
+        * In fact, for networks with security WEP or OPEN, it
+        * always arrives together with transition to COMPLETED.
+        */
+       switch (interface->state) {
+       case G_SUPPLICANT_STATE_UNKNOWN:
+       case G_SUPPLICANT_STATE_DISABLED:
+       case G_SUPPLICANT_STATE_DISCONNECTED:
+       case G_SUPPLICANT_STATE_INACTIVE:
+       case G_SUPPLICANT_STATE_SCANNING:
+       case G_SUPPLICANT_STATE_AUTHENTICATING:
+       case G_SUPPLICANT_STATE_ASSOCIATING:
+               return;
+       case G_SUPPLICANT_STATE_ASSOCIATED:
+       case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
+       case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
+       case G_SUPPLICANT_STATE_COMPLETED:
+               callback_network_associated(network);
+               break;
+       }
+ }
  static void interface_bss_removed(DBusMessageIter *iter, void *user_data)
  {
        GSupplicantInterface *interface = user_data;
  
  static void set_config_methods(DBusMessageIter *iter, void *user_data)
  {
-       const char *config_methods = "push_button";
+       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
+ }
+ static void wps_property(const char *key, DBusMessageIter *iter,
+                                                       void *user_data)
+ {
+       GSupplicantInterface *interface = user_data;
+       if (!interface)
+               return;
+       SUPPLICANT_DBG("key: %s", key);
+       if (g_strcmp0(key, "ConfigMethods") == 0) {
+               const char *config_methods = "push_button", *str = NULL;
+               dbus_message_iter_get_basic(iter, &str);
+               if (str && strlen(str) > 0) {
+                       /* It was already set at wpa_s level, don't modify it. */
+                       SUPPLICANT_DBG("%s", str);
+                       return;
+               }
+               supplicant_dbus_property_set(interface->path,
+                       SUPPLICANT_INTERFACE ".Interface.WPS",
+                       "ConfigMethods", DBUS_TYPE_STRING_AS_STRING,
+                       set_config_methods, NULL, &config_methods, NULL);
+               SUPPLICANT_DBG("No value. Set %s", config_methods);
+       }
  
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
-                                                       &config_methods);
  }
  
  static void interface_property(const char *key, DBusMessageIter *iter,
                debug_strvalmap("Mode capability", mode_capa_map,
                                                interface->mode_capa);
  
-               supplicant_dbus_property_set(interface->path,
+               supplicant_dbus_property_get_all(interface->path,
                                SUPPLICANT_INTERFACE ".Interface.WPS",
-                               "ConfigMethods", DBUS_TYPE_STRING_AS_STRING,
-                               set_config_methods, NULL, NULL, NULL);
+                               wps_property, interface, interface);
  
                if (interface->ready)
                        callback_interface_added(interface);
        if (g_strcmp0(key, "Capabilities") == 0) {
                supplicant_dbus_property_foreach(iter, interface_capability,
                                                                interface);
 +#if !defined TIZEN_EXT
                if (interface->mode_capa & G_SUPPLICANT_CAPABILITY_MODE_P2P)
                        interface->p2p_support = true;
 +#endif
        } else if (g_strcmp0(key, "State") == 0) {
                const char *str = NULL;
  
                                interface->state = string2state(str);
                                callback_interface_state(interface);
                        }
+               if (interface->ap_create_in_progress) {
+                       if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED)
+                               callback_ap_create_fail(interface);
+                       interface->ap_create_in_progress = false;
+               }
                if (interface->state == G_SUPPLICANT_STATE_DISABLED)
                        interface->ready = FALSE;
                else
                        g_free(interface->bridge);
                        interface->bridge = g_strdup(str);
                }
+       } else if (g_strcmp0(key, "ConfigFile") == 0) {
+               const char *str = NULL;
+               dbus_message_iter_get_basic(iter, &str);
+               if (str && strlen(str) > 0 && interface->ifname) {
+                       SUPPLICANT_DBG("New {%s, %s}", interface->ifname, str);
+                       g_hash_table_replace(config_file_table,
+                               g_strdup(interface->ifname), g_strdup(str));
+               }
        } else if (g_strcmp0(key, "CurrentBSS") == 0) {
-               interface_bss_added_without_keys(iter, interface);
+               interface_current_bss(interface, iter);
        } else if (g_strcmp0(key, "CurrentNetwork") == 0) {
 +#if defined TIZEN_EXT
 +              if (interface->state != G_SUPPLICANT_STATE_COMPLETED)
 +#endif
                interface_network_added(iter, interface);
        } else if (g_strcmp0(key, "BSSs") == 0) {
                supplicant_dbus_array_foreach(iter,
                        dbus_message_iter_get_basic(iter, &status_code);
                        callback_assoc_status_code(interface, status_code);
                }
-       } else
+       } else {
                SUPPLICANT_DBG("key %s type %c",
                                key, dbus_message_iter_get_arg_type(iter));
+       }
  }
  
  static void scan_network_update(DBusMessageIter *iter, void *user_data)
@@@ -2447,30 -2403,15 +2714,30 @@@ static void scan_bss_data(const char *k
  {
        GSupplicantInterface *interface = user_data;
  
 +/*Fixed : stucking in scanning state when scan failed*/
 +#if defined TIZEN_EXT
 +              GSupplicantInterfaceCallback scan_callback;
 +#endif
 +
        if (iter)
                supplicant_dbus_array_foreach(iter, scan_network_update,
                                                interface);
  
 +#if defined TIZEN_EXT
 +              scan_callback = interface->scan_callback;
 +#endif
 +
        if (interface->scan_callback)
                interface->scan_callback(0, interface, interface->scan_data);
  
 +#if defined TIZEN_EXT
 +              if (interface->scan_callback == scan_callback) {
 +#endif
        interface->scan_callback = NULL;
        interface->scan_data = NULL;
 +#if defined TIZEN_EXT
 +      }
 +#endif
  }
  
  static GSupplicantInterface *interface_alloc(const char *path)
                                        g_str_equal, NULL, remove_peer);
        interface->group_table = g_hash_table_new_full(g_str_hash,
                                        g_str_equal, NULL, remove_group);
-       interface->net_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
-                                                               NULL, NULL);
        interface->bss_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                                NULL, NULL);
  
@@@ -2503,6 -2442,7 +2768,7 @@@ static void interface_added(DBusMessage
  {
        GSupplicantInterface *interface;
        const char *path = NULL;
+       bool properties_appended = GPOINTER_TO_UINT(user_data);
  
        SUPPLICANT_DBG("");
  
        if (!interface)
                return;
  
+       if (!properties_appended) {
+               supplicant_dbus_property_get_all(path,
+                                               SUPPLICANT_INTERFACE ".Interface",
+                                               interface_property, interface,
+                                               interface);
+               return;
+       }
        dbus_message_iter_next(iter);
        if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
                supplicant_dbus_property_foreach(iter, interface_property,
                                                                interface);
                interface_property(NULL, NULL, interface);
-               return;
        }
-       supplicant_dbus_property_get_all(path,
-                                       SUPPLICANT_INTERFACE ".Interface",
-                                       interface_property, interface,
-                                       interface);
  }
  
  static void interface_removed(DBusMessageIter *iter, void *user_data)
@@@ -2635,6 -2577,7 +2903,7 @@@ static void signal_name_owner_changed(c
                g_hash_table_remove_all(bss_mapping);
                g_hash_table_remove_all(peer_mapping);
                g_hash_table_remove_all(group_mapping);
+               g_hash_table_remove_all(config_file_table);
                g_hash_table_remove_all(interface_table);
                callback_system_killed();
        }
@@@ -2662,7 -2605,7 +2931,7 @@@ static void signal_interface_added(cons
        SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
  
        if (g_strcmp0(path, SUPPLICANT_PATH) == 0)
-               interface_added(iter, NULL);
+               interface_added(iter, GUINT_TO_POINTER(true));
  }
  
  static void signal_interface_removed(const char *path, DBusMessageIter *iter)
@@@ -2797,9 -2740,7 +3066,9 @@@ static void signal_bss_changed(const ch
                return;
  
        supplicant_dbus_property_foreach(iter, bss_property, bss);
 -
 +#if defined TIZEN_EXT
 +      network->frequency = bss->frequency;
 +#endif
        old_security = network->security;
        bss_compute_security(bss);
  
  
                g_hash_table_remove(interface->network_table, network->group);
  
-               add_or_replace_bss_to_network(new_bss);
+               if (add_or_replace_bss_to_network(new_bss) < 0) {
+                       /* Remove entries in hash tables to handle the
+                        * failure in add_or_replace_bss_to_network
+                        */
+                       g_hash_table_remove(bss_mapping, path);
+                       g_hash_table_remove(interface->bss_mapping, path);
+                       g_hash_table_remove(network->bss_table, path);
+               }
  
                return;
        }
  
 +#if defined TIZEN_EXT
 +      if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
 +              network->wps = TRUE;
 +              network->wps_capabilities |= bss->wps_capabilities;
 +      } else
 +              network->wps = FALSE;
 +#endif
 +
+       /* Consider only property changes of the connected BSS */
+       if (network == interface->current_network && bss != network->best_bss)
+               return;
        if (bss->signal == network->signal)
 +#ifndef TIZEN_EXT
 +              return;
 +#else
 +      {
 +              callback_network_changed(network, "");
                return;
 +      }
 +#endif
  
        /*
         * If the new signal is lower than the SSID signal, we need
         */
        if (bss->signal < network->signal) {
                if (bss != network->best_bss)
 +#ifndef TIZEN_EXT
 +                      return;
 +#else
 +              {
 +                      callback_network_changed(network, "");
                        return;
 +              }
 +#endif
                network->signal = bss->signal;
                update_network_signal(network);
        } else {
@@@ -2966,7 -2896,7 +3246,7 @@@ static void signal_wps_event(const cha
  
        if (g_strcmp0(name, "success") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
 -      else if (g_strcmp0(name, "fail") == 0)
 +      else if (g_strcmp0(name, "failed") == 0)
                interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
        else
                interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
        supplicant_dbus_property_foreach(iter, wps_event_args, interface);
  }
  
 +#if defined TIZEN_EXT
 +static void signal_power_off(const char *path, DBusMessageIter *iter)
 +{
 +      int poweroff_state = 0;
 +
 +      dbus_message_iter_get_basic(iter, &poweroff_state);
 +
 +      SUPPLICANT_DBG("poweroff_state(%d)", poweroff_state);
 +
 +      /* POWER_OFF_DIRECT 2 && POWER_OFF_RESTART 3 */
 +      if (poweroff_state != 2 && poweroff_state != 3)
 +              return;
 +
 +      if (callbacks_pointer == NULL)
 +              return;
 +
 +      if (callbacks_pointer->system_power_off == NULL)
 +              return;
 +
 +      callbacks_pointer->system_power_off();
 +}
 +#endif
 +
 +static void signal_station_connected(const char *path, DBusMessageIter *iter)
 +{
 +      GSupplicantInterface *interface;
 +      const char *sta_mac = NULL;
 +
 +      SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
 +
 +      if (callbacks_pointer->add_station == NULL)
 +              return;
 +
 +      if (g_strcmp0(path, "/") == 0)
 +              return;
 +
 +      interface = g_hash_table_lookup(interface_table, path);
 +      if (interface == NULL)
 +              return;
 +
 +      dbus_message_iter_get_basic(iter, &sta_mac);
 +      if (sta_mac == NULL)
 +              return;
 +
 +      SUPPLICANT_DBG("New station %s connected", sta_mac);
 +      callbacks_pointer->add_station(sta_mac);
 +}
 +
 +static void signal_station_disconnected(const char *path, DBusMessageIter *iter)
 +{
 +      GSupplicantInterface *interface;
 +      const char *sta_mac = NULL;
 +
 +      SUPPLICANT_DBG("path %s %s", path, SUPPLICANT_PATH);
 +
 +      if (callbacks_pointer->remove_station == NULL)
 +              return;
 +
 +      if (g_strcmp0(path, "/") == 0)
 +              return;
 +
 +      interface = g_hash_table_lookup(interface_table, path);
 +      if (interface == NULL)
 +              return;
 +
 +      dbus_message_iter_get_basic(iter, &sta_mac);
 +      if (sta_mac == NULL)
 +              return;
 +
 +      SUPPLICANT_DBG("Station %s disconnected", sta_mac);
 +      callbacks_pointer->remove_station(sta_mac);
 +}
 +
  static void create_peer_identifier(GSupplicantPeer *peer)
  {
        const unsigned char test[ETH_ALEN] = {};
@@@ -3097,7 -2954,7 +3377,7 @@@ static void peer_groups_relation(DBusMe
        if (!group)
                return;
  
-       elem = g_slist_find_custom(data->old_groups, str, g_str_equal);
+       elem = g_slist_find_custom(data->old_groups, str, (GCompareFunc)g_strcmp0);
        if (elem) {
                data->old_groups = g_slist_remove_link(data->old_groups, elem);
                peer->groups = g_slist_concat(elem, peer->groups);
@@@ -3616,12 -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  },
@@@ -3717,6 -3568,7 +3997,7 @@@ int g_supplicant_set_country(const cha
                                        const void *user_data)
  {
        struct supplicant_regdom *regdom;
+       int ret;
  
        SUPPLICANT_DBG("Country setting %s", alpha2);
  
        regdom->alpha2 = alpha2;
        regdom->user_data = user_data;
  
-       return supplicant_dbus_property_set(SUPPLICANT_PATH, SUPPLICANT_INTERFACE,
+       ret =  supplicant_dbus_property_set(SUPPLICANT_PATH, SUPPLICANT_INTERFACE,
                                        "Country", DBUS_TYPE_STRING_AS_STRING,
                                        country_params, country_result,
                                        regdom, NULL);
+       if (ret < 0) {
+               dbus_free(regdom);
+               SUPPLICANT_DBG("Unable to set Country configuration");
+       }
+       return ret;
  }
  
  int g_supplicant_interface_set_country(GSupplicantInterface *interface,
                                                        void *user_data)
  {
        struct supplicant_regdom *regdom;
+       int ret;
  
        regdom = dbus_malloc0(sizeof(*regdom));
        if (!regdom)
        regdom->alpha2 = alpha2;
        regdom->user_data = user_data;
  
-       return supplicant_dbus_property_set(interface->path,
+       ret =  supplicant_dbus_property_set(interface->path,
                                SUPPLICANT_INTERFACE ".Interface",
                                "Country", DBUS_TYPE_STRING_AS_STRING,
                                country_params, country_result,
                                        regdom, NULL);
+       if (ret < 0) {
+               dbus_free(regdom);
+               SUPPLICANT_DBG("Unable to set Country configuration");
+       }
+       return ret;
  }
  
  bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface)
@@@ -3896,43 -3760,6 +4189,6 @@@ GSupplicantPeer *g_supplicant_interface
        return peer;
  }
  
- struct interface_data {
-       GSupplicantInterface *interface;
-       char *path; /* Interface path cannot be taken from interface (above) as
-                    * it might have been freed already.
-                    */
-       GSupplicantInterfaceCallback callback;
-       void *user_data;
- };
- struct interface_create_data {
-       char *ifname;
-       char *driver;
-       char *bridge;
-       GSupplicantInterface *interface;
-       GSupplicantInterfaceCallback callback;
-       void *user_data;
- };
- struct interface_connect_data {
-       GSupplicantInterface *interface;
-       char *path;
-       GSupplicantInterfaceCallback callback;
-       union {
-               GSupplicantSSID *ssid;
-               GSupplicantPeerParams *peer;
-       };
-       void *user_data;
- };
- struct interface_scan_data {
-       GSupplicantInterface *interface;
-       char *path;
-       GSupplicantInterfaceCallback callback;
-       GSupplicantScanParams *scan_params;
-       void *user_data;
- };
  static void interface_create_data_free(struct interface_create_data *data)
  {
        g_free(data->ifname);
@@@ -3962,9 -3789,7 +4218,9 @@@ static void interface_create_property(c
        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);
@@@ -4026,6 -3851,7 +4282,7 @@@ static void interface_create_params(DBu
  {
        struct interface_create_data *data = user_data;
        DBusMessageIter dict;
+       char *config_file = NULL;
  
        SUPPLICANT_DBG("");
  
                supplicant_dbus_dict_append_basic(&dict, "BridgeIfname",
                                        DBUS_TYPE_STRING, &data->bridge);
  
+       config_file = g_hash_table_lookup(config_file_table, data->ifname);
+       if (config_file) {
+               SUPPLICANT_DBG("[%s] ConfigFile %s", data->ifname, config_file);
+               supplicant_dbus_dict_append_basic(&dict, "ConfigFile",
+                                       DBUS_TYPE_STRING, &config_file);
+       }
        supplicant_dbus_dict_close(iter, &dict);
  }
  
@@@ -4074,9 -3908,7 +4339,9 @@@ static void interface_get_result(const 
  
        if (data->callback) {
                data->callback(0, interface, data->user_data);
 +#if !defined TIZEN_EXT
                callback_p2p_support(interface);
 +#endif
        }
  
        interface_create_data_free(data);
@@@ -4162,6 -3994,7 +4427,7 @@@ static void interface_remove_result(con
  
        if (error) {
                err = -EIO;
+               SUPPLICANT_DBG("error: %s", error);
                goto done;
        }
  
@@@ -4371,11 -4204,7 +4637,11 @@@ static void interface_scan_params(DBusM
                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);
@@@ -4407,14 -4236,8 +4673,14 @@@ static int interface_ready_to_scan(GSup
        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:
@@@ -4443,13 -4266,8 +4709,13 @@@ int g_supplicant_interface_scan(GSuppli
  
        data->interface = interface;
        data->path = g_strdup(interface->path);
 +#if defined TIZEN_EXT
 +      data->interface->scan_callback = data->callback = callback;
 +      data->interface->scan_data = data->user_data = user_data;
 +#else
        data->callback = callback;
        data->user_data = user_data;
 +#endif
        data->scan_params = scan_data;
  
          interface->scan_callback = callback;
  
  static int parse_supplicant_error(DBusMessageIter *iter)
  {
-       int err = -ECANCELED;
+       int err = -ECONNABORTED;
        char *key;
  
        if (!iter)
@@@ -4504,11 -4322,7 +4770,11 @@@ static void interface_select_network_re
  
        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);
        }
  
@@@ -4526,15 -4340,9 +4792,15 @@@ static void interface_select_network_pa
  {
        struct interface_connect_data *data = user_data;
        GSupplicantInterface *interface = data->interface;
 +#if defined TIZEN_EXT
 +      GSupplicantSSID *ssid = data->ssid;
 +#endif
  
        dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
                                        &interface->network_path);
 +#if defined TIZEN_EXT
 +      dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &ssid->freq);
 +#endif
  }
  
  static void interface_add_network_result(const char *error,
  
        SUPPLICANT_DBG("PATH: %s", path);
  
-       g_free(interface->network_path);
        interface->network_path = g_strdup(path);
  
+       store_network_information(interface, data->ssid);
 +#if defined TIZEN_EXT
 +      SUPPLICANT_DBG(".Interface.SelectNetworkFreq");
 +#endif
 +
 +#if defined TIZEN_EXT
 +      supplicant_dbus_method_call(data->interface->path,
 +                      SUPPLICANT_INTERFACE ".Interface", "SelectNetworkFreq",
 +                      interface_select_network_params,
 +                      interface_select_network_result, data,
 +                      interface);
 +#else
        supplicant_dbus_method_call(data->interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "SelectNetwork",
                        interface_select_network_params,
                        interface_select_network_result, data,
                        interface);
 +#endif
  
        return;
  
@@@ -4739,10 -4536,8 +5006,10 @@@ static void add_network_security_tls(DB
        if (!ssid->private_key_path)
                return;
  
 +#if !defined TIZEN_EXT
        if (!ssid->private_key_passphrase)
                return;
 +#endif
  
        if (ssid->ca_cert_path)
                supplicant_dbus_dict_append_basic(dict, "ca_cert",
        supplicant_dbus_dict_append_basic(dict, "private_key",
                                                DBUS_TYPE_STRING,
                                                &ssid->private_key_path);
 +#if !defined TIZEN_EXT
        supplicant_dbus_dict_append_basic(dict, "private_key_passwd",
                                                DBUS_TYPE_STRING,
                                                &ssid->private_key_passphrase);
 +#endif
        supplicant_dbus_dict_append_basic(dict, "client_cert",
                                                DBUS_TYPE_STRING,
                                                &ssid->client_cert_path);
@@@ -4787,10 -4580,8 +5054,10 @@@ static void add_network_security_peap(D
                if (!ssid->private_key_path)
                        return;
  
 +#if !defined TIZEN_EXT
                if (!ssid->private_key_passphrase)
                        return;
 +#endif
  
                supplicant_dbus_dict_append_basic(dict, "client_cert",
                                                DBUS_TYPE_STRING,
                                                DBUS_TYPE_STRING,
                                                &ssid->private_key_path);
  
 +#if !defined TIZEN_EXT
                supplicant_dbus_dict_append_basic(dict, "private_key_passwd",
                                                DBUS_TYPE_STRING,
                                                &ssid->private_key_passphrase);
 +#endif
  
        }
  
        g_free(phase2_auth);
  }
  
 +#if defined TIZEN_EXT
 +static void add_network_security_aka_sim(DBusMessageIter *dict,
 +                                      GSupplicantSSID *ssid)
 +{
 +      if (!ssid->passphrase)
 +              return;
 +
 +      supplicant_dbus_dict_append_basic(dict, "password",
 +                      DBUS_TYPE_STRING,
 +                      &ssid->passphrase);
 +}
 +#endif
 +
  static void add_network_security_eap(DBusMessageIter *dict,
                                        GSupplicantSSID *ssid)
  {
        char *eap_value;
  
 +#if defined TIZEN_EXT
 +      if (!ssid->eap)
 +#else
        if (!ssid->eap || !ssid->identity)
 +#endif
                return;
  
        if (g_strcmp0(ssid->eap, "tls") == 0) {
                add_network_security_tls(dict, ssid);
        } else if (g_strcmp0(ssid->eap, "peap") == 0 ||
                                g_strcmp0(ssid->eap, "ttls") == 0) {
 +#if defined TIZEN_EXT
 +              if (!ssid->identity)
 +                      return;
 +#endif
                add_network_security_peap(dict, ssid);
 +
 +#if defined TIZEN_EXT
 +      } else if (g_strcmp0(ssid->eap, "sim") == 0 ||
 +                      g_strcmp0(ssid->eap, "aka") == 0) {
 +              add_network_security_aka_sim(dict, ssid);
 +#endif
        } else
                return;
  
        supplicant_dbus_dict_append_basic(dict, "eap",
                                                DBUS_TYPE_STRING,
                                                &eap_value);
 +#if defined TIZEN_EXT
 +      if (ssid->identity != NULL)
 +              supplicant_dbus_dict_append_basic(dict, "identity",
 +                                                      DBUS_TYPE_STRING,
 +                                                      &ssid->identity);
 +#else
        supplicant_dbus_dict_append_basic(dict, "identity",
                                                DBUS_TYPE_STRING,
                                                &ssid->identity);
 +#endif
+       if(ssid->anonymous_identity)
+               supplicant_dbus_dict_append_basic(dict, "anonymous_identity",
+                                                    DBUS_TYPE_STRING,
+                                                    &ssid->anonymous_identity);
+       if(ssid->subject_match)
+               supplicant_dbus_dict_append_basic(dict, "subject_match",
+                                                    DBUS_TYPE_STRING,
+                                                    &ssid->subject_match);
+       if(ssid->altsubject_match)
+               supplicant_dbus_dict_append_basic(dict, "altsubject_match",
+                                                    DBUS_TYPE_STRING,
+                                                    &ssid->altsubject_match);
+       if(ssid->domain_suffix_match)
+               supplicant_dbus_dict_append_basic(dict, "domain_suffix_match",
+                                                    DBUS_TYPE_STRING,
+                                                    &ssid->domain_suffix_match);
+       if(ssid->domain_match)
+               supplicant_dbus_dict_append_basic(dict, "domain_match",
+                                                    DBUS_TYPE_STRING,
+                                                    &ssid->domain_match);
  
        g_free(eap_value);
  }
@@@ -5012,20 -4791,6 +5303,20 @@@ static void add_network_security(DBusMe
                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",
@@@ -5081,28 -4846,6 +5372,28 @@@ static void interface_add_network_param
                                        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);
  }
  
@@@ -5152,12 -4895,6 +5443,12 @@@ static void interface_add_wps_params(DB
        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);
  }
  
@@@ -5174,17 -4911,7 +5465,17 @@@ static void wps_start(const char *error
                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,
@@@ -5200,145 -4927,17 +5491,147 @@@ static void wps_process_credentials(DBu
        dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
  }
  
-               ret = -EINVAL;
 +#if defined TIZEN_EXT
 +#define NETCONFIG_SERVICE "net.netconfig"
 +#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
 +#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi"
 +
 +struct dec_method_call_data {
 +      struct interface_connect_data *data;
 +      DBusPendingCall *pending_call;
 +};
 +
 +static struct dec_method_call_data decrypt_request_data;
 +
 +static void crypt_method_call_cancel(void)
 +{
 +      if (decrypt_request_data.pending_call) {
 +              dbus_pending_call_cancel(decrypt_request_data.pending_call);
 +              dbus_pending_call_unref(decrypt_request_data.pending_call);
 +              decrypt_request_data.pending_call = NULL;
 +      }
 +
 +      g_free(decrypt_request_data.data->path);
 +      g_free(decrypt_request_data.data->ssid);
 +      dbus_free(decrypt_request_data.data);
 +      decrypt_request_data.data = NULL;
 +}
 +
 +static void decryption_request_reply(DBusPendingCall *call,
 +                                              void *user_data)
 +{
 +      DBusMessage *reply;
 +      DBusError error;
 +      DBusMessageIter args;
 +      char *out_data;
 +      int ret;
 +      static gchar* origin_value = NULL;
 +      struct interface_connect_data *data = user_data;
 +
 +      g_free(origin_value);
 +      origin_value = NULL;
 +
 +      SUPPLICANT_DBG("");
 +
 +      reply = dbus_pending_call_steal_reply(call);
 +
 +      dbus_error_init(&error);
 +      if (dbus_set_error_from_message(&error, reply)) {
 +              SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message);
 +              dbus_error_free(&error);
-               ret = -EINVAL;
 +              goto done;
 +      }
 +
 +      if (dbus_message_iter_init(reply, &args) == FALSE) {
 +              SUPPLICANT_DBG("dbus_message_iter_init() failed");
- done:
 +              goto done;
 +      }
 +
 +      dbus_message_iter_get_basic(&args, &out_data);
 +
 +      origin_value = g_strdup((const gchar *)out_data);
 +      data->ssid->passphrase = origin_value;
 +
 +      ret = supplicant_dbus_method_call(data->interface->path,
 +              SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
 +              interface_add_network_params,
 +              interface_add_network_result, data,
 +              data->interface);
 +
 +      if (ret < 0) {
 +              SUPPLICANT_DBG("AddNetwork failed %d", ret);
 +              callback_assoc_failed(decrypt_request_data.data->user_data);
 +              g_free(data->path);
 +              g_free(data->ssid);
 +              dbus_free(data);
 +      }
 +
++done:
 +      dbus_message_unref(reply);
 +      dbus_pending_call_unref(call);
 +
 +      decrypt_request_data.pending_call = NULL;
 +      decrypt_request_data.data = NULL;
 +}
 +
 +static int send_decryption_request(const char *passphrase,
 +                      struct interface_connect_data *data)
 +{
 +      DBusMessage *msg = NULL;
 +      DBusPendingCall *call;
 +
 +      SUPPLICANT_DBG("Decryption request");
 +
 +      if (!passphrase) {
 +              SUPPLICANT_DBG("Invalid parameter");
 +              return -EINVAL;
 +      }
 +
 +      if (!connection)
 +              return -EINVAL;
 +
 +      msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH,
 +                      NETCONFIG_WIFI_INTERFACE, "DecryptPassphrase");
 +      if (!msg)
 +              return -EINVAL;
 +
 +      dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase,
 +                                                      DBUS_TYPE_INVALID);
 +
 +      if (!dbus_connection_send_with_reply(connection, msg,
 +                              &call, DBUS_TIMEOUT_USE_DEFAULT)) {
 +              dbus_message_unref(msg);
 +              return -EIO;
 +      }
 +
 +      if (!call) {
 +              dbus_message_unref(msg);
 +              return -EIO;
 +      }
 +
 +      decrypt_request_data.pending_call = call;
 +      decrypt_request_data.data = data;
 +
 +      dbus_pending_call_set_notify(call, decryption_request_reply, data, NULL);
 +      dbus_message_unref(msg);
 +
 +      SUPPLICANT_DBG("Decryption request succeeded");
 +
 +      return 0;
 +}
 +#endif
 +
  int g_supplicant_interface_connect(GSupplicantInterface *interface,
                                GSupplicantSSID *ssid,
                                GSupplicantInterfaceCallback callback,
                                                        void *user_data)
  {
        struct interface_connect_data *data;
-       int ret;
+       struct interface_data *intf_data;
+       int ret = 0;
+       SUPPLICANT_DBG("");
  
        if (!interface)
                return -EINVAL;
                        SUPPLICANT_INTERFACE ".Interface.WPS",
                        "ProcessCredentials", DBUS_TYPE_BOOLEAN_AS_STRING,
                        wps_process_credentials, wps_start, data, interface);
-       } else
- #if defined TIZEN_EXT
-               if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) {
-                       ret = send_decryption_request(ssid->passphrase, data);
-                       if (ret < 0)
-                               SUPPLICANT_DBG("Decryption request failed %d", ret);
+       } else {
+               /* By the time there is a request for connect and the network
+                * path is not NULL it means that connman has not removed the
+                * previous network pointer. This can happen in the case AP
+                * deauthenticated client and connman does not remove the
+                * previously connected network pointer. This causes supplicant
+                * to reallocate the memory for struct wpa_ssid again even if it
+                * is the same SSID. This causes memory usage of wpa_supplicnat
+                * to go high. The idea here is that if the previously connected
+                * network is not removed at the time of next connection attempt
+                * check if the network path is not NULL. In case it is non-NULL
+                * first remove the network and then once removal is successful, add
+                * the network.
+                */
+               if (interface->network_path != NULL) {
+                       g_free(data->path);
+                       dbus_free(data);
+                       /*
+                        * If this add network is for the same network for
+                        * which wpa_supplicant already has a profile then do
+                        * not need to add another profile. Only if the
+                        * profile that needs to get added is different from
+                        * what is there in wpa_s delete the current one. A
+                        * network is identified by its SSID, security_type
+                        * and passphrase (private passphrase in case security
+                        * type is 802.11x).
+                        */
+                       if (compare_network_parameters(interface, ssid)) {
+                               return -EALREADY;
+                       }
+                       intf_data = dbus_malloc0(sizeof(*intf_data));
+                       if (!intf_data)
+                               return -ENOMEM;
+                       intf_data->interface = interface;
+                       intf_data->path = g_strdup(interface->path);
+                       intf_data->callback = callback;
+                       intf_data->ssid = ssid;
+                       intf_data->user_data = user_data;
+                       intf_data->network_remove_in_progress = TRUE;
+                       network_remove(intf_data);
 -              } else {
 -                      ret = supplicant_dbus_method_call(interface->path,
 -                                      SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
 -                                      interface_add_network_params,
 -                                      interface_add_network_result, data,
 -                                      interface);
 -              }
 -        }
 +              } else
++#if defined TIZEN_EXT
++                      if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) {
++                              ret = send_decryption_request(ssid->passphrase, data);
++                              if (ret < 0)
++                                      SUPPLICANT_DBG("Decryption request failed %d", ret);
++                      } else
 +#endif
-               ret = supplicant_dbus_method_call(interface->path,
-                       SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
-                       interface_add_network_params,
-                       interface_add_network_result, data,
-                       interface);
++                              ret = supplicant_dbus_method_call(interface->path,
++                                              SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
++                                              interface_add_network_params,
++                                              interface_add_network_result, data,
++                                              interface);
++      }
  
        if (ret < 0) {
                g_free(data->path);
@@@ -5394,22 -5032,47 +5732,47 @@@ static void network_remove_result(cons
                                DBusMessageIter *iter, void *user_data)
  {
        struct interface_data *data = user_data;
+       struct interface_connect_data *connect_data;
        int result = 0;
  
        SUPPLICANT_DBG("");
  
        if (error) {
                result = -EIO;
+               SUPPLICANT_DBG("error: %s", error);
                if (g_strcmp0("org.freedesktop.DBus.Error.UnknownMethod",
                                                error) == 0)
                        result = -ECONNABORTED;
        }
  
-       g_free(data->path);
+       g_free(data->interface->network_path);
+       data->interface->network_path = NULL;
  
-       if (data->callback)
-               data->callback(result, data->interface, data->user_data);
+       remove_network_information(data->interface);
+       if (data->network_remove_in_progress == TRUE) {
+               data->network_remove_in_progress = FALSE;
+               connect_data = dbus_malloc0(sizeof(*connect_data));
+               if (!connect_data)
+                       return;
+               connect_data->interface = data->interface;
+               connect_data->path = g_strdup(data->path);
+               connect_data->callback = data->callback;
+               connect_data->ssid = data->ssid;
+               connect_data->user_data = data->user_data;
  
+               supplicant_dbus_method_call(data->interface->path,
+                       SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+                       interface_add_network_params,
+                       interface_add_network_result, connect_data,
+                       connect_data->interface);
+       } else {
+               if (data->callback)
+                       data->callback(result, data->interface, data->user_data);
+       }
+       g_free(data->path);
        dbus_free(data);
  }
  
@@@ -5429,16 -5092,6 +5792,16 @@@ static int network_remove(struct interf
  
        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,
@@@ -5455,25 -5108,31 +5818,31 @@@ static void interface_disconnect_result
  
        if (error) {
                result = -EIO;
+               SUPPLICANT_DBG("error: %s", error);
                if (g_strcmp0("org.freedesktop.DBus.Error.UnknownMethod",
                                                error) == 0)
                        result = -ECONNABORTED;
        }
  
-       if (result < 0 && data->callback) {
-               data->callback(result, data->interface, data->user_data);
-               data->callback = NULL;
-       }
        /* If we are disconnecting from previous WPS successful
         * association. i.e.: it did not went through AddNetwork,
         * and interface->network_path was never set. */
        if (!data->interface->network_path) {
+               if (data->callback)
+                       data->callback(result, data->interface,
+                                                       data->user_data);
                g_free(data->path);
                dbus_free(data);
                return;
        }
  
+       if (result < 0 && data->callback) {
+               data->callback(result, data->interface, data->user_data);
+               data->callback = NULL;
+       }
        if (result != -ECONNABORTED) {
                if (network_remove(data) < 0) {
                        g_free(data->path);
@@@ -5499,17 -5158,7 +5868,17 @@@ int g_supplicant_interface_disconnect(G
  
        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;
@@@ -5630,8 -5279,10 +5999,10 @@@ static void interface_p2p_connect_resul
  
        SUPPLICANT_DBG("");
  
-       if (error)
+       if (error) {
+               SUPPLICANT_DBG("error: %s", error);
                err = parse_supplicant_error(iter);
+       }
  
        if (data->callback)
                data->callback(err, data->interface, data->user_data);
@@@ -5689,6 -5340,9 +6060,9 @@@ int g_supplicant_interface_p2p_connect(
                return -ENOTSUP;
  
        data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
        data->interface = interface;
        data->path = g_strdup(interface->path);
        data->peer = peer_params;
@@@ -5833,6 -5487,9 +6207,9 @@@ int g_supplicant_interface_p2p_add_serv
                return -ENOTSUP;
  
        data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
        data->registration = true;
        data->interface = interface;
        data->service = p2p_service_params;
@@@ -5863,6 -5520,9 +6240,9 @@@ int g_supplicant_interface_p2p_del_serv
                return -ENOTSUP;
  
        data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
        data->interface = interface;
        data->service = p2p_service_params;
  
@@@ -5948,6 -5608,9 +6328,9 @@@ int g_supplicant_set_widi_ies(GSupplica
                return -EFAULT;
  
        data = dbus_malloc0(sizeof(*data));
+       if (!data)
+               return -ENOMEM;
        data->service = p2p_service_params;
        data->callback = callback;
        data->user_data = user_data;
        return -EINPROGRESS;
  }
  
 +#if defined TIZEN_EXT
 +int g_supplicant_interface_remove_network(GSupplicantInterface *interface)
 +{
 +      struct interface_data *data;
 +
 +      SUPPLICANT_DBG("");
 +
 +      if (interface == NULL)
 +              return -EINVAL;
 +
 +      if (system_available == FALSE)
 +              return -EFAULT;
 +
 +      data = dbus_malloc0(sizeof(*data));
 +      if (data == NULL)
 +              return -ENOMEM;
 +
 +      data->interface = interface;
 +
 +      return network_remove(data);
 +}
 +#endif
  
  static const char *g_supplicant_rule0 = "type=signal,"
                                        "path=" DBUS_PATH_DBUS ","
@@@ -6009,14 -5650,12 +6392,14 @@@ static const char *g_supplicant_rule4 
                        "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)
  {
@@@ -6062,6 -5701,8 +6445,8 @@@ int g_supplicant_register(const GSuppli
                                                                NULL, NULL);
        pending_peer_connection = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                                NULL, NULL);
+       config_file_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                               g_free, g_free);
  
        supplicant_dbus_setup(connection);
  
        dbus_bus_add_match(connection, g_supplicant_rule3, NULL);
        dbus_bus_add_match(connection, g_supplicant_rule4, NULL);
        dbus_bus_add_match(connection, g_supplicant_rule5, NULL);
 +#if defined TIZEN_EXT
 +      dbus_bus_add_match(connection,
 +                      "type=signal,interface=org.tizen.system.deviced.PowerOff,"
 +                      "member=ChangeState", NULL);
 +#endif
 +#if !defined TIZEN_EXT
        dbus_bus_add_match(connection, g_supplicant_rule6, NULL);
        dbus_bus_add_match(connection, g_supplicant_rule7, NULL);
        dbus_bus_add_match(connection, g_supplicant_rule8, NULL);
 +#endif
        dbus_connection_flush(connection);
  
        if (dbus_bus_name_has_owner(connection,
@@@ -6122,11 -5756,9 +6507,11 @@@ void g_supplicant_unregister(const GSup
        SUPPLICANT_DBG("");
  
        if (connection) {
 +#if !defined TIZEN_EXT
                dbus_bus_remove_match(connection, g_supplicant_rule8, NULL);
                dbus_bus_remove_match(connection, g_supplicant_rule7, NULL);
                dbus_bus_remove_match(connection, g_supplicant_rule6, NULL);
 +#endif
                dbus_bus_remove_match(connection, g_supplicant_rule5, NULL);
                dbus_bus_remove_match(connection, g_supplicant_rule4, NULL);
                dbus_bus_remove_match(connection, g_supplicant_rule3, NULL);
                                                g_supplicant_filter, NULL);
        }
  
+       if (config_file_table) {
+               g_hash_table_destroy(config_file_table);
+               config_file_table = NULL;
+       }
        if (bss_mapping) {
                g_hash_table_destroy(bss_mapping);
                bss_mapping = NULL;
diff --combined gweb/gresolv.c
index 93f156e,8a51a9f..cf16a48
mode 100755,100644..100755
@@@ -181,17 -181,15 +181,15 @@@ static void find_srcaddr(struct sort_re
        if (fd < 0)
                return;
  
-       if (connect(fd, &res->dst.sa, sizeof(res->dst)) < 0) {
-               close(fd);
-               return;
-       }
+       if (connect(fd, &res->dst.sa, sizeof(res->dst)) < 0)
+               goto out;
  
-       if (getsockname(fd, &res->src.sa, &sl) < 0) {
-               close(fd);
-               return;
-       }
+       if (getsockname(fd, &res->src.sa, &sl) < 0)
+               goto out;
  
        res->reachable = true;
+ out:
        close(fd);
  }
  
@@@ -948,12 -946,10 +946,12 @@@ bool g_resolv_add_nameserver(GResolv *r
        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);
@@@ -1055,8 -1051,6 +1053,8 @@@ guint g_resolv_lookup_hostname(GResolv 
        lookup->result_data = user_data;
        lookup->id = resolv->next_lookup_id++;
  
 +      debug(resolv, "");
 +
        if (resolv->result_family != AF_INET6) {
                if (add_query(lookup, hostname, ns_t_a)) {
                        g_free(lookup);
                }
        }
  
 +      debug(resolv, "");
 +
        if (resolv->result_family != AF_INET) {
                if (add_query(lookup, hostname, ns_t_aaaa)) {
                        if (resolv->result_family != AF_INET6) {
                }
        }
  
 +      debug(resolv, "");
 +
        g_queue_push_tail(resolv->lookup_queue, lookup);
  
        debug(resolv, "lookup %p id %d", lookup, lookup->id);
diff --combined gweb/gweb.c
index 307164e,393afe0..7037cd9
mode 100755,100644..100755
@@@ -792,6 -792,9 +792,9 @@@ static void handle_multi_line(struct we
        char *str;
        gchar *value;
  
+       if (!session->result.last_key)
+               return;
        str = session->current_header->str;
  
        if (str[0] != ' ' && str[0] != '\t')
                g_string_insert_c(session->current_header, 0, ' ');
        }
  
 +#if defined TIZEN_EXT
 +      if (session->result.last_key == NULL)
 +              return;
 +#endif
        value = g_hash_table_lookup(session->result.headers,
                                        session->result.last_key);
        if (value) {
@@@ -1079,7 -1078,6 +1082,6 @@@ static int connect_session_transport(st
                        session->addr->ai_addrlen) < 0) {
                if (errno != EINPROGRESS) {
                        debug(session->web, "connect() %s", strerror(errno));
-                       close(sk);
                        return -EIO;
                }
        }
@@@ -1259,16 -1257,6 +1261,16 @@@ static void resolv_result(GResolvResult
                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]);
  
@@@ -1360,8 -1348,7 +1362,7 @@@ static guint do_request(GWeb *web, cons
                        g_free(session->address);
                        session->address = g_strdup(host);
                }
-               session->address_action = g_timeout_add(0, already_resolved,
-                                                       session);
+               session->address_action = g_idle_add(already_resolved, session);
        } else {
                session->resolv_action = g_resolv_lookup_hostname(web->resolv,
                                        host, resolv_result, session);
@@@ -1480,6 -1467,9 +1481,9 @@@ GWebParser *g_web_parser_new(const cha
  {
        GWebParser *parser;
  
+       if (!begin || !end)
+               return NULL;
        parser = g_try_new0(GWebParser, 1);
        if (!parser)
                return NULL;
  
        parser->begin_token = g_strdup(begin);
        parser->end_token = g_strdup(end);
-       if (!parser->begin_token) {
-               g_free(parser);
-               return NULL;
-       }
        parser->func = func;
        parser->user_data = user_data;
  
diff --combined include/device.h
index dafdca2,9ac800a..36b2f55
mode 100755,100644..100755
@@@ -85,10 -85,6 +85,6 @@@ int connman_device_set_scanning(struct 
  bool connman_device_get_scanning(struct connman_device *device);
  void connman_device_reset_scanning(struct connman_device *device);
  
- int connman_device_set_disconnected(struct connman_device *device,
-                                               bool disconnected);
- bool connman_device_get_disconnected(struct connman_device *device);
  int connman_device_set_string(struct connman_device *device,
                                        const char *key, const char *value);
  const char *connman_device_get_string(struct connman_device *device,
@@@ -130,11 -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 --combined include/network.h
index baf1c01,4fc20c1..4be5fbf
mode 100755,100644..100755
@@@ -55,11 -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
@@@ -94,9 -90,6 +94,9 @@@ void connman_network_set_group(struct c
  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);
@@@ -124,41 -117,6 +124,41 @@@ int connman_network_set_nameservers(str
                                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,
@@@ -183,10 -141,6 +183,6 @@@ int connman_network_set_blob(struct con
                        const char *key, const void *data, unsigned int size);
  const void *connman_network_get_blob(struct connman_network *network,
                                        const char *key, unsigned int *size);
- #if defined TIZEN_EXT
- void connman_network_set_vsie_list(struct connman_network *network, GSList *vsie_list);
- void *connman_network_get_vsie_list(struct connman_network *network);
- #endif
  
  struct connman_device *connman_network_get_device(struct connman_network *network);
  
@@@ -203,9 -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 --combined include/provider.h
index d1a8983,d28651a..d28651a
mode 100755,100644..100755
@@@ -124,7 -124,8 +124,8 @@@ struct connman_provider_driver 
        enum connman_provider_type type;
        int (*probe) (struct connman_provider *provider);
        int (*remove) (struct connman_provider *provider);
-       int (*connect) (struct connman_provider *provider);
+       int (*connect) (struct connman_provider *provider,
+                       const char *dbus_sender);
        int (*disconnect) (struct connman_provider *provider);
        int (*save) (struct connman_provider *provider, GKeyFile *keyfile);
        int (*set_property) (struct connman_provider *provider,
diff --combined include/service.h
index ff29613,958e7fd..3055023
mode 100755,100644..100755
  
  #include <stdbool.h>
  
 +#if defined TIZEN_EXT
 +#include <glib.h>
 +#endif
 +
  #ifdef __cplusplus
  extern "C" {
  #endif
@@@ -134,49 -130,13 +134,50 @@@ bool connman_service_get_favorite(struc
  bool connman_service_get_autoconnect(struct connman_service *service);
  
  struct connman_service *connman_service_lookup_from_network(struct connman_network *network);
+ struct connman_service *connman_service_lookup_from_identifier(const char* identifier);
  
  void connman_service_create_ip4config(struct connman_service *service,
                                                                int index);
  void connman_service_create_ip6config(struct connman_service *service,
                                                                int index);
  
 +#if defined TIZEN_EXT
 +/*
 + * Description: TIZEN implements system global connection management.
 + *              It's only for PDP (cellular) bearer. Wi-Fi is managed by ConnMan automatically.
 + *              Reference count can help to manage open/close connection requests by each application.
 + */
 +
 +/*
 + * Increase reference count of user-initiated packet data network connection
 + */
 +void connman_service_user_pdn_connection_ref(struct connman_service *service);
 +
 +/*
 + * Decrease reference count of user initiated packet data network connection
 + * and return TRUE if counter is zero.
 + */
 +gboolean connman_service_user_pdn_connection_unref_and_test(
 +                                      struct connman_service *service);
 +
 +/*
 + * Test reference count of user initiated packet data network connection
 + * and return TRUE if counter is zero. No impact to reference count
 + */
 +gboolean connman_service_is_no_ref_user_pdn_connection(
 +                                      struct connman_service *service);
 +#endif
 +
 +#if defined TIZEN_EXT
 +struct connman_service *connman_service_get_default_connection(void);
 +
 +/*
 + * Description: telephony plug-in requires manual PROXY setting
 + */
 +int connman_service_set_proxy(struct connman_service *service,
 +                                      const char *proxy, gboolean active);
 +#endif
 +
  #ifdef __cplusplus
  }
  #endif
diff --combined include/session.h
index 37dfc4e,5106e88..5106e88
mode 100755,100644..100755
@@@ -22,6 -22,7 +22,7 @@@
  #ifndef __CONNMAN_SESSION_H
  #define __CONNMAN_SESSION_H
  
+ #include <stdint.h>
  #include <connman/service.h>
  
  #ifdef __cplusplus
@@@ -55,6 -56,12 +56,12 @@@ enum connman_session_id_type 
        CONNMAN_SESSION_ID_TYPE_LSM     = 3,
  };
  
+ enum connman_session_state {
+       CONNMAN_SESSION_STATE_DISCONNECTED   = 0,
+       CONNMAN_SESSION_STATE_CONNECTED      = 1,
+       CONNMAN_SESSION_STATE_ONLINE         = 2,
+ };
  struct connman_session;
  
  struct connman_session_config {
@@@ -65,6 -72,8 +72,8 @@@
        enum connman_session_type type;
        bool ecall;
        GSList *allowed_bearers;
+       char *allowed_interface;
+       bool source_ip_rule;
  };
  
  typedef int (* connman_session_config_func_t) (struct connman_session *session,
@@@ -83,8 -92,13 +92,13 @@@ struct connman_session_policy 
                                GSList *bearers);
        bool (*allowed)(struct connman_session *session,
                        struct connman_service *service);
+       void (*update_session_state)(struct connman_session* session,
+                                    enum connman_session_state state);
+       struct connman_service* (*get_service_for_session)(struct connman_session* session,
+                                                          GSList* services);
  };
  
+ uint32_t connman_session_firewall_get_fwmark(struct connman_session *session);
  int connman_session_policy_register(struct connman_session_policy *config);
  void connman_session_policy_unregister(struct connman_session_policy *config);
  
diff --combined include/technology.h
index 8efe9e7,97db660..55bb3dd
mode 100755,100644..100755
@@@ -36,11 -36,7 +36,11 @@@ extern "C" 
  
  struct connman_technology;
  
- void connman_technology_tethering_notify(struct connman_technology *technology,
 +int connman_technology_tethering_add_station(enum connman_service_type type,
 +                                            const char *mac);
 +int connman_technology_tethering_remove_station(const char *mac);
 +
+ int connman_technology_tethering_notify(struct connman_technology *technology,
                                                        bool enabled);
  int connman_technology_set_regdom(const char *alpha2);
  void connman_technology_regdom_notify(struct connman_technology *technology,
@@@ -63,7 -59,7 +63,7 @@@ struct connman_technology_driver 
                                                                int index);
        int (*set_tethering) (struct connman_technology *technology,
                                const char *identifier, const char *passphrase,
-                               const char *bridge, bool enabled, bool hidden);
+                               const char *bridge, bool enabled);
        int (*set_regdom) (struct connman_technology *technology,
                                                const char *alpha2);
  };
diff --combined packaging/connman.spec
index e99ae37,0000000..0554f9a
mode 100755,000000..100755
--- /dev/null
@@@ -1,343 -1,0 +1,343 @@@
- Version:        1.29
 +%bcond_with     connman_openconnect
 +%bcond_without  connman_openvpn
 +%bcond_without  connman_ipsec
 +%bcond_without  connman_vpnd
 +
 +Name:           connman
++Version:        1.35
 +Release:        26
 +License:        GPL-2.0+
 +Summary:        Connection Manager
 +Url:            http://connman.net
 +Group:          Network & Connectivity/Connection Management
 +Source0:        %{name}-%{version}.tar.gz
 +BuildRequires:  systemd-devel
 +BuildRequires:  pkgconfig(dbus-1)
 +BuildRequires:  pkgconfig(glib-2.0)
 +BuildRequires:  pkgconfig(gio-2.0)
 +BuildRequires:  pkgconfig(libiptc)
 +BuildRequires:  pkgconfig(xtables)
 +BuildRequires:  pkgconfig(libsmack)
 +BuildRequires:  pkgconfig(libsystemd-daemon)
 +%if %{with connman_openconnect}
 +BuildRequires:  openconnect
 +%endif
 +%if %{with connman_openvpn}
 +BuildRequires:  openvpn
 +%endif
 +%if %{with connman_ipsec}
 +BuildRequires:  strongswan
 +%endif
 +BuildRequires:  readline-devel
 +#%systemd_requires
 +Requires:       iptables
 +Requires:         systemd
 +Requires(post):   systemd
 +Requires(preun):  systemd
 +Requires(postun): systemd
 +Requires:         net-config
 +Requires:         security-config
 +Provides:       %{name}-profile_common = %{version}-%{release}
 +Provides:       %{name}-profile_mobile = %{version}-%{release}
 +Provides:       %{name}-profile_wearable = %{version}-%{release}
 +
 +%define upgrade_script_filename 500.connman_upgrade.sh
 +%define upgrade_script_path /usr/share/upgrade/scripts
 +
 +%description
 +Connection Manager provides a daemon for managing Internet connections
 +within embedded devices running the Linux operating system.
 +
 +%if %{with connman_openconnect}
 +%package plugin-openconnect
 +Summary:        Openconnect Support for Connman
 +Requires:       %{name} = %{version}
 +Requires:       openconnect
 +
 +%description plugin-openconnect
 +Openconnect Support for Connman.
 +%endif
 +
 +%if %{with connman_openvpn}
 +%package plugin-openvpn
 +Summary:        Openvpn Support for Connman
 +Requires:       %{name} = %{version}
 +Requires:       openvpn
 +
 +%description plugin-openvpn
 +OpenVPN support for Connman.
 +%endif
 +
 +%if %{with connman_ipsec}
 +%package plugin-ipsec
 +Summary:        IPsec Support for Connman
 +Requires:       %{name} = %{version}
 +Requires:       strongswan
 +
 +%description plugin-ipsec
 +OpenVPN support for Connman.
 +%endif
 +
 +%if %{with connman_vpnd}
 +%package connman-vpnd
 +Summary:        VPN Support for Connman
 +#BuildRequires:  %{name} = %{version}
 +Requires:       %{name} = %{version}
 +
 +%description connman-vpnd
 +Provides VPN support for Connman
 +%endif
 +
 +%package test
 +Summary:        Test Scripts for Connection Manager
 +Group:          Development/Tools
 +Requires:       %{name} = %{version}
 +Requires:       dbus-python
 +Requires:       pygobject
 +Requires:       python-xml
 +
 +%description test
 +Scripts for testing Connman and its functionality
 +
 +%package devel
 +Summary:        Development Files for connman
 +Group:          Development/Tools
 +Requires:       %{name} = %{version}
 +
 +%description devel
 +Header files and development files for connman.
 +
 +%package extension-tv
 +Summary:        Connman service script for TV profile
 +Requires:       %{name} = %{version}-%{release}
 +Provides:       %{name}-profile_tv = %{version}-%{release}
 +Conflicts:      %{name}-extension-ivi
 +Conflicts:      %{name}-extension-disable-eth
 +%description extension-tv
 +Supplies Tizen TV profile systemd service scripts instead of the default one.
 +This overwrites service script of %{name}.
 +
 +%package extension-ivi
 +Summary:        Connman configuration for IVI profile
 +Requires:       %{name} = %{version}-%{release}
 +Provides:       %{name}-profile_ivi = %{version}-%{release}
 +Conflicts:      %{name}-extension-tv
 +Conflicts:      %{name}-extension-disable-eth
 +%description extension-ivi
 +Supplies Tizen IVI profile configuration instead of the default one.
 +This overwrites conf file of %{name}.
 +
 +%package extension-disable-eth
 +Summary:        Connman configuration for testing which requires the ethernet to be disabled
 +Requires:       %{name} = %{version}-%{release}
 +Conflicts:      %{name}-extension-tv
 +Conflicts:      %{name}-extension-ivi
 +%description extension-disable-eth
 +Connman without ethernet support
 +This overwrites conf file of %{name}.
 +
 +%prep
 +%setup -q
 +
 +
 +%build
 +#CFLAGS+=" -DTIZEN_EXT -lsmack -Werror"
 +
 +%if %{with connman_vpnd}
 +VPN_CFLAGS+=" -DTIZEN_EXT -lsmack -Werror"
 +%endif
 +
 +chmod +x bootstrap
 +./bootstrap
 +%configure \
 +            --sysconfdir=/etc \
 +            --enable-client \
 +                      --enable-tizen-ext \
 +            --enable-pacrunner \
 +            --enable-wifi=builtin \
 +%if %{with connman_openconnect}
 +            --enable-openconnect \
 +%endif
 +%if %{with connman_openvpn}
 +            --enable-openvpn \
 +%endif
 +%if %{with connman_ipsec}
 +            --enable-ipsec \
 +%endif
 +%if 0%{?enable_connman_features}
 +            %connman_features \
 +%endif
 +            --disable-ofono \
 +            --enable-telephony=builtin \
 +            --enable-test \
 +                      --enable-loopback \
 +                      --enable-ethernet \
 +            --with-systemdunitdir=%{_libdir}/systemd/system \
 +            --enable-pie \
 +                      --disable-wispr
 +
 +make %{?_smp_mflags}
 +
 +%install
 +%make_install
 +
 +#Systemd service file
 +mkdir -p %{buildroot}%{_libdir}/systemd/system/
 +%if "%{?_lib}" == "lib64"
 +mkdir -p %{buildroot}%{_unitdir}
 +%endif
 +
 +%if "%{?_lib}" == "lib64"
 +cp src/connman_tv.service %{buildroot}%{_unitdir}/connman.service.tv
 +cp src/connman.service %{buildroot}%{_unitdir}/connman.service
 +cp vpn/connman-vpn.service %{buildroot}%{_unitdir}/connman-vpn.service
 +%else
 +cp src/connman_tv.service %{buildroot}%{_libdir}/systemd/system/connman.service.tv
 +%endif
 +
 +mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
 +ln -s ../connman.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/connman.service
 +%if "%{?_lib}" == "lib64"
 +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants
 +ln -s ../connman.service %{buildroot}%{_unitdir}/multi-user.target.wants/connman.service
 +%endif
 +
 +#Systemd socket file for DNS proxy
 +%if "%{?_lib}" == "lib64"
 +cp src/connman.socket %{buildroot}%{_unitdir}/connman.socket
 +mkdir -p %{buildroot}%{_unitdir}/sockets.target.wants
 +ln -s ../connman.socket %{buildroot}%{_unitdir}/sockets.target.wants/connman.socket
 +%else
 +cp src/connman.socket %{buildroot}%{_libdir}/systemd/system/connman.socket
 +mkdir -p %{buildroot}%{_libdir}/systemd/system/sockets.target.wants
 +ln -s ../connman.socket %{buildroot}%{_libdir}/systemd/system/sockets.target.wants/connman.socket
 +%endif
 +
 +mkdir -p %{buildroot}/%{_localstatedir}/lib/connman
 +cp resources/var/lib/connman/settings %{buildroot}/%{_localstatedir}/lib/connman/settings
 +mkdir -p %{buildroot}%{_datadir}/dbus-1/system-services
 +cp resources/usr/share/dbus-1/system-services/net.connman.service %{buildroot}%{_datadir}/dbus-1/system-services/net.connman.service
 +mkdir -p %{buildroot}/etc/connman
 +
 +cp src/main_ivi.conf %{buildroot}/etc/connman/main.conf.ivi
 +cp src/main_tv.conf %{buildroot}/etc/connman/main.conf.tv
 +cp src/main_disable_eth.conf %{buildroot}/etc/connman/main.conf.disable.eth
 +cp src/main.conf %{buildroot}/etc/connman/main.conf
 +
 +rm %{buildroot}%{_sysconfdir}/dbus-1/system.d/*.conf
 +mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d/
 +cp src/connman.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/
 +
 +%if %{with connman_vpnd}
 +cp vpn/vpn-dbus.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/connman-vpn-dbus.conf
 +%endif
 +
 +#OS Upgrade
 +mkdir -p %{buildroot}%{upgrade_script_path}
 +cp -f scripts/%{upgrade_script_filename} %{buildroot}%{upgrade_script_path}
 +
 +%post
 +#chsmack -a 'System' /%{_localstatedir}/lib/connman
 +#chsmack -a 'System' /%{_localstatedir}/lib/connman/settings
 +
 +%preun
 +
 +%postun
 +systemctl daemon-reload
 +
 +%docs_package
 +
 +%files
 +%manifest connman.manifest
 +%attr(500,network_fw,network_fw) %{_bindir}/connmand
 +%attr(500,network_fw,network_fw) %{_bindir}/connmanctl
 +%attr(755,network_fw,network_fw) /%{_localstatedir}/lib/connman
 +%attr(600,network_fw,network_fw) /%{_localstatedir}/lib/connman/settings
 +%attr(644,root,root) %{_datadir}/dbus-1/system-services/net.connman.service
 +%{_sysconfdir}/dbus-1/system.d/*
 +%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf
 +%{_sysconfdir}/dbus-1/system.d/*.conf
 +%attr(644,root,root) %{_libdir}/systemd/system/connman.service
 +%attr(644,root,root) %{_libdir}/systemd/system/multi-user.target.wants/connman.service
 +%if "%{?_lib}" == "lib64"
 +%attr(644,root,root) %{_unitdir}/connman.service
 +%attr(644,root,root) %{_unitdir}/multi-user.target.wants/connman.service
 +%attr(644,root,root) %{_unitdir}/connman.socket
 +%attr(644,root,root) %{_unitdir}/sockets.target.wants/connman.socket
 +%else
 +%attr(644,root,root) %{_libdir}/systemd/system/connman.socket
 +%attr(644,root,root) %{_libdir}/systemd/system/sockets.target.wants/connman.socket
 +%endif
 +%license COPYING
 +%{upgrade_script_path}/%{upgrade_script_filename}
 +
 +%files test
 +%manifest connman.manifest
 +%{_libdir}/%{name}/test/*
 +
 +%files devel
 +%manifest connman.manifest
 +%{_includedir}/*
 +%{_libdir}/pkgconfig/*.pc
 +
 +%if %{with connman_openconnect}
 +%files plugin-openconnect
 +%manifest %{name}.manifest
 +%{_libdir}/connman/plugins-vpn/openconnect.so
 +%{_libdir}/connman/scripts/openconnect-script
 +%license COPYING
 +%endif
 +
 +%if %{with connman_openvpn}
 +%files plugin-openvpn
 +%manifest %{name}.manifest
 +%{_libdir}/%{name}/plugins-vpn/openvpn.so
 +%{_libdir}/%{name}/scripts/openvpn-script
 +%license COPYING
 +%endif
 +
 +%if %{with connman_ipsec}
 +%files plugin-ipsec
 +%manifest %{name}.manifest
 +%{_libdir}/%{name}/plugins-vpn/ipsec.so
 +%{_libdir}/%{name}/scripts/ipsec-script
 +%license COPYING
 +%endif
 +
 +%if %{with connman_vpnd}
 +%files connman-vpnd
 +%manifest %{name}.manifest
 +%{_bindir}/connman-vpnd
 +%dir %{_libdir}/%{name}
 +%dir %{_libdir}/%{name}/scripts
 +%dir %{_libdir}/%{name}/plugins-vpn
 +%config %{_sysconfdir}/dbus-1/system.d/connman-vpn-dbus.conf
 +%{_datadir}/dbus-1/system-services/net.connman.vpn.service
 +%license COPYING
 +%attr(644,root,root) %{_libdir}/systemd/system/connman-vpn.service
 +%if "%{?_lib}" == "lib64"
 +%attr(644,root,root) %{_unitdir}/connman-vpn.service
 +%endif
 +%endif
 +
 +%post extension-tv
 +mv -f %{_libdir}/systemd/system/connman.service.tv %{_libdir}/systemd/system/connman.service
 +mv -f %{_sysconfdir}/connman/main.conf.tv %{_sysconfdir}/connman/main.conf
 +%files extension-tv
 +%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf.tv
 +%license COPYING
 +%if "%{?_lib}" == "lib64"
 +%attr(644,root,root) %{_unitdir}/connman.service.tv
 +%else
 +%attr(644,root,root) %{_libdir}/systemd/system/connman.service.tv
 +%endif
 +%post extension-ivi
 +mv -f %{_sysconfdir}/connman/main.conf.ivi %{_sysconfdir}/connman/main.conf
 +%files extension-ivi
 +%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf.ivi
 +%license COPYING
 +%post extension-disable-eth
 +mv -f %{_sysconfdir}/connman/main.conf.disable.eth %{_sysconfdir}/connman/main.conf
 +%files extension-disable-eth
 +%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf.disable.eth
 +%license COPYING
diff --combined plugins/bluetooth.c
index f72a4af,f759a90..f89edfa
mode 100755,100644..100755
@@@ -192,14 -192,8 +192,14 @@@ static bool pan_connect(struct bluetoot
                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;
  }
@@@ -212,23 -206,11 +212,23 @@@ static void pan_connect_cb(DBusMessage 
        DBusMessageIter iter;
  
        pan = g_hash_table_lookup(networks, path);
-       if (!pan) {
+       if (!pan || !pan->network) {
                DBG("network already removed");
                return;
        }
  
 +#ifdef TIZEN_EXT
 +      /*
 +       * Network could be removed because of BT adapter power off
 +       * This is to handle the scenario where network is removed
 +       * before the connect_cb is called
 +       */
 +      if (!pan->network) {
 +              DBG("network already removed");
 +              return;
 +      }
 +#endif
 +
        if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
                const char *dbus_error = dbus_message_get_error_name(message);
  
  
                if (strcmp(dbus_error,
                                "org.bluez.Error.AlreadyConnected") != 0) {
+                       connman_network_set_associating(pan->network, false);
                        connman_network_set_error(pan->network,
                                CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
                        return;
@@@ -279,9 -262,6 +280,9 @@@ static int bluetooth_pan_connect(struc
                        g_strdup(path), g_free))
                return -EIO;
  
 +#if defined TIZEN_EXT
 +      if (pan->network)
 +#endif
        connman_network_set_associating(pan->network, true);
  
        return -EINPROGRESS;
@@@ -293,7 -273,7 +294,7 @@@ static void pan_disconnect_cb(DBusMessa
        struct bluetooth_pan *pan;
  
        pan = g_hash_table_lookup(networks, path);
-       if (!pan) {
+       if (!pan || !pan->network) {
                DBG("network already removed");
                return;
        }
  
        DBG("network %p", pan->network);
  
 +#if defined TIZEN_EXT
 +      if (pan->network)
 +#endif
        connman_network_set_connected(pan->network, false);
  }
  
@@@ -322,11 -299,6 +323,11 @@@ static int bluetooth_pan_disconnect(str
        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",
@@@ -366,6 -338,7 +367,7 @@@ static void pan_create_nap(struct bluet
  {
        struct connman_device *device;
        const char* role;
+       const char *adapter;
  
        role = proxy_get_role(pan->btdevice_proxy);
        if (!role) {
                return;
        }
  
-       device = g_hash_table_lookup(devices,
-                       proxy_get_string(pan->btdevice_proxy, "Adapter"));
+       adapter = proxy_get_string(pan->btdevice_proxy, "Adapter");
+       if (!adapter)
+               return;
+       device = g_hash_table_lookup(devices, adapter);
  
        if (!device || !connman_device_get_powered(device))
                return;
@@@ -547,10 -524,7 +553,10 @@@ static void device_enable_cb(const DBus
                goto out;
        }
  
 +#if !defined TIZEN_EXT
        enable_device(device, path);
 +#endif
 +
  out:
        g_free(path);
  }
@@@ -617,9 -591,7 +623,9 @@@ static void device_disable_cb(const DBu
                goto out;
        }
  
 +#if !defined TIZEN_EXT
        disable_device(device, path);
 +#endif
  
  out:
        g_free(path);
@@@ -740,21 -712,23 +746,23 @@@ static bool tethering_create(const cha
                struct connman_technology *technology, const char *bridge,
                bool enabled)
  {
-       struct tethering_info *tethering;
+       struct tethering_info *tethering = g_new0(struct tethering_info, 1);
        GDBusProxy *proxy;
        const char *method;
        bool result;
  
        DBG("path %s bridge %s", path, bridge);
  
-       if (!bridge)
-               return -EINVAL;
+       if (!bridge) {
+               g_free(tethering);
+               return false;
+       }
  
        proxy = g_dbus_proxy_new(client, path, "org.bluez.NetworkServer1");
-       if (!proxy)
+       if (!proxy) {
+               g_free(tethering);
                return false;
-       tethering = g_new0(struct tethering_info, 1);
+       }
  
        tethering->technology = technology;
        tethering->bridge = g_strdup(bridge);
@@@ -909,7 -883,7 +917,7 @@@ static void bluetooth_tech_remove(struc
  
  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 --combined plugins/ethernet.c
index 73494f1,9a4d741..9a4d741
mode 100755,100644..100755
@@@ -32,6 -32,7 +32,7 @@@
  
  #include <linux/if_vlan.h>
  #include <linux/sockios.h>
+ #include <linux/ethtool.h>
  
  #ifndef IFF_LOWER_UP
  #define IFF_LOWER_UP  0x10000
@@@ -83,6 -84,48 +84,48 @@@ static int get_vlan_vid(const char *ifn
        return vid;
  }
  
+ static int get_dsa_port(const char *ifname)
+ {
+       int sk;
+       int dsaport = -1;
+       struct ifreq ifr;
+       struct ethtool_cmd cmd;
+       struct ethtool_drvinfo drvinfocmd;
+       struct vlan_ioctl_args vifr;
+       sk = socket(AF_INET, SOCK_STREAM, 0);
+       if (sk < 0)
+               return -errno;
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+       /* check if it is a vlan and get physical interface name*/
+       vifr.cmd = GET_VLAN_REALDEV_NAME_CMD;
+       strncpy(vifr.device1, ifname, sizeof(vifr.device1));
+       if(ioctl(sk, SIOCSIFVLAN, &vifr) >= 0)
+               strncpy(ifr.ifr_name, vifr.u.device2, sizeof(ifr.ifr_name));
+       /* get driver info */
+       drvinfocmd.cmd =  ETHTOOL_GDRVINFO;
+       ifr.ifr_data = (caddr_t)&drvinfocmd;
+       if (!ioctl(sk, SIOCETHTOOL, &ifr)) {
+               if(!strcmp(drvinfocmd.driver, "dsa")) {
+                       /* get dsa port*/
+                       cmd.cmd =  ETHTOOL_GSET;
+                       ifr.ifr_data = (caddr_t)&cmd;
+                       if (!ioctl(sk, SIOCETHTOOL, &ifr))
+                               dsaport = cmd.phy_address;
+               }
+       }
+       close(sk);
+       return dsaport;
+ }
  static int eth_network_probe(struct connman_network *network)
  {
        DBG("network %p", network);
@@@ -126,7 -169,7 +169,7 @@@ static void add_network(struct connman_
                        struct ethernet_data *ethernet)
  {
        struct connman_network *network;
-       int index, vid;
+       int index;
        char *ifname;
  
        network = connman_network_create("carrier",
        ifname = connman_inet_ifname(index);
        if (!ifname)
                return;
-       vid = get_vlan_vid(ifname);
  
        connman_network_set_name(network, "Wired");
  
        }
  
        if (!eth_tethering) {
-               char group[10] = "cable";
+               char group[16] = "cable";
+               int vid, dsaport;
+               vid = get_vlan_vid(ifname);
+               dsaport = get_dsa_port(ifname);
                /*
                 * Prevent service from starting the reconnect
                 * procedure as we do not want the DHCP client
                 * to run when tethering.
                 */
-               if (vid >= 0)
+               if((vid >= 0) && (dsaport >= 0))
+                       snprintf(group, sizeof(group), "p%02x_%03x_cable", dsaport, vid);
+               else if (vid >= 0)
                        snprintf(group, sizeof(group), "%03x_cable", vid);
+               else if (dsaport >= 0)
+                       snprintf(group, sizeof(group), "p%02x_cable", dsaport);
  
                connman_network_set_group(network, group);
        }
@@@ -353,7 -404,7 +404,7 @@@ static void eth_tech_disable_tethering(
  
  static int eth_tech_set_tethering(struct connman_technology *technology,
                                const char *identifier, const char *passphrase,
-                               const char *bridge, bool enabled, bool hidden)
+                               const char *bridge, bool enabled)
  {
        if (!connman_technology_is_tethering_allowed(
                        CONNMAN_SERVICE_TYPE_ETHERNET))
diff --combined plugins/gadget.c
index 6bc37a7,94f6648..cce51e2
mode 100755,100644..100755
@@@ -25,8 -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
@@@ -228,71 -226,6 +228,71 @@@ static struct connman_device_driver gad
  };
  
  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)
@@@ -313,8 -246,6 +313,8 @@@ static void gadget_tech_remove_interfac
  
        cdc_interface_list = g_list_remove(cdc_interface_list,
                                        GINT_TO_POINTER((int) index));
 +
 +      remove_station(index);
  }
  
  static void gadget_tech_enable_tethering(struct connman_technology *technology,
                connman_inet_ifup(index);
  
                connman_inet_add_to_bridge(index, bridge);
 +
 +              add_station(index);
        }
  }
  
@@@ -354,8 -283,6 +354,8 @@@ static void gadget_tech_disable_tetheri
  
                connman_inet_remove_from_bridge(index, bridge);
  
 +              remove_station(index);
 +
                connman_inet_ifdown(index);
  
                connman_technology_tethering_notify(technology, false);
  
  static int gadget_tech_set_tethering(struct connman_technology *technology,
                                const char *identifier, const char *passphrase,
-                               const char *bridge, bool enabled, bool hidden)
+                               const char *bridge, bool enabled)
  {
        DBG("bridge %s enabled %d", bridge, enabled);
  
  
  static int gadget_tech_probe(struct connman_technology *technology)
  {
 +      DBG("tech probe %p", technology);
 +
 +      cdc_mac_hash = g_hash_table_new_full(g_direct_hash,
 +                                       g_direct_equal, NULL, g_free);
 +
        return 0;
  }
  
  static void gadget_tech_remove(struct connman_technology *technology)
  {
 +      DBG("tech remove %p", technology);
 +
        g_list_free(cdc_interface_list);
  
        cdc_interface_list = NULL;
 +
 +      if (cdc_mac_hash) {
 +              g_hash_table_foreach_remove(cdc_mac_hash, remove_all_station,
 +                                              NULL);
 +              g_hash_table_destroy(cdc_mac_hash);
 +              cdc_mac_hash = NULL;
 +      }
  }
  
  static struct connman_technology_driver gadget_tech_driver = {
diff --combined plugins/neard.c
index 1a0fc1c,69586df..69586df
mode 100755,100644..100755
@@@ -534,10 -534,8 +534,8 @@@ static void register_agent(void
                        &path, DBUS_TYPE_STRING, &type, DBUS_TYPE_INVALID);
  
        if (!dbus_connection_send_with_reply(connection, message,
-                                               &register_call, TIMEOUT)) {
-               dbus_message_unref(message);
+                                               &register_call, TIMEOUT))
                goto out;
-       }
  
        if (!dbus_pending_call_set_notify(register_call,
                                                register_agent_cb, NULL, NULL))
diff --combined plugins/ofono.c
index 5cd8302,78f8f19..78f8f19
mode 100755,100644..100755
@@@ -133,6 -133,7 +133,7 @@@ static GHashTable *context_hash
  struct network_context {
        char *path;
        int index;
+       struct connman_network *network;
  
        enum connman_ipconfig_method ipv4_method;
        struct connman_ipaddress *ipv4_address;
        enum connman_ipconfig_method ipv6_method;
        struct connman_ipaddress *ipv6_address;
        char *ipv6_nameservers;
+       int refcount;
+       bool active;
+       bool valid_apn; /* APN is 'valid' if length > 0 */
  };
  
  struct modem_data {
        char *path;
  
        struct connman_device *device;
-       struct connman_network *network;
  
-       struct network_context *context;
+       GSList *context_list;
  
        /* Modem Interface */
        char *serial;
        bool attached;
        bool cm_powered;
  
-       /* ConnectionContext Interface */
-       bool active;
-       bool valid_apn; /* APN is 'valid' if length > 0 */
        /* SimManager Interface */
        char *imsi;
  
@@@ -219,6 -220,40 +220,40 @@@ static char *get_ident(const char *path
        return pos + 1;
  }
  
+ static struct network_context *get_context_with_path(GSList *context_list,
+                                               const gchar *path)
+ {
+       GSList *list;
+       DBG("path %s", path);
+       for (list = context_list; list; list = list->next) {
+               struct network_context *context = list->data;
+               if (g_strcmp0(context->path, path) == 0)
+                       return context;
+       }
+       return NULL;
+ }
+ static struct network_context *get_context_with_network(GSList *context_list,
+                               const struct connman_network *network)
+ {
+       GSList *list;
+       DBG("network %p", network);
+       for (list = context_list; list; list = list->next) {
+               struct network_context *context = list->data;
+               if (context->network == network)
+                       return context;
+       }
+       return NULL;
+ }
  static struct network_context *network_context_alloc(const char *path)
  {
        struct network_context *context;
        context->ipv6_address = NULL;
        context->ipv6_nameservers = NULL;
  
+       context->refcount = 1;
        return context;
  }
  
- static void network_context_free(struct network_context *context)
+ static void network_context_ref(struct network_context *context)
+ {
+       DBG("%p ref %d", context, context->refcount + 1);
+       __sync_fetch_and_add(&context->refcount, 1);
+ }
+ static void network_context_unref(struct network_context *context)
  {
+       DBG("%p ref %d", context, context->refcount - 1);
+       if (__sync_fetch_and_sub(&context->refcount, 1) != 1)
+               return;
        g_free(context->path);
  
        connman_ipaddress_free(context->ipv4_address);
        connman_ipaddress_free(context->ipv6_address);
        g_free(context->ipv6_nameservers);
  
-       free(context);
+       g_free(context);
  }
  
- static void set_connected(struct modem_data *modem)
+ static void set_connected(struct modem_data *modem,
+                       struct network_context *context)
  {
        struct connman_service *service;
        bool setip = false;
  
        DBG("%s", modem->path);
  
-       index = modem->context->index;
+       index = context->index;
  
-       method = modem->context->ipv4_method;
-       if (index < 0 || (!modem->context->ipv4_address &&
+       method = context->ipv4_method;
+       if (index < 0 || (!context->ipv4_address &&
                                method == CONNMAN_IPCONFIG_METHOD_FIXED)) {
                connman_error("Invalid index and/or address");
                return;
        }
  
-       service = connman_service_lookup_from_network(modem->network);
+       service = connman_service_lookup_from_network(context->network);
        if (!service)
                return;
  
        connman_service_create_ip4config(service, index);
-       connman_network_set_ipv4_method(modem->network, method);
+       connman_network_set_ipv4_method(context->network, method);
  
        if (method == CONNMAN_IPCONFIG_METHOD_FIXED ||
                        method == CONNMAN_IPCONFIG_METHOD_DHCP) {
        }
  
        if (method == CONNMAN_IPCONFIG_METHOD_FIXED) {
-               connman_network_set_ipaddress(modem->network,
-                                               modem->context->ipv4_address);
+               connman_network_set_ipaddress(context->network,
+                                               context->ipv4_address);
        }
  
-       method = modem->context->ipv6_method;
+       method = context->ipv6_method;
        connman_service_create_ip6config(service, index);
-       connman_network_set_ipv6_method(modem->network, method);
+       connman_network_set_ipv6_method(context->network, method);
  
        if (method == CONNMAN_IPCONFIG_METHOD_AUTO) {
                setip = true;
        }
  
        /* Set the nameservers */
-       if (modem->context->ipv4_nameservers &&
-                       modem->context->ipv6_nameservers) {
+       if (context->ipv4_nameservers &&
+                   context->ipv6_nameservers) {
                nameservers = g_strdup_printf("%s %s",
-                                       modem->context->ipv4_nameservers,
-                                       modem->context->ipv6_nameservers);
-               connman_network_set_nameservers(modem->network, nameservers);
+                                   context->ipv4_nameservers,
+                                   context->ipv6_nameservers);
+               connman_network_set_nameservers(context->network, nameservers);
                g_free(nameservers);
-       } else if (modem->context->ipv4_nameservers) {
-               connman_network_set_nameservers(modem->network,
-                                       modem->context->ipv4_nameservers);
-       } else if (modem->context->ipv6_nameservers) {
-               connman_network_set_nameservers(modem->network,
-                                       modem->context->ipv6_nameservers);
+       } else if (context->ipv4_nameservers) {
+               connman_network_set_nameservers(context->network,
+                                   context->ipv4_nameservers);
+       } else if (context->ipv6_nameservers) {
+               connman_network_set_nameservers(context->network,
+                                   context->ipv6_nameservers);
        }
  
        if (setip) {
-               connman_network_set_index(modem->network, index);
-               connman_network_set_connected(modem->network, true);
+               connman_network_set_index(context->network, index);
+               connman_network_set_connected(context->network, true);
        }
  }
  
- static void set_disconnected(struct modem_data *modem)
+ static void set_disconnected(struct network_context *context)
  {
-       DBG("%s", modem->path);
+       DBG("%s", context->path);
  
-       if (modem->network)
-               connman_network_set_connected(modem->network, false);
+       if (context->network)
+               connman_network_set_connected(context->network, false);
  
-       if (modem->context) {
-               g_free(modem->context->ipv4_nameservers);
-               modem->context->ipv4_nameservers = NULL;
-               if (modem->context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
-                       modem->context->ipv4_method =
-                                       CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+       g_free(context->ipv4_nameservers);
+       context->ipv4_nameservers = NULL;
+       if (context->ipv4_method != CONNMAN_IPCONFIG_METHOD_OFF)
+               context->ipv4_method =
+                       CONNMAN_IPCONFIG_METHOD_UNKNOWN;
  
-               g_free(modem->context->ipv6_nameservers);
-               modem->context->ipv6_nameservers = NULL;
-               if (modem->context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
-                       modem->context->ipv6_method =
-                                       CONNMAN_IPCONFIG_METHOD_UNKNOWN;
-       }
+       g_free(context->ipv6_nameservers);
+       context->ipv6_nameservers = NULL;
+       if (context->ipv6_method != CONNMAN_IPCONFIG_METHOD_OFF)
+               context->ipv6_method =
+                       CONNMAN_IPCONFIG_METHOD_UNKNOWN;
  }
  
  typedef void (*set_property_cb)(struct modem_data *data,
-                               bool success);
+                               struct network_context *context, bool success);
  typedef void (*get_properties_cb)(struct modem_data *data,
                                DBusMessageIter *dict);
  
  struct property_info {
        struct modem_data *modem;
+       struct network_context *context;
        const char *path;
        const char *interface;
        const char *property;
        get_properties_cb get_properties_cb;
  };
  
+ static void free_property_info(void * memory)
+ {
+       struct property_info * info = memory;
+       if (info->context)
+               network_context_unref(info->context);
+       g_free(info);
+ }
  static void set_property_reply(DBusPendingCall *call, void *user_data)
  {
        struct property_info *info = user_data;
        }
  
        if (info->set_property_cb)
-               (*info->set_property_cb)(info->modem, success);
+               (*info->set_property_cb)(info->modem, info->context,
+                                               success);
  
        dbus_message_unref(reply);
  
  }
  
  static int set_property(struct modem_data *modem,
+                       struct network_context *context,
                        const char *path, const char *interface,
                        const char *property, int type, void *value,
                        set_property_cb notify)
  
        if (modem->call_set_property) {
                DBG("Cancel pending SetProperty");
                dbus_pending_call_cancel(modem->call_set_property);
+               dbus_pending_call_unref(modem->call_set_property);
                modem->call_set_property = NULL;
        }
  
        }
  
        info->modem = modem;
+       info->context = context;
        info->path = path;
        info->interface = interface;
        info->property = property;
        info->set_property_cb = notify;
  
+       if (info->context)
+               network_context_ref(info->context);
        dbus_pending_call_set_notify(modem->call_set_property,
-                                       set_property_reply, info, g_free);
+                               set_property_reply, info, free_property_info);
  
        dbus_message_unref(message);
  
@@@ -542,9 -607,9 +607,9 @@@ static int get_properties(const char *p
  }
  
  static void context_set_active_reply(struct modem_data *modem,
-                                       bool success)
+                               struct network_context *context, bool success)
  {
-       DBG("%s", modem->path);
+       DBG("%s", context->path);
  
        if (success) {
                /*
         * cycle the modem in such cases?
         */
  
-       if (!modem->network) {
+       if (!context->network) {
                /*
                 * In the case where we power down the device
                 * we don't wait for the reply, therefore the network
                return;
        }
  
-       connman_network_set_error(modem->network,
+       connman_network_set_error(context->network,
                                CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
  }
  
  static int context_set_active(struct modem_data *modem,
-                               dbus_bool_t active)
+                       struct network_context *context,
+                       dbus_bool_t active)
  {
        int err;
  
        DBG("%s active %d", modem->path, active);
  
-       err = set_property(modem, modem->context->path,
+       err = set_property(modem, context, context->path,
                                OFONO_CONTEXT_INTERFACE,
                                "Active", DBUS_TYPE_BOOLEAN,
                                &active,
  }
  
  static void cdma_cm_set_powered_reply(struct modem_data *modem,
-                                       bool success)
+                               struct network_context *context, bool success)
  {
-       DBG("%s", modem->path);
+       DBG("%s", context->path);
  
        if (success) {
                /*
         * cycle the modem in such cases?
         */
  
-       if (!modem->network) {
+       if (!context->network) {
                /*
                 * In the case where we power down the device
                 * we don't wait for the reply, therefore the network
                return;
        }
  
-       connman_network_set_error(modem->network,
+       connman_network_set_error(context->network,
                                CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
  }
  
  static int cdma_cm_set_powered(struct modem_data *modem, dbus_bool_t powered)
  {
        int err;
+       struct network_context *context = NULL;
+       if (!modem->context_list)
+               return -1;
  
        DBG("%s powered %d", modem->path, powered);
  
-       err = set_property(modem, modem->path, OFONO_CDMA_CM_INTERFACE,
+       /* In case of CDMA, there is only one context */
+       context = modem->context_list->data;
+       err = set_property(modem, context, modem->path,
+                               OFONO_CDMA_CM_INTERFACE,
                                "Powered", DBUS_TYPE_BOOLEAN,
                                &powered,
                                cdma_cm_set_powered_reply);
@@@ -647,7 -720,7 +720,7 @@@ static int modem_set_online(struct mode
  {
        DBG("%s online %d", modem->path, online);
  
-       return set_property(modem, modem->path,
+       return set_property(modem, NULL, modem->path,
                                OFONO_MODEM_INTERFACE,
                                "Online", DBUS_TYPE_BOOLEAN,
                                &online,
@@@ -660,7 -733,7 +733,7 @@@ static int cm_set_powered(struct modem_
  
        DBG("%s powered %d", modem->path, powered);
  
-       err = set_property(modem, modem->path,
+       err = set_property(modem, NULL, modem->path,
                                OFONO_CM_INTERFACE,
                                "Powered", DBUS_TYPE_BOOLEAN,
                                &powered,
@@@ -680,7 -753,7 +753,7 @@@ static int modem_set_powered(struct mod
  
        modem->set_powered = powered;
  
-       err = set_property(modem, modem->path,
+       err = set_property(modem, NULL, modem->path,
                                OFONO_MODEM_INTERFACE,
                                "Powered", DBUS_TYPE_BOOLEAN,
                                &powered,
@@@ -768,7 -841,6 +841,6 @@@ static void extract_ipv4_settings(DBusM
  
        connman_ipaddress_free(context->ipv4_address);
        context->ipv4_address = NULL;
-       context->index = -1;
  
        if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
                return;
@@@ -871,7 -943,6 +943,6 @@@ static void extract_ipv6_settings(DBusM
  
        connman_ipaddress_free(context->ipv6_address);
        context->ipv6_address = NULL;
-       context->index = -1;
  
        if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
                return;
@@@ -1017,71 -1088,68 +1088,68 @@@ static void destroy_device(struct modem
  
        connman_device_set_powered(modem->device, false);
  
-       if (modem->network) {
-               connman_device_remove_network(modem->device, modem->network);
-               connman_network_unref(modem->network);
-               modem->network = NULL;
-       }
        connman_device_unregister(modem->device);
        connman_device_unref(modem->device);
  
        modem->device = NULL;
  }
  
- static void add_network(struct modem_data *modem)
+ static void add_network(struct modem_data *modem,
+                       struct network_context *context)
  {
        const char *group;
  
        DBG("%s", modem->path);
  
-       if (modem->network)
+       if (context->network)
                return;
  
-       modem->network = connman_network_create(modem->context->path,
-                                               CONNMAN_NETWORK_TYPE_CELLULAR);
-       if (!modem->network)
+       context->network = connman_network_create(context->path,
+                                       CONNMAN_NETWORK_TYPE_CELLULAR);
+       if (!context->network)
                return;
  
-       DBG("network %p", modem->network);
+       DBG("network %p", context->network);
  
-       connman_network_set_data(modem->network, modem);
+       connman_network_set_data(context->network, modem);
  
-       connman_network_set_string(modem->network, "Path",
-                                       modem->context->path);
+       connman_network_set_string(context->network, "Path",
+                                       context->path);
  
        if (modem->name)
-               connman_network_set_name(modem->network, modem->name);
+               connman_network_set_name(context->network, modem->name);
        else
-               connman_network_set_name(modem->network, "");
+               connman_network_set_name(context->network, "");
  
-       connman_network_set_strength(modem->network, modem->strength);
+       connman_network_set_strength(context->network, modem->strength);
  
-       group = get_ident(modem->context->path);
-       connman_network_set_group(modem->network, group);
+       group = get_ident(context->path);
+       connman_network_set_group(context->network, group);
  
-       connman_network_set_bool(modem->network, "Roaming",
-                                       modem->roaming);
+       connman_network_set_bool(context->network, "Roaming",
+                               modem->roaming);
  
-       if (connman_device_add_network(modem->device, modem->network) < 0) {
-               connman_network_unref(modem->network);
-               modem->network = NULL;
+       if (connman_device_add_network(modem->device, context->network) < 0) {
+               connman_network_unref(context->network);
+               context->network = NULL;
                return;
        }
  }
  
- static void remove_network(struct modem_data *modem)
+ static void remove_network(struct modem_data *modem,
+               struct network_context *context)
  {
        DBG("%s", modem->path);
  
-       if (!modem->network)
+       if (!context || !context->network)
                return;
  
-       DBG("network %p", modem->network);
+       DBG("network %p", context->network);
  
-       connman_device_remove_network(modem->device, modem->network);
-       connman_network_unref(modem->network);
-       modem->network = NULL;
+       if (modem->device)
+               connman_device_remove_network(modem->device, context->network);
+       connman_network_unref(context->network);
+       context->network = NULL;
  }
  
  static int set_context_ipconfig(struct network_context *context,
@@@ -1134,14 -1202,6 +1202,6 @@@ static int add_cm_context(struct modem_
  
        DBG("%s context path %s", modem->path, context_path);
  
-       if (modem->context) {
-               /*
-                * We have already assigned a context to this modem
-                * and we do only support one Internet context.
-                */
-               return -EALREADY;
-       }
        context = network_context_alloc(context_path);
        if (!context)
                return -ENOMEM;
  
                        dbus_message_iter_get_basic(&value, &apn);
                        if (apn && strlen(apn) > 0)
-                               modem->valid_apn = true;
+                               context->valid_apn = true;
                        else
-                               modem->valid_apn = false;
+                               context->valid_apn = false;
  
                        DBG("%s AccessPointName '%s'", modem->path, apn);
                }  else if (g_str_equal(key, "Protocol") &&
        }
  
        if (g_strcmp0(context_type, "internet") != 0) {
-               network_context_free(context);
+               network_context_unref(context);
                return -EINVAL;
        }
  
        if (ip_protocol)
                set_context_ipconfig(context, ip_protocol);
  
-       modem->context = context;
-       modem->active = active;
+       context->active = active;
  
+       modem->context_list = g_slist_prepend(modem->context_list, context);
        g_hash_table_replace(context_hash, g_strdup(context_path), modem);
  
-       if (modem->valid_apn && modem->attached &&
-                       has_interface(modem->interfaces,
-                               OFONO_API_NETREG)) {
-               add_network(modem);
-       }
+       if (context->valid_apn && modem->attached &&
+           has_interface(modem->interfaces, OFONO_API_NETREG))
+               add_network(modem, context);
  
        return 0;
  }
  
  static void remove_cm_context(struct modem_data *modem,
-                               const char *context_path)
+                               struct network_context *context)
  {
-       if (!modem->context)
+       if (!modem->context_list)
                return;
+       if (!context)
+               return;
+       g_hash_table_remove(context_hash, context->path);
+       if (context->network)
+               remove_network(modem, context);
+       modem->context_list = g_slist_remove(modem->context_list, context);
+       network_context_unref(context);
+       context = NULL;
+ }
+ static void remove_all_contexts(struct modem_data *modem)
+ {
+       GSList *list = NULL;
  
-       if (modem->network)
-               remove_network(modem);
+       DBG("");
+       if (modem->context_list == NULL)
+               return;
+       for (list = modem->context_list; list; list = list->next) {
+               struct network_context *context = list->data;
  
-       g_hash_table_remove(context_hash, context_path);
+               remove_cm_context(modem, context);
+       }
+       g_slist_free(modem->context_list);
+       modem->context_list = NULL;
+ }
  
-       network_context_free(modem->context);
-       modem->context = NULL;
+ static void remove_all_networks(struct modem_data *modem)
+ {
+       GSList *list;
  
-       modem->valid_apn = false;
+       for (list = modem->context_list; list; list = list->next) {
+               struct network_context *context = list->data;
  
-       if (modem->network)
-               remove_network(modem);
+               remove_network(modem, context);
+       }
  }
  
  static gboolean context_changed(DBusConnection *conn,
                                DBusMessage *message,
                                void *user_data)
  {
+       struct network_context *context = NULL;
        const char *context_path = dbus_message_get_path(message);
        struct modem_data *modem = NULL;
        DBusMessageIter iter, value;
        if (!modem)
                return TRUE;
  
+       context = get_context_with_path(modem->context_list, context_path);
+       if (!context)
+               return TRUE;
        if (!dbus_message_iter_init(message, &iter))
                return TRUE;
  
        if (g_str_equal(key, "Settings")) {
                DBG("%s Settings", modem->path);
  
-               extract_ipv4_settings(&value, modem->context);
+               extract_ipv4_settings(&value, context);
        } else if (g_str_equal(key, "IPv6.Settings")) {
                DBG("%s IPv6.Settings", modem->path);
  
-               extract_ipv6_settings(&value, modem->context);
+               extract_ipv6_settings(&value, context);
        } else if (g_str_equal(key, "Active")) {
                dbus_bool_t active;
  
                dbus_message_iter_get_basic(&value, &active);
-               modem->active = active;
+               context->active = active;
  
-               DBG("%s Active %d", modem->path, modem->active);
+               DBG("%s Active %d", modem->path, context->active);
  
-               if (modem->active)
-                       set_connected(modem);
+               if (context->active)
+                       set_connected(modem, context);
                else
-                       set_disconnected(modem);
+                       set_disconnected(context);
        } else if (g_str_equal(key, "AccessPointName")) {
                const char *apn;
  
                DBG("%s AccessPointName %s", modem->path, apn);
  
                if (apn && strlen(apn) > 0) {
-                       modem->valid_apn = true;
+                       context->valid_apn = true;
  
-                       if (modem->network)
+                       if (context->network)
                                return TRUE;
  
                        if (!modem->attached)
                                                OFONO_API_NETREG))
                                return TRUE;
  
-                       add_network(modem);
+                       add_network(modem, context);
  
-                       if (modem->active)
-                               set_connected(modem);
+                       if (context->active)
+                               set_connected(modem, context);
                } else {
-                       modem->valid_apn = false;
+                       context->valid_apn = false;
  
-                       if (!modem->network)
+                       if (!context->network)
                                return TRUE;
  
-                       remove_network(modem);
+                       remove_network(modem, context);
                }
  
        } else if (g_str_equal(key, "Protocol") &&
  
                dbus_message_iter_get_basic(&value, &ip_protocol);
  
-               set_context_ipconfig(modem->context, ip_protocol);
+               set_context_ipconfig(context, ip_protocol);
        }
  
        return TRUE;
@@@ -1367,7 -1457,7 +1457,7 @@@ static void cm_get_contexts_reply(DBusP
                dbus_message_iter_next(&entry);
                dbus_message_iter_recurse(&entry, &value);
  
-               if (add_cm_context(modem, context_path, &value) == 0)
+               if (add_cm_context(modem, context_path, &value))
                        break;
  
                dbus_message_iter_next(&dict);
@@@ -1422,7 -1512,7 +1512,7 @@@ static gboolean cm_context_added(DBusCo
        const char *path = dbus_message_get_path(message);
        char *context_path;
        struct modem_data *modem;
-       DBusMessageIter iter, properties;
+       DBusMessageIter iter, properties, dict;
  
        DBG("%s", path);
  
        dbus_message_iter_next(&iter);
        dbus_message_iter_recurse(&iter, &properties);
  
+       /* Sometimes, we get an array instead of dict */
+       if (dbus_message_iter_get_arg_type(&properties) == DBUS_TYPE_ARRAY) {
+               /* Must recurse again */
+               dbus_message_iter_recurse(&properties, &dict);
+               if (add_cm_context(modem, context_path, &dict) != 0)
+                       return TRUE;
+       }
        if (add_cm_context(modem, context_path, &properties) != 0)
                return TRUE;
  
@@@ -1451,6 -1548,7 +1548,7 @@@ static gboolean cm_context_removed(DBus
        const char *path = dbus_message_get_path(message);
        const char *context_path;
        struct modem_data *modem;
+       struct network_context *context;
        DBusMessageIter iter;
  
        DBG("context path %s", path);
        if (!modem)
                return TRUE;
  
-       remove_cm_context(modem, context_path);
+       context = get_context_with_path(modem->context_list, context_path);
+       remove_cm_context(modem, context);
  
        return TRUE;
  }
@@@ -1473,6 -1572,7 +1572,7 @@@ static void netreg_update_name(struct m
                                DBusMessageIter* value)
  {
        char *name;
+       GSList *list;
  
        dbus_message_iter_get_basic(value, &name);
  
        g_free(modem->name);
        modem->name = g_strdup(name);
  
-       if (!modem->network)
+       if (!modem->context_list)
                return;
  
-       connman_network_set_name(modem->network, modem->name);
-       connman_network_update(modem->network);
+       /* For all the context */
+       for (list = modem->context_list; list; list = list->next) {
+               struct network_context *context = list->data;
+               if (context->network) {
+                       connman_network_set_name(context->network, modem->name);
+                       connman_network_update(context->network);
+               }
+       }
  }
  
  static void netreg_update_strength(struct modem_data *modem,
                                        DBusMessageIter *value)
  {
+       GSList *list;
        dbus_message_iter_get_basic(value, &modem->strength);
  
        DBG("%s Strength %d", modem->path, modem->strength);
  
-       if (!modem->network)
+       if (!modem->context_list)
                return;
  
        /*
        if (modem->data_strength != 0)
                return;
  
-       connman_network_set_strength(modem->network, modem->strength);
-       connman_network_update(modem->network);
+       /* For all the context */
+       for (list = modem->context_list; list; list = list->next) {
+               struct network_context *context = list->data;
+               if (context->network) {
+                       connman_network_set_strength(context->network,
+                                                       modem->strength);
+                       connman_network_update(context->network);
+               }
+       }
  }
  
  /* Retrieve 1xEVDO Data Strength signal */
  static void netreg_update_datastrength(struct modem_data *modem,
                                        DBusMessageIter *value)
  {
+       GSList *list;
        dbus_message_iter_get_basic(value, &modem->data_strength);
  
        DBG("%s Data Strength %d", modem->path, modem->data_strength);
  
-       if (!modem->network)
+       if (!modem->context_list)
                return;
  
        /*
        if (modem->data_strength == 0)
                return;
  
-       connman_network_set_strength(modem->network, modem->data_strength);
-       connman_network_update(modem->network);
+       /* For all the context */
+       for (list = modem->context_list; list; list = list->next) {
+               struct network_context *context = list->data;
+               if (context->network) {
+                       connman_network_set_strength(context->network,
+                                                       modem->data_strength);
+                       connman_network_update(context->network);
+               }
+       }
  }
  
  static void netreg_update_status(struct modem_data *modem,
  {
        char *status;
        bool roaming;
+       GSList *list;
  
        dbus_message_iter_get_basic(value, &status);
  
  
        modem->roaming = roaming;
  
-       if (!modem->network)
+       if (!modem->context_list)
                return;
  
-       connman_network_set_bool(modem->network,
+       /* For all the context */
+       for (list = modem->context_list; list; list = list->next) {
+               struct network_context *context = list->data;
+               if (context->network) {
+                       connman_network_set_bool(context->network,
                                "Roaming", modem->roaming);
-       connman_network_update(modem->network);
+                       connman_network_update(context->network);
+               }
+       }
  }
  
  static void netreg_update_regdom(struct modem_data *modem,
@@@ -1624,6 -1759,8 +1759,8 @@@ static gboolean netreg_changed(DBusConn
  static void netreg_properties_reply(struct modem_data *modem,
                                        DBusMessageIter *dict)
  {
+       GSList *list = NULL;
        DBG("%s", modem->path);
  
        while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
                dbus_message_iter_next(dict);
        }
  
-       if (!modem->context) {
+       if (!modem->context_list) {
                /*
                 * netgreg_get_properties() was issued after we got
                 * cm_get_contexts_reply() where we create the
                 */
                return;
        }
-       if (modem->valid_apn)
-               add_network(modem);
-       if (modem->active)
-               set_connected(modem);
+       /* Check for all contexts if they are valids and/or actives */
+       for (list = modem->context_list; list; list = list->next) {
+               struct network_context *context = list->data;
+               if (context->valid_apn)
+                       add_network(modem, context);
+               if (context->active)
+                       set_connected(modem, context);
+       }
  }
  
  static int netreg_get_properties(struct modem_data *modem)
  
  static void add_cdma_network(struct modem_data *modem)
  {
+       struct network_context *context = NULL;
        /* Be sure that device is created before adding CDMA network */
        if (!modem->device)
                return;
         * CDMA modems don't need contexts for data call, however the current
         * add_network() logic needs one, so we create one to proceed.
         */
-       if (!modem->context)
-               modem->context = network_context_alloc(modem->path);
+       if (!modem->context_list) {
+               context = network_context_alloc(modem->path);
+               modem->context_list = g_slist_prepend(modem->context_list,
+                                                       context);
+       } else
+               context = modem->context_list->data;
  
        if (!modem->name)
                modem->name = g_strdup("CDMA Network");
  
-       add_network(modem);
+       add_network(modem, context);
  
        if (modem->cdma_cm_powered)
-               set_connected(modem);
+               set_connected(modem, context);
  }
  
  static gboolean cdma_netreg_changed(DBusConnection *conn,
        if (modem->registered)
                add_cdma_network(modem);
        else
-               remove_network(modem);
+               remove_all_networks(modem);
  
        return TRUE;
  }
@@@ -1768,7 -1913,7 +1913,7 @@@ static void cdma_netreg_properties_repl
        if (modem->registered)
                add_cdma_network(modem);
        else
-               remove_network(modem);
+               remove_all_networks(modem);
  }
  
  static int cdma_netreg_get_properties(struct modem_data *modem)
@@@ -1788,7 -1933,7 +1933,7 @@@ static void cm_update_attached(struct m
        DBG("%s Attached %d", modem->path, modem->attached);
  
        if (!modem->attached) {
-               remove_network(modem);
+               remove_all_networks(modem);
                return;
        }
  
@@@ -1849,6 -1994,7 +1994,7 @@@ static gboolean cm_changed(DBusConnecti
  static void cdma_cm_update_powered(struct modem_data *modem,
                                        DBusMessageIter *value)
  {
+       struct network_context *context =  NULL;
        dbus_bool_t cdma_cm_powered;
  
        dbus_message_iter_get_basic(value, &cdma_cm_powered);
  
        DBG("%s CDMA cm Powered %d", modem->path, modem->cdma_cm_powered);
  
-       if (!modem->network)
+       if (!modem->context_list)
                return;
  
+       /* In case of CDMA, there is only one context */
+       context = modem->context_list->data;
        if (modem->cdma_cm_powered)
-               set_connected(modem);
+               set_connected(modem, context);
        else
-               set_disconnected(modem);
+               set_disconnected(context);
  }
  
  static void cdma_cm_update_settings(struct modem_data *modem,
  {
        DBG("%s Settings", modem->path);
  
-       extract_ipv4_settings(value, modem->context);
+       extract_ipv4_settings(value, modem->context_list->data);
  }
  
  static gboolean cdma_cm_changed(DBusConnection *conn,
        if (!modem)
                return TRUE;
  
-       if (modem->online && !modem->network)
+       if (modem->online && !modem->context_list)
                cdma_netreg_get_properties(modem);
  
        if (!dbus_message_iter_init(message, &iter))
@@@ -2142,17 -2290,24 +2290,24 @@@ static void modem_update_interfaces(str
        if (api_added(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG))
                cdma_netreg_get_properties(modem);
  
-       if (api_removed(old_ifaces, new_ifaces, OFONO_API_CM))
-               remove_cm_context(modem, modem->context->path);
+       if (api_removed(old_ifaces, new_ifaces, OFONO_API_CM)) {
+               if (modem->call_get_contexts) {
+                       DBG("cancelling pending GetContexts call");
+                       dbus_pending_call_cancel(modem->call_get_contexts);
+                       dbus_pending_call_unref(modem->call_get_contexts);
+                       modem->call_get_contexts = NULL;
+               }
+               remove_all_contexts(modem);
+       }
  
        if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_CM))
-               remove_cm_context(modem, modem->context->path);
+               remove_all_contexts(modem);
  
        if (api_removed(old_ifaces, new_ifaces, OFONO_API_NETREG))
-               remove_network(modem);
+               remove_all_networks(modem);
  
        if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG))
-               remove_network(modem);
+               remove_all_networks(modem);
  }
  
  static gboolean modem_changed(DBusConnection *conn, DBusMessage *message,
  
                DBG("%s Powered %d", modem->path, modem->powered);
  
-               if (!modem->powered)
-                       modem_set_powered(modem, TRUE);
+               /* Set the powered according to the value */
+               modem_set_powered(modem, powered);
        } else if (g_str_equal(key, "Online")) {
                dbus_bool_t online;
  
@@@ -2340,21 -2495,31 +2495,31 @@@ static void remove_modem(gpointer data
  
        DBG("%s", modem->path);
  
-       if (modem->call_set_property)
+       if (modem->call_set_property) {
                dbus_pending_call_cancel(modem->call_set_property);
+               dbus_pending_call_unref(modem->call_set_property);
+               modem->call_set_property = NULL;
+       }
  
-       if (modem->call_get_properties)
+       if (modem->call_get_properties) {
                dbus_pending_call_cancel(modem->call_get_properties);
+               dbus_pending_call_unref(modem->call_get_properties);
+               modem->call_get_properties = NULL;
+       }
  
-       if (modem->call_get_contexts)
+       if (modem->call_get_contexts) {
                dbus_pending_call_cancel(modem->call_get_contexts);
+               dbus_pending_call_unref(modem->call_get_contexts);
+               modem->call_get_contexts = NULL;
+       }
+       /* Must remove the contexts before the device */
+       if (modem->context_list)
+               remove_all_contexts(modem);
  
        if (modem->device)
                destroy_device(modem);
  
-       if (modem->context)
-               remove_cm_context(modem, modem->context->path);
        g_free(modem->serial);
        g_free(modem->name);
        g_free(modem->imsi);
@@@ -2530,12 -2695,20 +2695,20 @@@ static void network_remove(struct connm
  
  static int network_connect(struct connman_network *network)
  {
+       struct network_context *context;
        struct modem_data *modem = connman_network_get_data(network);
  
        DBG("%s network %p", modem->path, network);
  
+       if (!g_hash_table_lookup(modem_hash, modem->path))
+               return -ENODEV;
+       context = get_context_with_network(modem->context_list, network);
+       if (!context)
+               return -ENODEV;
        if (has_interface(modem->interfaces, OFONO_API_CM))
-               return context_set_active(modem, TRUE);
+               return context_set_active(modem, context, TRUE);
        else if (has_interface(modem->interfaces, OFONO_API_CDMA_CM))
                return cdma_cm_set_powered(modem, TRUE);
  
  
  static int network_disconnect(struct connman_network *network)
  {
+       struct network_context *context;
        struct modem_data *modem = connman_network_get_data(network);
  
        DBG("%s network %p", modem->path, network);
  
+       if (!g_hash_table_lookup(modem_hash, modem->path))
+               return -ENODEV;
+       context = get_context_with_network(modem->context_list, network);
+       if (!context)
+               return -ENODEV;
        if (has_interface(modem->interfaces, OFONO_API_CM))
-               return context_set_active(modem, FALSE);
+               return context_set_active(modem, context, FALSE);
        else if (has_interface(modem->interfaces, OFONO_API_CDMA_CM))
                return cdma_cm_set_powered(modem, FALSE);
  
diff --combined plugins/pacrunner.c
index 850139f,d2464a5..d2464a5
mode 100755,100644..100755
@@@ -78,11 -78,6 +78,6 @@@ done
        dbus_message_unref(reply);
  }
  
- static void append_string(DBusMessageIter *iter, void *user_data)
- {
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
- }
  static void append_string_list(DBusMessageIter *iter, void *user_data)
  {
        char **list = user_data;
@@@ -178,11 -173,6 +173,6 @@@ static void create_proxy_configuration(
                g_free(interface);
        }
  
-       str = connman_service_get_domainname(default_service);
-       if (str)
-               connman_dbus_dict_append_array(&dict, "Domains",
-                                       DBUS_TYPE_STRING, append_string, &str);
        str_list = connman_service_get_nameservers(default_service);
        if (str_list)
                connman_dbus_dict_append_array(&dict, "Nameservers",
index b2369bd,f003c0e..f003c0e
mode 100755,100644..100755
@@@ -459,6 -459,8 +459,8 @@@ static int load_policy(GKeyFile *keyfil
        str = g_key_file_get_string(keyfile, groupname, "AllowedBearers",
                                NULL);
        if (str) {
+               g_slist_free(config->allowed_bearers);
+               config->allowed_bearers = NULL;
                tokens = g_strsplit(str, " ", 0);
  
                for (i = 0; tokens[i]; i++) {
@@@ -623,7 -625,7 +625,7 @@@ static int load_file(const char *filena
  
        for (i = 0; groupnames[i]; i++) {
                group = g_new0(struct policy_group, 1);
-               group->config = g_new0(struct connman_session_config, 1);
+               group->config = connman_session_create_default_config();
  
                err = load_policy(keyfile, groupnames[i], group);
                if (err < 0) {
diff --combined plugins/vpn.c
index ba5841e,c2a332b..d3d75b8
mode 100755,100644..100755
@@@ -203,7 -203,7 +203,7 @@@ static void resolv_result(GResolvResult
         * We cannot unref the resolver here as resolv struct is manipulated
         * by gresolv.c after we return from this callback.
         */
-       g_timeout_add_seconds(0, remove_resolv, data);
+       g_idle_add(remove_resolv, data);
  
        data->resolv_id = 0;
  }
@@@ -512,26 -512,39 +512,39 @@@ done
        dbus_pending_call_unref(call);
  }
  
- static int connect_provider(struct connection_data *data, void *user_data)
+ static int connect_provider(struct connection_data *data, void *user_data,
+                       const char *dbus_sender)
  {
        DBusPendingCall *call;
        DBusMessage *message;
        struct config_create_data *cb_data = user_data;
  
-       DBG("data %p user %p path %s", data, cb_data, data->path);
+       DBG("data %p user %p path %s sender %s", data, cb_data, data->path,
+                                                               dbus_sender);
  
        data->connect_pending = false;
  
+ #define VPN_CONNECT2 "Connect2"
+       /* We need to pass original dbus sender to connman-vpnd,
+        * use a Connect2 method for that.
+        */
        message = dbus_message_new_method_call(VPN_SERVICE, data->path,
                                        VPN_CONNECTION_INTERFACE,
-                                       VPN_CONNECT);
+                                       VPN_CONNECT2);
        if (!message)
                return -ENOMEM;
  
+       if (dbus_sender)
+               dbus_message_append_args(message, DBUS_TYPE_STRING,
+                                       &dbus_sender, NULL);
+       else
+               dbus_sender = "";
        if (!dbus_connection_send_with_reply(connection, message,
                                                &call, DBUS_TIMEOUT)) {
                connman_error("Unable to call %s.%s()",
-                       VPN_CONNECTION_INTERFACE, VPN_CONNECT);
+                       VPN_CONNECTION_INTERFACE, VPN_CONNECT2);
                dbus_message_unref(message);
                return -EINVAL;
        }
@@@ -658,8 -671,15 +671,15 @@@ static void add_connection(const char *
                connman_provider_set_domain(data->provider,
                                                data->domain);
  
-       if (data->connect_pending)
-               connect_provider(data, data->cb_data);
+       if (data->connect_pending) {
+               const char *dbus_sender = NULL;
+               if (data->cb_data && data->cb_data->message) {
+                       dbus_sender =
+                               dbus_message_get_sender(data->cb_data->message);
+               }
+               connect_provider(data, data->cb_data, dbus_sender);
+       }
  
        return;
  
@@@ -857,7 -877,8 +877,8 @@@ static int provider_remove(struct connm
        return 0;
  }
  
- static int provider_connect(struct connman_provider *provider)
+ static int provider_connect(struct connman_provider *provider,
+                                       const char *dbus_sender)
  {
        struct connection_data *data;
  
        if (!data)
                return -EINVAL;
  
-       return connect_provider(data, NULL);
+       return connect_provider(data, NULL, dbus_sender);
  }
  
  static void disconnect_reply(DBusPendingCall *call, void *user_data)
@@@ -1705,7 -1726,7 +1726,7 @@@ static gboolean property_changed(DBusCo
        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 --combined plugins/wifi.c
index 0d33f4d,34c16df..8bc6307
mode 100755,100644..100755
  #define P2P_LISTEN_PERIOD 500
  #define P2P_LISTEN_INTERVAL 2000
  
+ #define ASSOC_STATUS_NO_CLIENT 17
+ #define LOAD_SHAPING_MAX_RETRIES 3
  
  static struct connman_technology *wifi_technology = NULL;
  static struct connman_technology *p2p_technology = NULL;
  
+ enum wifi_ap_capability{
+       WIFI_AP_UNKNOWN         = 0,
+       WIFI_AP_SUPPORTED       = 1,
+       WIFI_AP_NOT_SUPPORTED   = 2,
+ };
  struct hidden_params {
        char ssid[32];
        unsigned int ssid_len;
        char *identity;
+       char *anonymous_identity;
+       char *subject_match;
+       char *altsubject_match;
+       char *domain_suffix_match;
+       char *domain_match;
        char *passphrase;
        char *security;
        GSupplicantScanParams *scan_params;
@@@ -96,6 -109,13 +109,13 @@@ struct autoscan_params 
        unsigned int timeout;
  };
  
+ struct wifi_tethering_info {
+       struct wifi_data *wifi;
+       struct connman_technology *technology;
+       char *ifname;
+       GSupplicantSSID *ssid;
+ };
  struct wifi_data {
        char *identifier;
        struct connman_device *device;
        bool connected;
        bool disconnecting;
        bool tethering;
+       enum wifi_ap_capability ap_supported;
        bool bridged;
        bool interface_ready;
        const char *bridge;
        unsigned flags;
        unsigned int watch;
        int retries;
+       int load_shaping_retries;
        struct hidden_params *hidden;
        bool postpone_hidden;
+       struct wifi_tethering_info *tethering_param;
        /**
         * autoscan "emulation".
         */
        unsigned int p2p_find_timeout;
        unsigned int p2p_connection_timeout;
        struct connman_peer *pending_peer;
-       GSupplicantPeer *peer;
+       GSList *peers;
        bool p2p_connecting;
        bool p2p_device;
        int servicing;
 +#if defined TIZEN_EXT
 +      int assoc_retry_count;
 +      struct connman_network *scan_pending_network;
 +      bool allow_full_scan;
 +#endif
        int disconnect_code;
        int assoc_code;
  };
  
 +#if defined TIZEN_EXT
 +#include "connman.h"
 +#include "dbus.h"
 +
 +#define TIZEN_ASSOC_RETRY_COUNT               4
 +
 +static gboolean wifi_first_scan = false;
 +static gboolean found_with_first_scan = false;
 +static gboolean is_wifi_notifier_registered = false;
 +#endif
 +
 +
  static GList *iface_list = NULL;
  
  static GList *pending_wifi_device = NULL;
@@@ -157,124 -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;
@@@ -363,8 -255,6 +390,6 @@@ static void peer_cancel_timeout(struct 
                connman_peer_unref(wifi->pending_peer);
                wifi->pending_peer = NULL;
        }
-       wifi->peer = NULL;
  }
  
  static gboolean peer_connect_timeout(gpointer data)
  
        if (wifi->p2p_connecting) {
                enum connman_peer_state state = CONNMAN_PEER_STATE_FAILURE;
+               GSupplicantPeer *gs_peer =
+                       g_supplicant_interface_peer_lookup(wifi->interface,
+                               connman_peer_get_identifier(wifi->pending_peer));
  
-               if (g_supplicant_peer_has_requested_connection(wifi->peer))
+               if (g_supplicant_peer_has_requested_connection(gs_peer))
                        state = CONNMAN_PEER_STATE_IDLE;
  
                connman_peer_set_state(wifi->pending_peer, state);
@@@ -427,14 -320,12 +455,12 @@@ static int peer_connect(struct connman_
                return -ENODEV;
  
        wifi = connman_device_get_data(device);
-       if (!wifi)
+       if (!wifi || !wifi->interface)
                return -ENODEV;
  
        if (wifi->p2p_connecting)
                return -EBUSY;
  
-       wifi->peer = NULL;
        gs_peer = g_supplicant_interface_peer_lookup(wifi->interface,
                                        connman_peer_get_identifier(peer));
        if (!gs_peer)
                                                peer_connect_callback, wifi);
        if (ret == -EINPROGRESS) {
                wifi->pending_peer = connman_peer_ref(peer);
-               wifi->peer = gs_peer;
                wifi->p2p_connecting = true;
-       } else if (ret < 0)
+       } else if (ret < 0) {
+               g_free(peer_params->path);
+               g_free(peer_params->wps_pin);
                g_free(peer_params);
+       }
  
        return ret;
  }
@@@ -509,8 -402,10 +537,10 @@@ static int peer_disconnect(struct connm
                                                        &peer_params);
        g_free(peer_params.path);
  
-       if (ret == -EINPROGRESS)
+       if (ret == -EINPROGRESS) {
                peer_cancel_timeout(wifi);
+               wifi->p2p_device = false;
+       }
  
        return ret;
  }
@@@ -650,11 -545,6 +680,11 @@@ static void register_peer_service_cb(in
        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)
@@@ -879,6 -769,8 +909,8 @@@ static int wifi_probe(struct connman_de
                return -ENOMEM;
  
        wifi->state = G_SUPPLICANT_STATE_INACTIVE;
+       wifi->ap_supported = WIFI_AP_UNKNOWN;
+       wifi->tethering_param = NULL;
  
        connman_device_set_data(device, wifi);
        wifi->device = connman_device_ref(device);
@@@ -912,6 -804,21 +944,21 @@@ static void remove_networks(struct conn
        wifi->networks = NULL;
  }
  
+ static void remove_peers(struct wifi_data *wifi)
+ {
+       GSList *list;
+       for (list = wifi->peers; list; list = list->next) {
+               struct connman_peer *peer = list->data;
+               connman_peer_unregister(peer);
+               connman_peer_unref(peer);
+       }
+       g_slist_free(wifi->peers);
+       wifi->peers = NULL;
+ }
  static void reset_autoscan(struct connman_device *device)
  {
        struct wifi_data *wifi = connman_device_get_data(device);
@@@ -995,6 -902,7 +1042,7 @@@ static void wifi_remove(struct connman_
                g_source_remove(wifi->p2p_connection_timeout);
  
        remove_networks(device, wifi);
+       remove_peers(wifi);
  
        connman_device_set_powered(device, false);
        connman_device_set_data(device, NULL);
@@@ -1161,15 -1069,6 +1209,15 @@@ static int get_hidden_connections(GSupp
                        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);
  
@@@ -1309,11 -1208,8 +1357,11 @@@ static int throw_wifi_scan(struct connm
  
        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);
@@@ -1342,45 -1238,6 +1390,45 @@@ static void hidden_free(struct hidden_p
        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)
  {
                return scan_callback(ret, interface, user_data);
        }
  
 -      scanning = connman_device_get_scanning(device);
 +#if defined TIZEN_EXT
 +      if (wifi && wifi->allow_full_scan) {
 +              int ret;
 +              DBG("Trigger Full Channel Scan");
 +              wifi->allow_full_scan = FALSE;
  
 -      if (scanning) {
 +              ret = g_supplicant_interface_scan(wifi->interface, NULL,
 +                                                      scan_callback, device);
 +              if (ret == 0)
 +                      return;
 +
 +              /* On error, let's recall scan_callback, which will cleanup */
 +              return scan_callback(ret, interface, user_data);
 +      }
 +#endif
 +
 +      scanning = connman_device_get_scanning(device);
 +      if (scanning)
                connman_device_set_scanning(device,
                                CONNMAN_SERVICE_TYPE_WIFI, false);
 -      }
  
        if (result != -ENOLINK)
 +#if defined TIZEN_EXT
 +      if (result != -EIO)
 +#endif
                start_autoscan(device);
  
        /*
  
        if (scanning)
                connman_device_unref(device);
 +
 +#if defined TIZEN_EXT
 +      if (wifi && wifi->scan_pending_network && result != -EIO) {
 +              network_connect(wifi->scan_pending_network);
 +              wifi->scan_pending_network = NULL;
 +              connman_network_set_connecting(wifi->network);
 +      }
 +
 +      if (is_wifi_notifier_registered != true &&
 +                      wifi_first_scan == true && found_with_first_scan == true) {
 +              wifi_first_scan = false;
 +              found_with_first_scan = false;
 +
 +              connman_notifier_register(&notifier);
 +              is_wifi_notifier_registered = true;
 +      }
 +#endif
  }
  
  static void scan_callback_hidden(int result,
@@@ -1535,11 -1358,7 +1583,11 @@@ static gboolean autoscan_timeout(gpoint
        } 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);
@@@ -1731,16 -1550,8 +1779,17 @@@ static int wifi_disable(struct connman_
        }
  
        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;
@@@ -1894,12 -1705,14 +1943,14 @@@ static gboolean p2p_find_stop(gpointer 
  
        DBG("");
  
-       wifi->p2p_find_timeout = 0;
+       if (wifi) {
+               wifi->p2p_find_timeout = 0;
+               g_supplicant_interface_p2p_stop_find(wifi->interface);
+       }
  
        connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_P2P, false);
  
-       g_supplicant_interface_p2p_stop_find(wifi->interface);
        connman_device_unref(device);
        reset_autoscan(device);
  
@@@ -1914,6 -1727,9 +1965,9 @@@ static void p2p_find_callback(int resul
  
        DBG("result %d wifi %p", result, wifi);
  
+       if (!wifi)
+               goto error;
        if (wifi->p2p_find_timeout) {
                g_source_remove(wifi->p2p_find_timeout);
                wifi->p2p_find_timeout = 0;
@@@ -1963,137 -1779,6 +2017,137 @@@ static int p2p_find(struct connman_devi
        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.
@@@ -2117,16 -1802,16 +2171,16 @@@ static int wifi_scan(enum connman_servi
                return -ENODEV;
  
        if (wifi->p2p_device)
-               return 0;
+               return -EBUSY;
+       if (wifi->tethering)
+               return -EBUSY;
  
        if (type == CONNMAN_SERVICE_TYPE_P2P)
                return p2p_find(device);
  
        DBG("device %p wifi %p hidden ssid %s", device, wifi->interface, ssid);
  
-       if (wifi->tethering)
-               return 0;
        scanning = connman_device_get_scanning(device);
  
        if (!ssid || ssid_len == 0 || ssid_len > 32) {
  
        ret = g_supplicant_interface_scan(wifi->interface, scan_params,
                                                scan_callback, device);
 +
        if (ret == 0) {
                connman_device_set_scanning(device,
                                CONNMAN_SERVICE_TYPE_WIFI, true);
 +#if defined TIZEN_EXT
 +              /*To allow the Full Scan after ssid based scan, set the flag here
 +                It is required because Tizen does not use the ConnMan specific
 +                backgroung Scan feature.Tizen has added the BG Scan feature in
 +                net-config. To sync with up ConnMan, we need to issue the Full Scan
 +                after SSID specific scan.*/
 +              wifi->allow_full_scan = TRUE;
 +#endif
        } else {
                g_supplicant_free_scan_params(scan_params);
                connman_device_unref(device);
@@@ -2273,9 -1949,6 +2327,9 @@@ static struct connman_device_driver wif
        .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)
@@@ -2315,42 -1988,15 +2369,42 @@@ static void network_remove(struct connm
                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);
@@@ -2376,12 -2022,6 +2430,12 @@@ static GSupplicantSecurity network_secu
                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;
  }
@@@ -2399,6 -2039,7 +2453,6 @@@ static void ssid_init(GSupplicantSSID *
        ssid->security = network_security(security);
        ssid->passphrase = connman_network_get_string(network,
                                                "WiFi.Passphrase");
 -
        ssid->eap = connman_network_get_string(network, "WiFi.EAP");
  
        /*
                ssid->identity = connman_network_get_string(network,
                                                        "WiFi.AgentIdentity");
  
+       ssid->anonymous_identity = connman_network_get_string(network,
+                                               "WiFi.AnonymousIdentity");
        ssid->ca_cert_path = connman_network_get_string(network,
                                                        "WiFi.CACertFile");
+       ssid->subject_match = connman_network_get_string(network,
+                                                       "WiFi.SubjectMatch");
+       ssid->altsubject_match = connman_network_get_string(network,
+                                                       "WiFi.AltSubjectMatch");
+       ssid->domain_suffix_match = connman_network_get_string(network,
+                                                       "WiFi.DomainSuffixMatch");
+       ssid->domain_match = connman_network_get_string(network,
+                                                       "WiFi.DomainMatch");
        ssid->client_cert_path = connman_network_get_string(network,
                                                        "WiFi.ClientCertFile");
        ssid->private_key_path = connman_network_get_string(network,
        ssid->use_wps = connman_network_get_bool(network, "WiFi.UseWPS");
        ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
  
 +#if defined TIZEN_EXT
 +      ssid->bssid = connman_network_get_bssid(network);
 +#endif
 +#if defined TIZEN_EXT
 +      ssid->freq = connman_network_get_frequency(network);
 +#endif
 +
        if (connman_setting_get_bool("BackgroundScanning"))
                ssid->bgscan = BGSCAN_DEFAULT;
  }
@@@ -2473,9 -2117,6 +2537,9 @@@ static int network_connect(struct connm
        } else {
                wifi->network = connman_network_ref(network);
                wifi->retries = 0;
 +#if defined TIZEN_EXT
 +              wifi->scan_pending_network = NULL;
 +#endif
  
                return g_supplicant_interface_connect(interface, ssid,
                                                connect_callback, network);
  static void disconnect_callback(int result, GSupplicantInterface *interface,
                                                                void *user_data)
  {
 +#if defined TIZEN_EXT
 +      GList *list;
 +      struct wifi_data *wifi;
 +      struct connman_network *network = user_data;
 +
 +      DBG("network %p result %d", network, result);
 +
 +      for (list = iface_list; list; list = list->next) {
 +              wifi = list->data;
 +
 +              if (wifi->network == NULL && wifi->disconnecting == true)
 +                      wifi->disconnecting = false;
 +
 +              if (wifi->network == network)
 +                      goto found;
 +      }
 +
 +      /* wifi_data may be invalid because wifi is already disabled */
 +      return;
 +
 +found:
 +#else
        struct wifi_data *wifi = user_data;
 +#endif
  
        DBG("result %d supplicant interface %p wifi %p",
                        result, interface, wifi);
        }
  
        if (wifi->network) {
-               /*
-                * if result < 0 supplican return an error because
-                * the network is not current.
-                * we wont receive G_SUPPLICANT_STATE_DISCONNECTED since it
-                * failed, call connman_network_set_connected to report
-                * disconnect is completed.
-                */
-               if (result < 0)
-                       connman_network_set_connected(wifi->network, false);
+               connman_network_set_connected(wifi->network, false);
+               wifi->network = NULL;
        }
  
-       wifi->network = NULL;
        wifi->disconnecting = false;
+       wifi->connected = false;
  
        if (wifi->pending_network) {
                network_connect(wifi->pending_network);
@@@ -2549,9 -2159,6 +2605,9 @@@ static int network_disconnect(struct co
        struct connman_device *device = connman_network_get_device(network);
        struct wifi_data *wifi;
        int err;
 +#if defined TIZEN_EXT
 +      struct connman_service *service;
 +#endif
  
        DBG("network %p", network);
  
        if (!wifi || !wifi->interface)
                return -ENODEV;
  
 +#if defined TIZEN_EXT
 +      if (connman_network_get_associating(network) == true) {
 +              connman_network_clear_associating(network);
 +              connman_network_set_bool(network, "WiFi.UseWPS", false);
 +      } else {
 +              service = connman_service_lookup_from_network(network);
 +
 +              if (service != NULL &&
 +                      (__connman_service_is_connected_state(service,
 +                                      CONNMAN_IPCONFIG_TYPE_IPV4) == false &&
 +                      __connman_service_is_connected_state(service,
 +                                      CONNMAN_IPCONFIG_TYPE_IPV6) == false) &&
 +                      (connman_service_get_favorite(service) == false))
 +                                      __connman_service_set_passphrase(service, NULL);
 +      }
 +
 +      if (wifi->pending_network == network)
 +              wifi->pending_network = NULL;
 +
 +      if (wifi->scan_pending_network == network)
 +              wifi->scan_pending_network = NULL;
 +
 +#endif
        connman_network_set_associating(network, false);
  
        if (wifi->disconnecting)
  
        wifi->disconnecting = true;
  
 +#if defined TIZEN_EXT
 +      err = g_supplicant_interface_disconnect(wifi->interface,
 +                                              disconnect_callback, network);
 +#else
        err = g_supplicant_interface_disconnect(wifi->interface,
                                                disconnect_callback, wifi);
 +#endif
 +
        if (err < 0)
                wifi->disconnecting = false;
  
@@@ -2625,6 -2203,7 +2681,7 @@@ static void interface_added(GSupplicant
                if (!wifi)
                        return;
  
+               wifi->interface = interface;
                g_supplicant_interface_set_data(interface, wifi);
                p2p_iface_list = g_list_append(p2p_iface_list, wifi);
                wifi->p2p_device = true;
@@@ -2718,78 -2297,38 +2775,91 @@@ static bool handle_wps_completion(GSupp
                if (!wps_ssid || wps_ssid_len != ssid_len ||
                                memcmp(ssid, wps_ssid, ssid_len) != 0) {
                        connman_network_set_associating(network, false);
 +#if defined TIZEN_EXT
 +                      g_supplicant_interface_disconnect(wifi->interface,
 +                                              disconnect_callback, wifi->network);
 +
 +                      connman_network_set_bool(network, "WiFi.UseWPS", false);
 +                      connman_network_set_string(network, "WiFi.PinWPS", NULL);
 +#else
                        g_supplicant_interface_disconnect(wifi->interface,
                                                disconnect_callback, wifi);
 +#endif
                        return false;
                }
  
                wps_key = g_supplicant_interface_get_wps_key(interface);
-                ret = send_encryption_request(passphrase, network);
 +#if defined TIZEN_EXT
 +              /* Check the passphrase and encrypt it
 +               */
 +               int ret;
 +               gchar *passphrase = g_strdup(wps_key);
 +
 +               connman_network_set_string(network, "WiFi.PinWPS", NULL);
 +
 +               if (check_passphrase_ext(network, passphrase) < 0) {
 +                       DBG("[WPS] Invalid passphrase");
 +                       g_free(passphrase);
 +                       return true;
 +               }
 +
++               ret = send_encryption_request(passphrase, passphrase);
 +
 +               g_free(passphrase);
 +
 +               if (!ret)
 +                       DBG("[WPS] Encryption request succeeded");
 +               else
 +                       DBG("[WPS] Encryption request failed %d", ret);
 +
 +#else
                connman_network_set_string(network, "WiFi.Passphrase",
                                        wps_key);
  
                connman_network_set_string(network, "WiFi.PinWPS", NULL);
 +#endif
        }
  
        return true;
  }
  
+ static bool handle_assoc_status_code(GSupplicantInterface *interface,
+                                      struct wifi_data *wifi)
+ {
+       if (wifi->state == G_SUPPLICANT_STATE_ASSOCIATING &&
+                       wifi->assoc_code == ASSOC_STATUS_NO_CLIENT &&
+                       wifi->load_shaping_retries < LOAD_SHAPING_MAX_RETRIES) {
+               wifi->load_shaping_retries ++;
+               return TRUE;
+       }
+       wifi->load_shaping_retries = 0;
+       return FALSE;
+ }
  static bool handle_4way_handshake_failure(GSupplicantInterface *interface,
                                        struct connman_network *network,
                                        struct wifi_data *wifi)
  {
 +#if defined TIZEN_EXT
 +      const char *security;
 +      struct connman_service *service;
 +
 +      if (wifi->connected)
 +              return false;
 +
 +      security = connman_network_get_string(network, "WiFi.Security");
 +
 +      if (security && g_str_equal(security, "ieee8021x") == true &&
 +                      wifi->state == G_SUPPLICANT_STATE_ASSOCIATED) {
 +              wifi->retries = 0;
 +              connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY);
 +
 +              return false;
 +      }
 +
 +      if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
 +              return false;
 +#else
        struct connman_service *service;
  
        if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
  
        if (wifi->connected)
                return false;
 +#endif
  
        service = connman_service_lookup_from_network(network);
        if (!service)
        return false;
  }
  
 +#if defined TIZEN_EXT
 +static bool handle_wifi_assoc_retry(struct connman_network *network,
 +                                      struct wifi_data *wifi)
 +{
 +      const char *security;
 +
 +      if (!wifi->network || wifi->connected || wifi->disconnecting ||
 +                      connman_network_get_connecting(network) != true) {
 +              wifi->assoc_retry_count = 0;
 +              return false;
 +      }
 +
 +      if (wifi->state != G_SUPPLICANT_STATE_ASSOCIATING &&
 +                      wifi->state != G_SUPPLICANT_STATE_ASSOCIATED) {
 +              wifi->assoc_retry_count = 0;
 +              return false;
 +      }
 +
 +      security = connman_network_get_string(network, "WiFi.Security");
 +      if (security && g_str_equal(security, "ieee8021x") == true &&
 +                      wifi->state == G_SUPPLICANT_STATE_ASSOCIATED) {
 +              wifi->assoc_retry_count = 0;
 +              return false;
 +      }
 +
 +      if (++wifi->assoc_retry_count >= TIZEN_ASSOC_RETRY_COUNT) {
 +              wifi->assoc_retry_count = 0;
 +
 +              /* Honestly it's not an invalid-key error,
 +               * however QA team recommends that the invalid-key error
 +               * might be better to display for user experience.
 +               */
 +              connman_network_set_error(network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
 +
 +              return false;
 +      }
 +
 +      return true;
 +}
 +#endif
 +
  static void interface_state(GSupplicantInterface *interface)
  {
        struct connman_network *network;
        struct wifi_data *wifi;
        GSupplicantState state = g_supplicant_interface_get_state(interface);
        bool wps;
+       bool old_connected;
  
        wifi = g_supplicant_interface_get_data(interface);
  
        if (!wifi)
                return;
  
+       if (state == G_SUPPLICANT_STATE_COMPLETED) {
+               if (wifi->tethering_param) {
+                       g_free(wifi->tethering_param->ssid);
+                       g_free(wifi->tethering_param);
+                       wifi->tethering_param = NULL;
+               }
+       }
        device = wifi->device;
        if (!device)
                return;
  
        switch (state) {
        case G_SUPPLICANT_STATE_SCANNING:
+               if (wifi->connected)
+                       connman_network_set_connected(network, false);
                break;
  
        case G_SUPPLICANT_STATE_AUTHENTICATING:
        case G_SUPPLICANT_STATE_ASSOCIATING:
 +#if defined TIZEN_EXT
 +              reset_autoscan(device);
 +#else
                stop_autoscan(device);
 +#endif
  
                if (!wifi->connected)
                        connman_network_set_associating(network, true);
                break;
  
        case G_SUPPLICANT_STATE_COMPLETED:
 +#if defined TIZEN_EXT
 +              /* though it should be already reset: */
 +              reset_autoscan(device);
 +
 +              wifi->assoc_retry_count = 0;
 +
 +              wifi->scan_pending_network = NULL;
 +
 +              /* should be cleared scanning flag */
 +              bool scanning = connman_device_get_scanning(device);
 +              if (scanning){
 +                      connman_device_set_scanning(device,
 +                              CONNMAN_SERVICE_TYPE_WIFI, false);
 +                      connman_device_unref(device);
 +              }
 +#else
                /* though it should be already stopped: */
                stop_autoscan(device);
 +#endif
  
                if (!handle_wps_completion(interface, network, device, wifi))
                        break;
  
                connman_network_set_connected(network, true);
                wifi->disconnect_code = 0;
                wifi->assoc_code = 0;
+               wifi->load_shaping_retries = 0;
                break;
  
        case G_SUPPLICANT_STATE_DISCONNECTED:
                if (is_idle(wifi))
                        break;
  
+               if (handle_assoc_status_code(interface, wifi))
+                       break;
                /* If previous state was 4way-handshake, then
                 * it's either: psk was incorrect and thus we retry
                 * or if we reach the maximum retries we declare the
                default:
                        break;
                }
-               /* We disable the selected network, if not then
-                * wpa_supplicant will loop retrying */
-               if (g_supplicant_interface_enable_selected_network(interface,
-                                               FALSE) != 0)
-                       DBG("Could not disables selected network");
 +
 +#if defined TIZEN_EXT
 +              int err;
 +
 +              err = g_supplicant_interface_remove_network(wifi->interface);
 +              if (err < 0)
 +                      DBG("Failed to remove network(%d)", err);
 +
 +
 +              /* Some of Wi-Fi networks are not comply Wi-Fi specification.
 +               * Retry association until its retry count is expired */
 +              if (handle_wifi_assoc_retry(network, wifi) == true) {
 +                      throw_wifi_scan(wifi->device, scan_callback);
 +                      wifi->scan_pending_network = wifi->network;
 +                      break;
 +              }
 +
 +              if(wifi->disconnect_code > 0){
 +                      DBG("Set disconnect reason code(%d)", wifi->disconnect_code);
 +                      connman_network_set_disconnect_reason(network, wifi->disconnect_code);
 +              }
 +
 +              /* To avoid unnecessary repeated association in wpa_supplicant,
 +               * "RemoveNetwork" should be made when Wi-Fi is disconnected */
 +              if (wps != true && wifi->network && wifi->disconnecting == false) {
 +                      wifi->disconnecting = true;
 +                      err = g_supplicant_interface_disconnect(wifi->interface,
 +                                                      disconnect_callback, wifi->network);
 +                      if (err < 0)
 +                              wifi->disconnecting = false;
 +
 +              connman_network_set_connected(network, false);
 +              connman_network_set_associating(network, false);
 +
 +              start_autoscan(device);
 +
 +              break;
 +              }
 +#endif
 +
                connman_network_set_connected(network, false);
                connman_network_set_associating(network, false);
                wifi->disconnecting = false;
                break;
  
        case G_SUPPLICANT_STATE_INACTIVE:
 +#if defined TIZEN_EXT
 +              if (handle_wps_completion(interface, network, device, wifi) == false)
 +                      break;
 +#endif
                connman_network_set_associating(network, false);
                start_autoscan(device);
  
                break;
        }
  
+       old_connected = wifi->connected;
        wifi->state = state;
  
        /* Saving wpa_s state policy:
         * --> We are not connected
         * */
        switch (state) {
- #if defined TIZEN_EXT
-       case G_SUPPLICANT_STATE_SCANNING:
-               break;
- #endif
        case G_SUPPLICANT_STATE_AUTHENTICATING:
        case G_SUPPLICANT_STATE_ASSOCIATING:
        case G_SUPPLICANT_STATE_ASSOCIATED:
                if (wifi->connected)
                        connman_warn("Probably roaming right now!"
                                                " Staying connected...");
-               else
-                       wifi->connected = false;
+               break;
+       case G_SUPPLICANT_STATE_SCANNING:
+               wifi->connected = false;
+               if (old_connected)
+                       start_autoscan(device);
                break;
        case G_SUPPLICANT_STATE_COMPLETED:
                wifi->connected = true;
@@@ -3106,24 -2549,24 +3187,24 @@@ static void interface_removed(GSupplica
  static void set_device_type(const char *type, char dev_type[17])
  {
        const char *oui = "0050F204";
-       const char *category = "0100";
+       const char *category = "0001";
        const char *sub_category = "0000";
  
        if (!g_strcmp0(type, "handset")) {
-               category = "0A00";
-               sub_category = "0500";
+               category = "000A";
+               sub_category = "0005";
        } else if (!g_strcmp0(type, "vm") || !g_strcmp0(type, "container"))
-               sub_category = "0100";
+               sub_category = "0001";
        else if (!g_strcmp0(type, "server"))
-               sub_category = "0200";
+               sub_category = "0002";
        else if (!g_strcmp0(type, "laptop"))
-               sub_category = "0500";
+               sub_category = "0005";
        else if (!g_strcmp0(type, "desktop"))
-               sub_category = "0600";
+               sub_category = "0006";
        else if (!g_strcmp0(type, "tablet"))
-               sub_category = "0900";
+               sub_category = "0009";
        else if (!g_strcmp0(type, "watch"))
-               category = "FF00";
+               category = "00FF";
  
        snprintf(dev_type, 17, "%s%s%s", category, oui, sub_category);
  }
@@@ -3135,6 -2578,9 +3216,9 @@@ static void p2p_support(GSupplicantInte
  
        DBG("");
  
+       if (!interface)
+               return;
        if (!g_supplicant_interface_has_p2p(interface))
                return;
  
@@@ -3160,50 -2606,47 +3244,80 @@@ static void scan_started(GSupplicantInt
  
  static void scan_finished(GSupplicantInterface *interface)
  {
 +#if defined TIZEN_EXT
 +      struct wifi_data *wifi;
 +      bool is_associating = false;
 +      static bool is_scanning = true;
 +#endif
 +
        DBG("");
 +
 +#if defined TIZEN_EXT
 +      wifi = g_supplicant_interface_get_data(interface);
 +      if (wifi && wifi->scan_pending_network) {
 +              network_connect(wifi->scan_pending_network);
 +              wifi->scan_pending_network = NULL;
 +      }
 +
 +      //service state - associating
 +      if(!wifi || !wifi->network)
 +              return;
 +
 +      is_associating = connman_network_get_associating(wifi->network);
 +      if(is_associating && is_scanning){
 +              is_scanning = false;
 +              DBG("send scan for connecting");
 +              throw_wifi_scan(wifi->device, scan_callback);
 +
 +              return;
 +      }
 +      is_scanning = true;
 +
 +      //go scan
 +
 +#endif
  }
  
+ static void ap_create_fail(GSupplicantInterface *interface)
+ {
+       struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+       int ret;
+       if ((wifi->tethering) && (wifi->tethering_param)) {
+               DBG("%s create AP fail \n",
+                               g_supplicant_interface_get_ifname(wifi->interface));
+               connman_inet_remove_from_bridge(wifi->index, wifi->bridge);
+               wifi->ap_supported = WIFI_AP_NOT_SUPPORTED;
+               wifi->tethering = false;
+               ret = tech_set_tethering(wifi->tethering_param->technology,
+                               wifi->tethering_param->ssid->ssid,
+                               wifi->tethering_param->ssid->passphrase,
+                               wifi->bridge, true);
+               if ((ret == -EOPNOTSUPP) && (wifi_technology)) {
+                       connman_technology_tethering_notify(wifi_technology,false);
+               }
+               g_free(wifi->tethering_param->ssid);
+               g_free(wifi->tethering_param);
+               wifi->tethering_param = NULL;
+       }
+       return;
+ }
  static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network)
  {
        unsigned char strength;
  
        strength = 120 + g_supplicant_network_get_signal(supplicant_network);
 +
 +#if !defined TIZEN_EXT
        if (strength > 100)
                strength = 100;
 -
 +#endif
        return strength;
  }
  
@@@ -3220,10 -2663,6 +3334,11 @@@ static void network_added(GSupplicantNe
        bool wps_ready;
        bool wps_advertizing;
  
-       GSList *vsie_list = NULL;
 +#if defined TIZEN_EXT
++      const char *wifi_vsie;
++      unsigned int wifi_vsie_len;
 +#endif
 +
        mode = g_supplicant_network_get_mode(supplicant_network);
        identifier = g_supplicant_network_get_identifier(supplicant_network);
  
  
        ssid = g_supplicant_network_get_ssid(supplicant_network, &ssid_len);
  
++#if defined TIZEN_EXT
++      wifi_vsie = g_supplicant_network_get_wifi_vsie(supplicant_network, &wifi_vsie_len);
++#endif
        network = connman_device_get_network(wifi->device, identifier);
  
        if (!network) {
  
        connman_network_set_blob(network, "WiFi.SSID",
                                                ssid, ssid_len);
-       vsie_list = (GSList *)g_supplicant_network_get_wifi_vsie(supplicant_network);
-       if (vsie_list)
-               connman_network_set_vsie_list(network, vsie_list);
-       else
-               DBG("vsie_list is NULL");
 +#if defined TIZEN_EXT
++      if(wifi_vsie_len > 0 && wifi_vsie)
++              connman_network_set_blob(network, "WiFi.Vsie",
++                                                      wifi_vsie, wifi_vsie_len);
 +#endif
        connman_network_set_string(network, "WiFi.Security", security);
        connman_network_set_strength(network,
                                calculate_strength(supplicant_network));
                /* Is AP advertizing for WPS association?
                 * If so, we decide to use WPS by default */
                if (wps_ready && wps_pbc &&
 -                                              wps_advertizing)
 +                                              wps_advertizing) {
 +#if !defined TIZEN_EXT
                        connman_network_set_bool(network, "WiFi.UseWPS", true);
 +#else
 +                      DBG("wps is activating by ap but ignore it.");
 +#endif
 +              }
        }
  
        connman_network_set_frequency(network,
                        g_supplicant_network_get_frequency(supplicant_network));
 -
 +#if defined TIZEN_EXT
 +      connman_network_set_bssid(network,
 +                      g_supplicant_network_get_bssid(supplicant_network));
 +      connman_network_set_maxrate(network,
 +                      g_supplicant_network_get_maxrate(supplicant_network));
 +      connman_network_set_enc_mode(network,
 +                      g_supplicant_network_get_enc_mode(supplicant_network));
 +      connman_network_set_rsn_mode(network,
 +                      g_supplicant_network_get_rsn_mode(supplicant_network));
 +      connman_network_set_keymgmt(network,
 +                      g_supplicant_network_get_keymgmt(supplicant_network));
 +      connman_network_set_bool(network, "WiFi.HS20AP",
 +                      g_supplicant_network_is_hs20AP(supplicant_network));
 +#endif
        connman_network_set_available(network, true);
        connman_network_set_string(network, "WiFi.Mode", mode);
  
 +#if defined TIZEN_EXT
 +      if (group)
 +#else
        if (ssid)
 +#endif
                connman_network_set_group(network, group);
  
 +#if defined TIZEN_EXT
 +      if (wifi_first_scan == true)
 +              found_with_first_scan = true;
 +#endif
 +
        if (wifi->hidden && ssid) {
 +#if defined TIZEN_EXT
 +              if (network_security(wifi->hidden->security) ==
 +                      network_security(security) &&
 +#else
                if (!g_strcmp0(wifi->hidden->security, security) &&
 +#endif
                                wifi->hidden->ssid_len == ssid_len &&
                                !memcmp(wifi->hidden->ssid, ssid, ssid_len)) {
                        connman_network_connect_hidden(network,
@@@ -3368,18 -2768,6 +3484,18 @@@ static void network_removed(GSupplicant
        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);
@@@ -3393,13 -2781,6 +3509,13 @@@ static void network_changed(GSupplicant
        const char *name, *identifier;
        struct connman_network *connman_network;
  
 +#if defined TIZEN_EXT
 +      const unsigned char *bssid;
 +      unsigned int maxrate;
 +      uint16_t frequency;
 +      bool wps;
 +#endif
 +
        interface = g_supplicant_network_get_interface(network);
        wifi = g_supplicant_interface_get_data(interface);
        identifier = g_supplicant_network_get_identifier(network);
                                        calculate_strength(network));
               connman_network_update(connman_network);
        }
 +
 +#if defined TIZEN_EXT
 +      bssid = g_supplicant_network_get_bssid(network);
 +      maxrate = g_supplicant_network_get_maxrate(network);
 +      frequency = g_supplicant_network_get_frequency(network);
 +      wps = g_supplicant_network_get_wps(network);
 +
 +      connman_network_set_bssid(connman_network, bssid);
 +      connman_network_set_maxrate(connman_network, maxrate);
 +      connman_network_set_frequency(connman_network, frequency);
 +      connman_network_set_bool(connman_network, "WiFi.WPS", wps);
 +#endif
  }
  
+ static void network_associated(GSupplicantNetwork *network)
+ {
+       GSupplicantInterface *interface;
+       struct wifi_data *wifi;
+       struct connman_network *connman_network;
+       const char *identifier;
+       DBG("");
+       interface = g_supplicant_network_get_interface(network);
+       if (!interface)
+               return;
+       wifi = g_supplicant_interface_get_data(interface);
+       if (!wifi)
+               return;
+       identifier = g_supplicant_network_get_identifier(network);
+       connman_network = connman_device_get_network(wifi->device, identifier);
+       if (!connman_network)
+               return;
+       if (wifi->network) {
+               if (wifi->network == connman_network)
+                       return;
+               /*
+                * This should never happen, we got associated with
+                * a network different than the one we were expecting.
+                */
+               DBG("Associated to %p while expecting %p",
+                                       connman_network, wifi->network);
+               connman_network_set_associating(wifi->network, false);
+       }
+       DBG("Reconnecting to previous network %p from wpa_s", connman_network);
+       wifi->network = connman_network_ref(connman_network);
+       wifi->retries = 0;
+       /*
+        * Interface state changes callback (interface_state) is always
+        * called before network_associated callback thus we need to call
+        * interface_state again in order to process the new state now that
+        * we have the network properly set.
+        */
+       interface_state(interface);
+ }
  static void apply_peer_services(GSupplicantPeer *peer,
                                struct connman_peer *connman_peer)
  {
        }
  }
  
 +static void add_station(const char *mac)
 +{
 +      connman_technology_tethering_add_station(CONNMAN_SERVICE_TYPE_WIFI,
 +                                               mac);
 +}
 +
 +static void remove_station(const char *mac)
 +{
 +      connman_technology_tethering_remove_station(mac);
 +}
 +
  static void peer_found(GSupplicantPeer *peer)
  {
        GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
        struct connman_peer *connman_peer;
        const char *identifier, *name;
        int ret;
 -
 +#if defined TIZEN_EXT
 +      if (!wifi)
 +              return;
 +#endif
        identifier = g_supplicant_peer_get_identifier(peer);
        name = g_supplicant_peer_get_name(peer);
  
        ret = connman_peer_register(connman_peer);
        if (ret < 0 && ret != -EALREADY)
                connman_peer_unref(connman_peer);
+       else
+               wifi->peers = g_slist_prepend(wifi->peers, connman_peer);
  }
  
  static void peer_lost(GSupplicantPeer *peer)
                connman_peer_unregister(connman_peer);
                connman_peer_unref(connman_peer);
        }
+       wifi->peers = g_slist_remove(wifi->peers, connman_peer);
  }
  
  static void peer_changed(GSupplicantPeer *peer, GSupplicantPeerState state)
        struct connman_peer *connman_peer;
        const char *identifier;
  
 +#if defined TIZEN_EXT
 +      if (!wifi)
 +              return;
 +#endif
 +
        identifier = g_supplicant_peer_get_identifier(peer);
  
        DBG("ident: %s", identifier);
  
+       if (!wifi)
+               return;
        connman_peer = connman_peer_get(wifi->device, identifier);
        if (!connman_peer)
                return;
                connman_peer_set_as_master(connman_peer,
                                        !g_supplicant_peer_is_client(peer));
                connman_peer_set_sub_device(connman_peer, g_wifi->device);
+               /*
+                * If wpa_supplicant didn't create a dedicated p2p-group
+                * interface then mark this interface as p2p_device to avoid
+                * scan and auto-scan are launched on it while P2P is connected.
+                */
+               if (!g_list_find(p2p_iface_list, g_wifi))
+                       wifi->p2p_device = true;
        }
  
        connman_peer_set_state(connman_peer, p_state);
@@@ -3607,11 -3023,6 +3789,11 @@@ static void peer_request(GSupplicantPee
        struct connman_peer *connman_peer;
        const char *identifier;
  
 +#if defined TIZEN_EXT
 +      if (!wifi)
 +              return;
 +#endif
 +
        identifier = g_supplicant_peer_get_identifier(peer);
  
        DBG("ident: %s", identifier);
        connman_peer_request_connection(connman_peer);
  }
  
 +#if defined TIZEN_EXT
 +static void system_power_off(void)
 +{
 +      GList *list;
 +      struct wifi_data *wifi;
 +      struct connman_service *service;
 +      struct connman_ipconfig *ipconfig_ipv4;
 +
 +      if (connman_setting_get_bool("WiFiDHCPRelease") == true) {
 +              for (list = iface_list; list; list = list->next) {
 +                      wifi = list->data;
 +
 +                      if (wifi->network != NULL) {
 +                              service = connman_service_lookup_from_network(wifi->network);
 +                              ipconfig_ipv4 = __connman_service_get_ip4config(service);
 +                              __connman_dhcp_stop(ipconfig_ipv4);
 +                      }
 +              }
 +      }
 +}
 +
 +static void network_merged(GSupplicantNetwork *network)
 +{
 +      GSupplicantInterface *interface;
 +      GSupplicantState state;
 +      struct wifi_data *wifi;
 +      const char *identifier;
 +      struct connman_network *connman_network;
 +      bool ishs20AP = 0;
 +      char *temp = NULL;
 +
 +      interface = g_supplicant_network_get_interface(network);
 +      if (!interface)
 +              return;
 +
 +      state = g_supplicant_interface_get_state(interface);
 +      if (state < G_SUPPLICANT_STATE_AUTHENTICATING)
 +              return;
 +
 +      wifi = g_supplicant_interface_get_data(interface);
 +      if (!wifi)
 +              return;
 +
 +      identifier = g_supplicant_network_get_identifier(network);
 +
 +      connman_network = connman_device_get_network(wifi->device, identifier);
 +      if (!connman_network)
 +              return;
 +
 +      DBG("merged identifier %s", identifier);
 +
 +      if (wifi->connected == FALSE) {
 +              switch (state) {
 +              case G_SUPPLICANT_STATE_AUTHENTICATING:
 +              case G_SUPPLICANT_STATE_ASSOCIATING:
 +              case G_SUPPLICANT_STATE_ASSOCIATED:
 +              case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
 +              case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
 +                      connman_network_set_associating(connman_network, TRUE);
 +                      break;
 +              case G_SUPPLICANT_STATE_COMPLETED:
 +                      connman_network_set_connected(connman_network, TRUE);
 +                      break;
 +              default:
 +                      DBG("Not handled the state : %d", state);
 +                      break;
 +              }
 +      }
 +
 +      ishs20AP = g_supplicant_network_is_hs20AP(network);
 +
 +      if (ishs20AP &&
 +              g_strcmp0(g_supplicant_network_get_security(network), "ieee8021x") == 0) {
 +              temp = g_ascii_strdown(g_supplicant_network_get_eap(network), -1);
 +              connman_network_set_string(connman_network, "WiFi.EAP",
 +                              temp);
 +              connman_network_set_string(connman_network, "WiFi.Identity",
 +                              g_supplicant_network_get_identity(network));
 +              connman_network_set_string(connman_network, "WiFi.Phase2",
 +                              g_supplicant_network_get_phase2(network));
 +
 +              g_free(temp);
 +      }
 +
 +      wifi->network = connman_network;
 +}
 +
 +static void assoc_failed(void *user_data)
 +{
 +      struct connman_network *network = user_data;
 +      connman_network_set_associating(network, false);
 +}
 +#endif
 +
  static void debug(const char *str)
  {
        if (getenv("CONNMAN_SUPPLICANT_DEBUG"))
@@@ -3727,6 -3044,7 +3909,7 @@@ static void disconnect_reasoncode(GSupp
                                int reasoncode)
  {
        struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
        if (wifi != NULL) {
                wifi->disconnect_code = reasoncode;
        }
@@@ -3736,18 -3054,8 +3919,8 @@@ static void assoc_status_code(GSupplica
  {
        struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
  
- #if defined TIZEN_EXT
-       struct connman_network *network;
- #endif
        if (wifi != NULL) {
                wifi->assoc_code = status_code;
- #if defined TIZEN_EXT
-               network = wifi->network;
-               connman_network_set_assoc_status_code(network,status_code);
- #endif
        }
  }
  
@@@ -3760,23 -3068,18 +3933,25 @@@ static const GSupplicantCallbacks callb
        .p2p_support            = p2p_support,
        .scan_started           = scan_started,
        .scan_finished          = scan_finished,
+       .ap_create_fail         = ap_create_fail,
        .network_added          = network_added,
        .network_removed        = network_removed,
        .network_changed        = network_changed,
+       .network_associated     = network_associated,
 +      .add_station            = add_station,
 +      .remove_station         = remove_station,
        .peer_found             = peer_found,
        .peer_lost              = peer_lost,
        .peer_changed           = peer_changed,
        .peer_request           = peer_request,
-       .network_merged         = network_merged,
 +#if defined TIZEN_EXT
 +      .system_power_off       = system_power_off,
++      .network_merged = network_merged,
 +      .assoc_failed           = assoc_failed,
 +#endif
+       .debug                  = debug,
        .disconnect_reasoncode  = disconnect_reasoncode,
        .assoc_status_code      = assoc_status_code,
-       .debug                  = debug,
  };
  
  
@@@ -3792,15 -3095,7 +3967,8 @@@ static void tech_remove(struct connman_
        wifi_technology = NULL;
  }
  
- struct wifi_tethering_info {
-       struct wifi_data *wifi;
-       struct connman_technology *technology;
-       char *ifname;
-       GSupplicantSSID *ssid;
- };
 -static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
 +static GSupplicantSSID *ssid_ap_init(const char *ssid,
-               const char *passphrase, bool hidden)
++              const char *passphrase)
  {
        GSupplicantSSID *ap;
  
               ap->passphrase = passphrase;
        }
  
-       if (hidden)
-               ap->ignore_broadcast_ssid =
-                               G_SUPPLICANT_AP_HIDDEN_SSID_ZERO_CONTENTS;
-       else
-               ap->ignore_broadcast_ssid = G_SUPPLICANT_AP_NO_SSID_HIDING;
        return ap;
  }
  
@@@ -3842,10 -3131,16 +4004,16 @@@ static void ap_start_callback(int resul
        DBG("result %d index %d bridge %s",
                result, info->wifi->index, info->wifi->bridge);
  
-       if (result < 0) {
+       if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
                connman_inet_remove_from_bridge(info->wifi->index,
                                                        info->wifi->bridge);
-               connman_technology_tethering_notify(info->technology, false);
+               if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
+                       connman_technology_tethering_notify(info->technology, false);
+                       g_free(info->wifi->tethering_param->ssid);
+                       g_free(info->wifi->tethering_param);
+                       info->wifi->tethering_param = NULL;
+               }
        }
  
        g_free(info->ifname);
@@@ -3861,10 -3156,17 +4029,17 @@@ static void ap_create_callback(int resu
        DBG("result %d ifname %s", result,
                                g_supplicant_interface_get_ifname(interface));
  
-       if (result < 0) {
+       if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
                connman_inet_remove_from_bridge(info->wifi->index,
                                                        info->wifi->bridge);
-               connman_technology_tethering_notify(info->technology, false);
+               if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
+                       connman_technology_tethering_notify(info->technology, false);
+                       g_free(info->wifi->tethering_param->ssid);
+                       g_free(info->wifi->tethering_param);
+                       info->wifi->tethering_param = NULL;
+               }
  
                g_free(info->ifname);
                g_free(info->ssid);
@@@ -3891,27 -3193,32 +4066,32 @@@ static void sta_remove_callback(int res
  
        DBG("ifname %s result %d ", info->ifname, result);
  
-       if (result < 0) {
-               info->wifi->tethering = true;
 -      if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
++      if (result < 0 || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
+               info->wifi->tethering = false;
+               connman_technology_tethering_notify(info->technology, false);
  
                g_free(info->ifname);
                g_free(info->ssid);
                g_free(info);
+               if (info->wifi->ap_supported == WIFI_AP_SUPPORTED) {
+                       g_free(info->wifi->tethering_param->ssid);
+                       g_free(info->wifi->tethering_param);
+                       info->wifi->tethering_param = NULL;
+               }
                return;
        }
  
        info->wifi->interface = NULL;
  
-       connman_technology_tethering_notify(info->technology, true);
        g_supplicant_interface_create(info->ifname, driver, info->wifi->bridge,
                                                ap_create_callback,
                                                        info);
  }
  
- static int tech_set_tethering(struct connman_technology *technology,
-                               const char *identifier, const char *passphrase,
-                               const char *bridge, bool enabled, bool hidden)
+ static int enable_wifi_tethering(struct connman_technology *technology,
+                               const char *bridge, const char *identifier,
+                               const char *passphrase, bool available)
  {
        GList *list;
        GSupplicantInterface *interface;
        struct wifi_tethering_info *info;
        const char *ifname;
        unsigned int mode;
-       int err;
-       DBG("");
-       if (!enabled) {
-               for (list = iface_list; list; list = list->next) {
-                       wifi = list->data;
-                       if (wifi->tethering) {
-                               wifi->tethering = false;
-                               connman_inet_remove_from_bridge(wifi->index,
-                                                                       bridge);
-                               wifi->bridged = false;
-                       }
-               }
-               connman_technology_tethering_notify(technology, false);
-               return 0;
-       }
+       int err, berr = 0;
  
        for (list = iface_list; list; list = list->next) {
                wifi = list->data;
  
+               DBG("wifi %p network %p pending_network %p", wifi,
+                       wifi->network, wifi->pending_network);
                interface = wifi->interface;
  
                if (!interface)
                        continue;
  
 -              ifname = g_supplicant_interface_get_ifname(wifi->interface);
 -              if (!ifname)
++              if (wifi->ap_supported == WIFI_AP_NOT_SUPPORTED)
+                       continue;
 +              ifname = g_supplicant_interface_get_ifname(wifi->interface);
 +
+               if (wifi->ap_supported == WIFI_AP_NOT_SUPPORTED) {
+                       DBG("%s does not support AP mode (detected)", ifname);
+                       continue;
+               }
                mode = g_supplicant_interface_get_mode(interface);
                if ((mode & G_SUPPLICANT_CAPABILITY_MODE_AP) == 0) {
-                       DBG("%s does not support AP mode", ifname);
+                       wifi->ap_supported = WIFI_AP_NOT_SUPPORTED;
+                       DBG("%s does not support AP mode (capability)", ifname);
                        continue;
                }
  
+               if (wifi->network && available)
+                       continue;
                info = g_try_malloc0(sizeof(struct wifi_tethering_info));
                if (!info)
                        return -ENOMEM;
  
+               wifi->tethering_param = g_try_malloc0(sizeof(struct wifi_tethering_info));
+               if (!wifi->tethering_param) {
+                       g_free(info);
+                       return -ENOMEM;
+               }
                info->wifi = wifi;
                info->technology = technology;
                info->wifi->bridge = bridge;
-               info->ssid = ssid_ap_init(identifier, passphrase, hidden);
-               if (!info->ssid) {
-                       g_free(info);
-                       continue;
-               }
+               info->ssid = ssid_ap_init(identifier, passphrase);
+               if (!info->ssid)
+                       goto failed;
                info->ifname = g_strdup(ifname);
-               if (!info->ifname) {
-                       g_free(info->ssid);
-                       g_free(info);
-                       continue;
-               }
++              if (!info->ifname)
++                      goto failed;
+               wifi->tethering_param->technology = technology;
+               wifi->tethering_param->ssid = ssid_ap_init(identifier, passphrase);
+               if (!wifi->tethering_param->ssid)
+                       goto failed;
  
                info->wifi->tethering = true;
+               info->wifi->ap_supported = WIFI_AP_SUPPORTED;
+               berr = connman_technology_tethering_notify(technology, true);
+               if (berr < 0)
+                       goto failed;
  
                err = g_supplicant_interface_remove(interface,
                                                sta_remove_callback,
                                                        info);
-               if (err == 0)
-                       return err;
+               if (err >= 0) {
+                       DBG("tethering wifi %p ifname %s", wifi, ifname);
+                       return 0;
+               }
+       failed:
+               g_free(info->ifname);
+               g_free(info->ssid);
+               g_free(info);
+               g_free(wifi->tethering_param);
+               wifi->tethering_param = NULL;
+               /*
+                * Remove bridge if it was correctly created but remove
+                * operation failed. Instead, if bridge creation failed then
+                * break out and do not try again on another interface,
+                * bridge set-up does not depend on it.
+                */
+               if (berr == 0)
+                       connman_technology_tethering_notify(technology, false);
+               else
+                       break;
        }
  
        return -EOPNOTSUPP;
  }
  
+ static int tech_set_tethering(struct connman_technology *technology,
+                               const char *identifier, const char *passphrase,
+                               const char *bridge, bool enabled)
+ {
+       GList *list;
+       struct wifi_data *wifi;
+       int err;
+       DBG("");
+       if (!enabled) {
+               for (list = iface_list; list; list = list->next) {
+                       wifi = list->data;
+                       if (wifi->tethering) {
+                               wifi->tethering = false;
+                               connman_inet_remove_from_bridge(wifi->index,
+                                                                       bridge);
+                               wifi->bridged = false;
+                       }
+               }
+               connman_technology_tethering_notify(technology, false);
+               return 0;
+       }
+       DBG("trying tethering for available devices");
+       err = enable_wifi_tethering(technology, bridge, identifier, passphrase,
+                               true);
+       if (err < 0) {
+               DBG("trying tethering for any device");
+               err = enable_wifi_tethering(technology, bridge, identifier,
+                                       passphrase, false);
+       }
+       return err;
+ }
  static void regdom_callback(int result, const char *alpha2, void *user_data)
  {
        DBG("");
diff --combined scripts/connman.in
index 2c380ab,0b9f63c..f3d438f
mode 100755,100644..100755
@@@ -1,6 -1,6 +1,6 @@@
  #!/bin/sh
  
 -DAEMON=@sbindir@/connmand
 +DAEMON=@bindir@/connmand
  DESC="Connection Manager"
  
  . /lib/lsb/init-functions
@@@ -9,6 -9,11 +9,11 @@@ if [ -f @sysconfdir@/default/connman ] 
        . @sysconfdir@/default/connman
  fi
  
+ if [ "CONNMAN_RUNSTATEDIR_RESOLVCONF" != "no" ] ; then
+     mkdir -p @runstatedir@/connman
+     ln -sf @runstatedir@/connman/resolv.conf /etc/
+ fi
  set -e
  
  do_start() {
diff --combined src/6to4.c
index 0e3a7a1,71a2882..71a2882
mode 100755,100644..100755
@@@ -63,7 -63,7 +63,7 @@@ static int tunnel_create(struct in_add
  {
        struct ip_tunnel_parm p;
        struct ifreq ifr;
-       int fd = -1;
+       int fd;
        int ret;
  
        /* ip tunnel add tun6to4 mode sit remote any local 1.2.3.4 ttl 64 */
diff --combined src/agent-connman.c
index 177cbe0,fca7cc1..e4850a8
mode 100755,100644..100755
@@@ -100,73 -100,101 +100,101 @@@ static void request_input_passphrase_re
                DBusMessageIter entry, value;
  
                dbus_message_iter_recurse(&dict, &entry);
-               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
+                       error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                        break;
+               }
  
                dbus_message_iter_get_basic(&entry, &key);
  
                if (g_str_equal(key, "Identity")) {
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry)
-                                                       != DBUS_TYPE_VARIANT)
+                                                       != DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
+                       }
                        dbus_message_iter_recurse(&entry, &value);
+                       if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+                               break;
+                       }
                        dbus_message_iter_get_basic(&value, &identity);
  
                } else if (g_str_equal(key, "Passphrase")) {
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry)
-                                                       != DBUS_TYPE_VARIANT)
+                                                       != DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
+                       }
                        dbus_message_iter_recurse(&entry, &value);
+                       if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+                               break;
+                       }
                        dbus_message_iter_get_basic(&value, &passphrase);
  
                } else if (g_str_equal(key, "WPS")) {
-                       wps = true;
  
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry)
-                                                       != DBUS_TYPE_VARIANT)
+                                                       != DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
+                       }
                        dbus_message_iter_recurse(&entry, &value);
+                       if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+                               break;
+                       }
+                       wps = true;
                        dbus_message_iter_get_basic(&value, &wpspin);
                        break;
                } else if (g_str_equal(key, "Name")) {
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry)
-                                                       != DBUS_TYPE_VARIANT)
+                                                       != DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
+                       }
                        dbus_message_iter_recurse(&entry, &value);
+                       if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+                               break;
+                       }
                        dbus_message_iter_get_basic(&value, &name);
                        name_len = strlen(name);
                } else if (g_str_equal(key, "SSID")) {
- #if defined TIZEN_EXT
-                       DBusMessageIter array;
- #endif
+                       DBusMessageIter array_iter;
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry)
-                                                       != DBUS_TYPE_VARIANT)
-                               break;
- #if defined TIZEN_EXT
-                       dbus_message_iter_recurse(&entry, &array);
-                       if (dbus_message_iter_get_arg_type(&array)
-                                                       != DBUS_TYPE_ARRAY)
-                               break;
-                       dbus_message_iter_recurse(&array, &value);
-                       if (dbus_message_iter_get_arg_type(&value)
-                                                       != DBUS_TYPE_BYTE)
+                                                       != DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
- #else
+                       }
                        dbus_message_iter_recurse(&entry, &value);
                        if (dbus_message_iter_get_arg_type(&value)
-                                                       != DBUS_TYPE_VARIANT)
+                                                       != DBUS_TYPE_ARRAY) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
-                       if (dbus_message_iter_get_element_type(&value)
-                                                       != DBUS_TYPE_VARIANT)
+                       }
+                       dbus_message_iter_recurse(&value, &array_iter);
+                       if (dbus_message_iter_get_arg_type(&array_iter)
+                                                       != DBUS_TYPE_BYTE) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
- #endif
-                       dbus_message_iter_get_fixed_array(&value, &name,
+                       }
+                       dbus_message_iter_get_fixed_array(&array_iter, &name,
                                                        &name_len);
                }
                dbus_message_iter_next(&dict);
@@@ -225,9 -253,6 +253,9 @@@ static void request_input_append_passph
                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:
@@@ -361,9 -386,6 +389,9 @@@ static void previous_passphrase_handler
                        data.type = "wep";
                        break;
                case CONNMAN_SERVICE_SECURITY_PSK:
 +#if defined TIZEN_EXT
 +              case CONNMAN_SERVICE_SECURITY_RSN:
 +#endif
                        data.type  = "psk";
                        break;
                /*
@@@ -417,17 -439,33 +445,33 @@@ static void request_input_login_reply(D
                if (g_str_equal(key, "Username")) {
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry)
-                                                       != DBUS_TYPE_VARIANT)
+                                                       != DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
+                       }
                        dbus_message_iter_recurse(&entry, &value);
+                       if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+                               break;
+                       }
                        dbus_message_iter_get_basic(&value, &username);
  
                } else if (g_str_equal(key, "Password")) {
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry) !=
-                                                       DBUS_TYPE_VARIANT)
+                                                       DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
+                       }
                        dbus_message_iter_recurse(&entry, &value);
+                       if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+                               break;
+                       }
                        dbus_message_iter_get_basic(&value, &password);
                }
  
@@@ -723,8 -761,10 +767,10 @@@ static void request_peer_authorization_
                DBusMessageIter entry, value;
  
                dbus_message_iter_recurse(&dict, &entry);
-               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
+                       error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                        break;
+               }
  
                dbus_message_iter_get_basic(&entry, &key);
  
  
                        dbus_message_iter_next(&entry);
                        if (dbus_message_iter_get_arg_type(&entry)
-                                                       != DBUS_TYPE_VARIANT)
+                                                       != DBUS_TYPE_VARIANT) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
                                break;
+                       }
                        dbus_message_iter_recurse(&entry, &value);
+                       if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING) {
+                               error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+                               break;
+                       }
                        dbus_message_iter_get_basic(&value, &wpspin);
                        break;
                }
diff --combined src/agent.c
index bdeb0e7,8f7b19b..8f7b19b
mode 100755,100644..100755
@@@ -165,12 -165,17 +165,17 @@@ static int send_cancel_request(struct c
                        struct connman_agent_request *request)
  {
        DBusMessage *message;
+       const char *interface = NULL;
  
-       DBG("send cancel req to %s %s", agent->owner, agent->path);
+       if (request && request->driver)
+               interface = request->driver->interface;
+       DBG("send cancel req to %s %s iface %s", agent->owner, agent->path,
+                                                               interface);
  
        message = dbus_message_new_method_call(agent->owner,
                                        agent->path,
-                                       request->driver->interface,
+                                       interface,
                                        "Cancel");
        if (!message) {
                connman_error("Couldn't allocate D-Bus message");
@@@ -519,12 -524,12 +524,12 @@@ void connman_agent_cancel(void *user_co
                                                                user_context) {
                                DBG("cancel pending %p", request);
  
+                               agent->queue = g_list_delete_link(agent->queue,
+                                                                       list);
                                request->callback(NULL, request->user_data);
  
                                agent_request_free(request);
-                               agent->queue = g_list_delete_link(agent->queue,
-                                                                       list);
                        }
  
                        list = next;
@@@ -581,7 -586,7 +586,7 @@@ static void agent_release(struct connma
  
        message = dbus_message_new_method_call(agent->owner, agent->path,
                                                interface, "Release");
-       if (message == NULL) {
+       if (!message) {
                connman_error("Couldn't allocate D-Bus message");
                return;
        }
diff --combined src/bridge.c
index ba20096,cd2d9ce..cd2d9ce
mode 100755,100644..100755
@@@ -56,7 -56,7 +56,7 @@@ static int set_forward_delay(const cha
        if (!f)
                return -errno;
  
-       fprintf(f, "%d", delay);
+       fprintf(f, "%u", delay);
  
        fclose(f);
  
diff --combined src/config.c
index 25dd174,a8c3da8..75cd717
mode 100755,100644..100755
@@@ -45,7 -45,12 +45,12 @@@ struct connman_config_service 
        unsigned int ssid_len;
        char *eap;
        char *identity;
+       char *anonymous_identity;
        char *ca_cert_file;
+       char *subject_match;
+       char *altsubject_match;
+       char *domain_suffix_match;
+       char *domain_match;
        char *client_cert_file;
        char *private_key_file;
        char *private_key_passphrase;
@@@ -98,6 -103,11 +103,11 @@@ static bool cleanup = false
  #define SERVICE_KEY_PRV_KEY_PASS       "PrivateKeyPassphrase"
  #define SERVICE_KEY_PRV_KEY_PASS_TYPE  "PrivateKeyPassphraseType"
  #define SERVICE_KEY_IDENTITY           "Identity"
+ #define SERVICE_KEY_ANONYMOUS_IDENTITY "AnonymousIdentity"
+ #define SERVICE_KEY_SUBJECT_MATCH      "SubjectMatch"
+ #define SERVICE_KEY_ALT_SUBJECT_MATCH  "AltSubjectMatch"
+ #define SERVICE_KEY_DOMAIN_SUFF_MATCH  "DomainSuffixMatch"
+ #define SERVICE_KEY_DOMAIN_MATCH       "DomainMatch"
  #define SERVICE_KEY_PHASE2             "Phase2"
  #define SERVICE_KEY_PASSPHRASE         "Passphrase"
  #define SERVICE_KEY_SECURITY           "Security"
@@@ -129,6 -139,11 +139,11 @@@ static const char *service_possible_key
        SERVICE_KEY_PRV_KEY_PASS,
        SERVICE_KEY_PRV_KEY_PASS_TYPE,
        SERVICE_KEY_IDENTITY,
+       SERVICE_KEY_ANONYMOUS_IDENTITY,
+       SERVICE_KEY_SUBJECT_MATCH,
+       SERVICE_KEY_ALT_SUBJECT_MATCH,
+       SERVICE_KEY_DOMAIN_SUFF_MATCH,
+       SERVICE_KEY_DOMAIN_MATCH,
        SERVICE_KEY_PHASE2,
        SERVICE_KEY_PASSPHRASE,
        SERVICE_KEY_SECURITY,
@@@ -220,7 -235,12 +235,12 @@@ free_only
        g_free(config_service->ssid);
        g_free(config_service->eap);
        g_free(config_service->identity);
+       g_free(config_service->anonymous_identity);
        g_free(config_service->ca_cert_file);
+       g_free(config_service->subject_match);
+       g_free(config_service->altsubject_match);
+       g_free(config_service->domain_suffix_match);
+       g_free(config_service->domain_match);
        g_free(config_service->client_cert_file);
        g_free(config_service->private_key_file);
        g_free(config_service->private_key_passphrase);
@@@ -655,6 -675,41 +675,41 @@@ static bool load_service(GKeyFile *keyf
                service->identity = str;
        }
  
+       str = __connman_config_get_string(keyfile, group,
+                                       SERVICE_KEY_ANONYMOUS_IDENTITY, NULL);
+       if (str) {
+               g_free(service->anonymous_identity);
+               service->anonymous_identity = str;
+       }
+       str = __connman_config_get_string(keyfile, group,
+                                       SERVICE_KEY_SUBJECT_MATCH, NULL);
+       if (str) {
+               g_free(service->subject_match);
+               service->subject_match = str;
+       }
+       str = __connman_config_get_string(keyfile, group,
+                                       SERVICE_KEY_ALT_SUBJECT_MATCH, NULL);
+       if (str) {
+               g_free(service->altsubject_match);
+               service->altsubject_match = str;
+       }
+       str = __connman_config_get_string(keyfile, group,
+                                       SERVICE_KEY_DOMAIN_SUFF_MATCH, NULL);
+       if (str) {
+               g_free(service->domain_suffix_match);
+               service->domain_suffix_match = str;
+       }
+       str = __connman_config_get_string(keyfile, group,
+                                       SERVICE_KEY_DOMAIN_MATCH, NULL);
+       if (str) {
+               g_free(service->domain_match);
+               service->domain_match = str;
+       }
        str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PHASE2, NULL);
        if (str) {
                g_free(service->phase2);
  
                if (str) {
                        if (security == CONNMAN_SERVICE_SECURITY_PSK ||
 +#if defined TIZEN_EXT
 +                          security == CONNMAN_SERVICE_SECURITY_RSN ||
 +#endif
                                        security == CONNMAN_SERVICE_SECURITY_WEP) {
                                service->security = security;
                        } else {
  
                } else
                        service->security = CONNMAN_SERVICE_SECURITY_PSK;
-       }
+       } else if (str) {
 -              if (security != CONNMAN_SERVICE_SECURITY_NONE)
++              if (security != CONNMAN_SERVICE_SECURITY_NONE) {
+                       connman_info("Mismatch no security and "
+                                       "setting %s = %s",
+                                       SERVICE_KEY_SECURITY, str);
 -
 -              service->security = CONNMAN_SERVICE_SECURITY_NONE;
++              }
++                      service->security = CONNMAN_SERVICE_SECURITY_NONE;
+       } else
 -              service->security = CONNMAN_SERVICE_SECURITY_NONE;
++                      service->security = CONNMAN_SERVICE_SECURITY_NONE;
+       g_free(str);
  
        service->config_ident = g_strdup(config->ident);
        service->config_entry = g_strdup_printf("service_%s", service->ident);
@@@ -894,10 -957,10 +960,10 @@@ static void config_notify_handler(struc
                return;
        }
  
-       if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO)
+       if (event->mask & (IN_CREATE | IN_MOVED_TO))
                create_config(ident);
  
-       if (event->mask & IN_MODIFY) {
+       if (event->mask & (IN_MODIFY | IN_MOVED_TO)) {
                struct connman_config *config;
  
                config = g_hash_table_lookup(config_table, ident);
                }
        }
  
-       if (event->mask & IN_DELETE)
+       if (event->mask & (IN_DELETE | IN_MOVED_FROM))
                g_hash_table_remove(config_table, ident);
  }
  
@@@ -956,6 -1019,11 +1022,11 @@@ char *__connman_config_get_string(GKeyF
        if (!str)
                return NULL;
  
+       /* passphrases can have spaces in the end */
+       if (!g_strcmp0(key, SERVICE_KEY_PASSPHRASE) ||
+                       !g_strcmp0(key, SERVICE_KEY_PRV_KEY_PASS))
+               return str;
        return g_strchomp(str);
  }
  
@@@ -1028,10 -1096,30 +1099,30 @@@ static void provision_service_wifi(stru
                __connman_service_set_string(service, "Identity",
                                                        config->identity);
  
+       if (config->anonymous_identity)
+               __connman_service_set_string(service, "AnonymousIdentity",
+                                               config->anonymous_identity);
        if (config->ca_cert_file)
                __connman_service_set_string(service, "CACertFile",
                                                        config->ca_cert_file);
  
+       if (config->subject_match)
+               __connman_service_set_string(service, "SubjectMatch",
+                                                       config->subject_match);
+       if (config->altsubject_match)
+               __connman_service_set_string(service, "AltSubjectMatch",
+                                                       config->altsubject_match);
+       if (config->domain_suffix_match)
+               __connman_service_set_string(service, "DomainSuffixMatch",
+                                                       config->domain_suffix_match);
+       if (config->domain_match)
+               __connman_service_set_string(service, "DomainMatch",
+                                                       config->domain_match);
        if (config->client_cert_file)
                __connman_service_set_string(service, "ClientCertFile",
                                                config->client_cert_file);
  
        if (config->phase2)
                __connman_service_set_string(service, "Phase2", config->phase2);
 +#if defined TIZEN_EXT
 +      else
 +              __connman_service_set_string(service, "Phase2", NULL);
 +#endif
  
        if (config->passphrase)
                __connman_service_set_string(service, "Passphrase",
@@@ -1097,20 -1181,6 +1188,20 @@@ static gboolean remove_virtual_config(g
        return FALSE;
  }
  
 +#if defined TIZEN_EXT
 +static bool __check_address_type(int address_family, const char *address)
 +{
 +      unsigned char buf[sizeof(struct in6_addr)] = {0, };
 +      int err = 0;
 +
 +      err = inet_pton(address_family, address, buf);
 +      if(err > 0)
 +              return TRUE;
 +
 +      return FALSE;
 +}
 +#endif
 +
  static int try_provision_service(struct connman_config_service *config,
                                struct connman_service *service)
  {
        enum connman_service_type type;
        const void *ssid;
        unsigned int ssid_len;
 -      const char *str;
  
        network = __connman_service_get_network(service);
        if (!network) {
                if (memcmp(config->ssid, ssid, ssid_len))
                        return -ENOENT;
  
 -              str = connman_network_get_string(network, "WiFi.Security");
 -              if (config->security != __connman_service_string2security(str))
 -                      return -ENOENT;
 -
                break;
  
        case CONNMAN_SERVICE_TYPE_ETHERNET:
                __connman_service_nameserver_clear(service);
  
                for (i = 0; config->nameservers[i]; i++) {
 +#if defined TIZEN_EXT
 +                      if (__check_address_type(AF_INET, config->nameservers[i]))
 +                              __connman_service_nameserver_append(service,
 +                                              config->nameservers[i], false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV4);
 +                      else if (__check_address_type(AF_INET6, config->nameservers[i]))
 +                              __connman_service_nameserver_append(service,
 +                                              config->nameservers[i], false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV6);
 +#else
                        __connman_service_nameserver_append(service,
                                                config->nameservers[i], false);
 +#endif
                }
        }
  
                virtual->service = service;
                virtual->vfile = config->virtual_file;
  
-               g_timeout_add(0, remove_virtual_config, virtual);
+               g_idle_add(remove_virtual_config, virtual);
  
                return 0;
        }
        return 0;
  }
  
+ static int
+ find_and_provision_service_from_config(struct connman_service *service,
+                                       struct connman_config *config)
+ {
+       GHashTableIter iter;
+       gpointer value, key;
+       g_hash_table_iter_init(&iter, config->service_table);
+       while (g_hash_table_iter_next(&iter, &key,
+                                       &value)) {
+               if (!try_provision_service(value, service))
+                       return 0;
+       }
+       return -ENOENT;
+ }
  static int find_and_provision_service(struct connman_service *service)
  {
-       GHashTableIter iter, iter_service;
-       gpointer value, key, value_service, key_service;
+       GHashTableIter iter;
+       gpointer value, key;
  
        g_hash_table_iter_init(&iter, config_table);
  
        while (g_hash_table_iter_next(&iter, &key, &value)) {
                struct connman_config *config = value;
  
-               g_hash_table_iter_init(&iter_service, config->service_table);
-               while (g_hash_table_iter_next(&iter_service, &key_service,
-                                               &value_service)) {
-                       if (!try_provision_service(value_service, service))
-                               return 0;
-               }
+               if (!find_and_provision_service_from_config(service, config))
+                       return 0;
        }
  
        return -ENOENT;
@@@ -1388,13 -1465,6 +1492,13 @@@ int __connman_config_provision_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);
  }
  
@@@ -1459,7 -1529,7 +1563,7 @@@ int __connman_config_provision_service_
                        }
                }
  
-               find_and_provision_service(service);
+               find_and_provision_service_from_config(service, config);
        }
  
        return ret;
@@@ -1489,7 -1559,7 +1593,7 @@@ int connman_config_provision_mutable_se
  {
        struct connman_config_service *service_config;
        struct connman_config *config;
-       char *vfile, *group;
+       char *vfile, *group = NULL;
        char rstr[11];
  
        DBG("");
        if (g_strcmp0(service_config->type, "wifi") == 0)
                __connman_device_request_scan(CONNMAN_SERVICE_TYPE_WIFI);
  
+       g_free(group);
        return 0;
  
  error:
        DBG("Could not proceed");
        g_hash_table_remove(config_table, vfile);
        g_free(vfile);
+       g_free(group);
        return -EINVAL;
  }
  
@@@ -1545,13 -1616,16 +1650,16 @@@ struct connman_config_entry **connman_c
        g_hash_table_iter_init(&iter_file, config_table);
        while (g_hash_table_iter_next(&iter_file, &key, &value)) {
                struct connman_config *config_file = value;
+               struct connman_config_entry **tmp_entries = entries;
  
                count = g_hash_table_size(config_file->service_table);
  
                entries = g_try_realloc(entries, (i + count + 1) *
                                        sizeof(struct connman_config_entry *));
-               if (!entries)
+               if (!entries) {
+                       g_free(tmp_entries);
                        return NULL;
+               }
  
                g_hash_table_iter_init(&iter_config,
                                                config_file->service_table);
        }
  
        if (entries) {
+               struct connman_config_entry **tmp_entries = entries;
                entries = g_try_realloc(entries, (i + 1) *
                                        sizeof(struct connman_config_entry *));
-               if (!entries)
+               if (!entries) {
+                       g_free(tmp_entries);
                        return NULL;
+               }
  
                entries[i] = NULL;
  
diff --combined src/connection.c
index 4389d58,6b005e7..64d48b7
mode 100755,100644..100755
@@@ -46,7 -46,6 +46,6 @@@ struct gateway_config 
  struct gateway_data {
        int index;
        struct connman_service *service;
-       unsigned int order;
        struct gateway_config *ipv4_gateway;
        struct gateway_config *ipv6_gateway;
        bool default_checked;
@@@ -381,8 -380,6 +380,6 @@@ static struct gateway_data *add_gateway
  
        data->service = service;
  
-       data->order = __connman_service_get_order(service);
        /*
         * If the service is already in the hash, then we
         * must not replace it blindly but disable the gateway
@@@ -558,25 -555,13 +555,13 @@@ static void unset_default_gateway(struc
  
  static struct gateway_data *find_default_gateway(void)
  {
-       struct gateway_data *found = NULL;
-       unsigned int order = 0;
-       GHashTableIter iter;
-       gpointer value, key;
-       g_hash_table_iter_init(&iter, gateway_hash);
-       while (g_hash_table_iter_next(&iter, &key, &value)) {
-               struct gateway_data *data = value;
-               if (!found || data->order > order) {
-                       found = data;
-                       order = data->order;
+       struct connman_service *service;
  
-                       DBG("default %p order %d", found, order);
-               }
-       }
+       service = __connman_service_get_default();
+       if (!service)
+               return NULL;
  
-       return found;
+       return g_hash_table_lookup(gateway_hash, service);
  }
  
  static bool choose_default_gateway(struct gateway_data *data,
         * this one as default. If the other one is already active
         * we mark this one as non default.
         */
-       if (data->ipv4_gateway) {
-               if (candidate->ipv4_gateway &&
-                               !candidate->ipv4_gateway->active) {
+       if (data->ipv4_gateway && candidate->ipv4_gateway) {
+               if (!candidate->ipv4_gateway->active) {
                        DBG("ipv4 downgrading %p", candidate);
                        unset_default_gateway(candidate,
                                                CONNMAN_IPCONFIG_TYPE_IPV4);
                }
-               if (candidate->ipv4_gateway &&
-                               candidate->ipv4_gateway->active &&
-                               candidate->order > data->order) {
+               if (candidate->ipv4_gateway->active &&
+                               __connman_service_compare(candidate->service,
+                                                       data->service) < 0) {
                        DBG("ipv4 downgrading this %p", data);
-                       unset_default_gateway(data,
-                                               CONNMAN_IPCONFIG_TYPE_IPV4);
+                       unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
                        downgraded = true;
                }
        }
  
-       if (data->ipv6_gateway) {
-               if (candidate->ipv6_gateway &&
-                               !candidate->ipv6_gateway->active) {
+       if (data->ipv6_gateway && candidate->ipv6_gateway) {
+               if (!candidate->ipv6_gateway->active) {
                        DBG("ipv6 downgrading %p", candidate);
                        unset_default_gateway(candidate,
                                                CONNMAN_IPCONFIG_TYPE_IPV6);
                }
  
-               if (candidate->ipv6_gateway &&
-                               candidate->ipv6_gateway->active &&
-                               candidate->order > data->order) {
+               if (candidate->ipv6_gateway->active &&
+                       __connman_service_compare(candidate->service,
+                                               data->service) < 0) {
                        DBG("ipv6 downgrading this %p", data);
-                       unset_default_gateway(data,
-                                               CONNMAN_IPCONFIG_TYPE_IPV6);
+                       unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
                        downgraded = true;
                }
        }
@@@ -674,15 -657,8 +657,15 @@@ static void connection_newgateway(int i
        }
  
        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);
@@@ -762,40 -738,6 +745,6 @@@ static struct gateway_data *find_active
        return NULL;
  }
  
- static void update_order(void)
- {
-       GHashTableIter iter;
-       gpointer value, key;
-       DBG("");
-       g_hash_table_iter_init(&iter, gateway_hash);
-       while (g_hash_table_iter_next(&iter, &key, &value)) {
-               struct gateway_data *data = value;
-               data->order = __connman_service_get_order(data->service);
-       }
- }
- void __connman_connection_gateway_activate(struct connman_service *service,
-                                       enum connman_ipconfig_type type)
- {
-       struct gateway_data *data = NULL;
-       data = g_hash_table_lookup(gateway_hash, service);
-       if (!data)
-               return;
-       DBG("gateway %p/%p type %d", data->ipv4_gateway,
-                                       data->ipv6_gateway, type);
-       if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
-               data->ipv4_gateway->active = true;
-       else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
-               data->ipv6_gateway->active = true;
- }
  static void add_host_route(int family, int index, const char *gateway,
                        enum connman_service_type service_type)
  {
        }
  }
  
 +#if defined TIZEN_EXT
 +static bool __connman_service_is_not_cellular_internet_profile(
 +              struct connman_service *cellular)
 +{
 +      char *suffix;
 +      const char *path;
 +      const char internet_suffix[] = "_1";
 +      const char prepaid_internet_suffix[] = "_3";
 +
 +      if (connman_service_get_type(cellular) != CONNMAN_SERVICE_TYPE_CELLULAR)
 +              return FALSE;
 +
 +      path = __connman_service_get_path(cellular);
 +
 +      suffix = strrchr(path, '_');
 +
 +      if (g_strcmp0(suffix, internet_suffix) != 0 &&
 +                      g_strcmp0(suffix, prepaid_internet_suffix) != 0) {
 +              DBG("not internet service profile: %s", path);
 +              return TRUE;
 +      }
 +
 +      return FALSE;
 +}
 +#endif
 +
  int __connman_connection_gateway_add(struct connman_service *service,
                                        const char *gateway,
                                        enum connman_ipconfig_type type,
        if (!gateway && type == CONNMAN_IPCONFIG_TYPE_IPV6)
                gateway = "::";
  
 +#if defined TIZEN_EXT
 +      if (__connman_service_is_not_cellular_internet_profile(service) == TRUE) {
 +              /* not internet service should not be default gateway */
 +
 +              DBG("no internet service %p index %d gateway %s vpn ip %s type %d",
 +                      service, index, gateway, peer, type);
 +
 +              if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
 +                      add_host_route(AF_INET, index, gateway, service_type);
 +                      __connman_service_nameserver_add_routes(service, gateway);
 +                      type4 = CONNMAN_IPCONFIG_TYPE_IPV4;
 +              }
 +
 +              if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
 +                      add_host_route(AF_INET6, index, gateway, service_type);
 +                      __connman_service_nameserver_add_routes(service, gateway);
 +                      type6 = CONNMAN_IPCONFIG_TYPE_IPV6;
 +              }
 +
 +              goto done;
 +      }
 +#endif
        DBG("service %p index %d gateway %s vpn ip %s type %d",
                service, index, gateway, peer, type);
  
        }
  
        if (!active_gateway) {
 +#if defined TIZEN_EXT
 +              if(new_gateway->ipv4_gateway)
 +                      DBG("ConnMan, Set default gateway[%s], active[%d]",
 +                              new_gateway->ipv4_gateway->gateway,
 +                              new_gateway->ipv4_gateway->active);
 +#endif
                set_default_gateway(new_gateway, type);
                goto done;
        }
@@@ -1083,19 -971,12 +1032,15 @@@ bool __connman_connection_update_gatewa
        bool updated = false;
        GHashTableIter iter;
        gpointer value, key;
 +#if defined TIZEN_EXT
 +      static struct gateway_data *old_default = NULL;
 +#endif
  
        if (!gateway_hash)
                return updated;
  
-       update_order();
        default_gateway = find_default_gateway();
  
-       __connman_service_update_ordering();
        DBG("default %p", default_gateway);
  
        /*
                }
        }
  
 +#if defined TIZEN_EXT
 +      if (updated == false && old_default != default_gateway) {
 +              updated = true;
 +              old_default = default_gateway;
 +      }
 +#endif
        if (updated && default_gateway) {
                if (default_gateway->ipv4_gateway)
                        set_default_gateway(default_gateway,
diff --combined src/connman.h
index 57cfc87,21b7080..4125463
mode 100755,100644..100755
@@@ -125,6 -125,7 +125,6 @@@ int __connman_agent_request_peer_author
                                                bool wps_requested,
                                                const char *dbus_sender,
                                                void *user_data);
 -
  #include <connman/log.h>
  
  int __connman_log_init(const char *program, const char *debug,
@@@ -134,6 -135,8 +134,6 @@@ void __connman_log_cleanup(gboolean bac
  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>
@@@ -169,9 -172,6 +169,9 @@@ int __connman_inet_ipv6_send_rs(int ind
                        __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,
@@@ -244,10 -244,14 +244,14 @@@ int __connman_inet_del_default_from_tab
  int __connman_inet_get_address_netmask(int ifindex,
                struct sockaddr_in *address, struct sockaddr_in *netmask);
  
+ bool __connman_inet_isrootnfs_device(const char *devname);
+ char **__connman_inet_get_pnp_nameservers(const char *pnp_file);
  #include <connman/resolver.h>
  
  int __connman_resolver_init(gboolean dnsproxy);
  void __connman_resolver_cleanup(void);
+ void __connman_resolver_append_fallback_nameservers(void);
  int __connman_resolvfile_append(int index, const char *domain, const char *server);
  int __connman_resolvfile_remove(int index, const char *domain, const char *server);
  int __connman_resolver_redo_servers(int index);
@@@ -367,11 -371,6 +371,11 @@@ const char *__connman_ipconfig_get_broa
  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);
  
@@@ -402,15 -401,7 +406,15 @@@ enum connman_ipconfig_method __connman_
  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,
@@@ -460,11 -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);
  
@@@ -511,8 -497,6 +515,6 @@@ void __connman_connection_gateway_remov
  int __connman_connection_get_vpn_index(int phy_index);
  
  bool __connman_connection_update_gateway(void);
- void __connman_connection_gateway_activate(struct connman_service *service,
-                                       enum connman_ipconfig_type type);
  
  int __connman_ntp_start(char *server);
  void __connman_ntp_stop();
@@@ -576,10 -560,6 +578,10 @@@ int __connman_device_request_hidden_sca
                                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);
  
@@@ -599,11 -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);
@@@ -648,7 -623,7 +650,7 @@@ int __connman_tethering_init(void)
  void __connman_tethering_cleanup(void);
  
  const char *__connman_tethering_get_bridge(void);
void __connman_tethering_set_enabled(void);
int __connman_tethering_set_enabled(void);
  void __connman_tethering_set_disabled(void);
  
  int __connman_private_network_request(DBusMessage *msg, const char *owner);
@@@ -671,7 -646,8 +673,8 @@@ int __connman_provider_indicate_state(s
                                        enum connman_provider_state state);
  int __connman_provider_indicate_error(struct connman_provider *provider,
                                        enum connman_provider_error error);
- int __connman_provider_connect(struct connman_provider *provider);
+ int __connman_provider_connect(struct connman_provider *provider,
+                                       const char *dbus_sender);
  int __connman_provider_remove_by_path(const char *path);
  void __connman_provider_cleanup(void);
  int __connman_provider_init(void);
@@@ -684,15 -660,9 +687,18 @@@ int __connman_service_load_modifiable(s
  
  void __connman_service_list_struct(DBusMessageIter *iter);
  
 +#if defined TIZEN_EXT
 +int connman_service_get_ipv6_dns_method(struct connman_service *service);
 +enum connman_dnsconfig_method {
 +      CONNMAN_DNSCONFIG_METHOD_UNKNOWN = 0,
 +      CONNMAN_DNSCONFIG_METHOD_MANUAL  = 1,
 +      CONNMAN_DNSCONFIG_METHOD_DHCP    = 2,
 +};
 +#endif
 +
+ int __connman_service_compare(const struct connman_service *a,
+                                       const struct connman_service *b);
  struct connman_service *__connman_service_lookup_from_index(int index);
  struct connman_service *__connman_service_lookup_from_ident(const char *identifier);
  struct connman_service *__connman_service_create_from_network(struct connman_network *network);
@@@ -710,6 -680,8 +716,8 @@@ struct connman_ipconfig *__connman_serv
                                struct connman_service *service);
  struct connman_ipconfig *__connman_service_get_ipconfig(
                                struct connman_service *service, int family);
+ void __connman_service_notify_ipv4_configuration(
+                               struct connman_service *service);
  bool __connman_service_is_connected_state(struct connman_service *service,
                                        enum connman_ipconfig_type type);
  const char *__connman_service_get_ident(struct connman_service *service);
@@@ -717,15 -689,10 +725,14 @@@ const char *__connman_service_get_path(
  const char *__connman_service_get_name(struct connman_service *service);
  unsigned int __connman_service_get_order(struct connman_service *service);
  enum connman_service_state __connman_service_get_state(struct connman_service *service);
- void __connman_service_update_ordering(void);
  struct connman_network *__connman_service_get_network(struct connman_service *service);
  enum connman_service_security __connman_service_get_security(struct connman_service *service);
  const char *__connman_service_get_phase2(struct connman_service *service);
  bool __connman_service_wps_enabled(struct connman_service *service);
 +#if defined TIZEN_EXT
 +void __connman_service_set_storage_reload(struct connman_service *service,
 +                                              bool storage_reload);
 +#endif
  int __connman_service_set_favorite(struct connman_service *service,
                                                bool favorite);
  int __connman_service_set_favorite_delayed(struct connman_service *service,
@@@ -749,10 -716,6 +756,10 @@@ enum connman_service_state __connman_se
                                        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);
@@@ -764,12 -727,6 +771,12 @@@ int __connman_service_disconnect(struc
  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,
@@@ -787,19 -744,10 +794,19 @@@ const char *__connman_service_type2stri
  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);
@@@ -815,17 -763,6 +822,17 @@@ void __connman_service_timeserver_chang
                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);
@@@ -842,11 -779,23 +849,23 @@@ void __connman_service_set_proxy_autoco
  
  void __connman_service_set_identity(struct connman_service *service,
                                        const char *identity);
+ void __connman_service_set_anonymous_identity(struct connman_service *service,
+                                       const char *anonymous_identity);
+ void __connman_service_set_subject_match(struct connman_service *service,
+                                       const char *subject_match);
+ void __connman_service_set_altsubject_match(struct connman_service *service,
+                                       const char *altsubject_match);
+ void __connman_service_set_domain_suffix_match(struct connman_service *service,
+                                       const char *domain_suffix_match);
+ void __connman_service_set_domain_match(struct connman_service *service,
+                                       const char *domain_match);
  void __connman_service_set_agent_identity(struct connman_service *service,
                                                const char *agent_identity);
  int __connman_service_set_passphrase(struct connman_service *service,
                                        const char *passphrase);
  const char *__connman_service_get_passphrase(struct connman_service *service);
+ int __connman_service_check_passphrase(enum connman_service_security security,
+                                       const char *passphrase);
  int __connman_service_reset_ipconfig(struct connman_service *service,
                enum connman_ipconfig_type type, DBusMessageIter *array,
                enum connman_service_state *new_state);
@@@ -857,9 -806,6 +876,9 @@@ void __connman_service_notify(struct co
                        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);
  
@@@ -929,16 -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);
@@@ -1063,13 -1005,19 +1087,19 @@@ struct firewall_context
  
  struct firewall_context *__connman_firewall_create(void);
  void __connman_firewall_destroy(struct firewall_context *ctx);
- int __connman_firewall_add_rule(struct firewall_context *ctx,
-                               const char *table,
-                               const char *chain,
-                               const char *rule_fmt, ...);
- int __connman_firewall_enable(struct firewall_context *ctx);
- int __connman_firewall_disable(struct firewall_context *ctx);
- bool __connman_firewall_is_up(void);
+ int __connman_firewall_enable_nat(struct firewall_context *ctx,
+                                       char *address, unsigned char prefixlen,
+                                       char *interface);
+ int __connman_firewall_disable_nat(struct firewall_context *ctx);
+ int __connman_firewall_enable_snat(struct firewall_context *ctx,
+                               int index, const char *ifname,
+                               const char *addr);
+ int __connman_firewall_disable_snat(struct firewall_context *ctx);
+ int __connman_firewall_enable_marking(struct firewall_context *ctx,
+                                       enum connman_session_id_type id_type,
+                                       char *id, const char *src_ip,
+                                       uint32_t mark);
+ int __connman_firewall_disable_marking(struct firewall_context *ctx);
  
  int __connman_firewall_init(void);
  void __connman_firewall_cleanup(void);
@@@ -1114,12 -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 --combined src/device.c
index b5855cc,a563f46..3ec8f71
mode 100755,100644..100755
@@@ -53,7 -53,6 +53,6 @@@ struct connman_device 
                                                         */
        bool powered;
        bool scanning;
-       bool disconnected;
        char *name;
        char *node;
        char *address;
@@@ -385,6 -384,9 +384,9 @@@ static void device_destruct(struct conn
  
        clear_pending_trigger(device);
  
+       g_hash_table_destroy(device->networks);
+       device->networks = NULL;
        g_free(device->ident);
        g_free(device->node);
        g_free(device->name);
  
        g_free(device->last_network);
  
-       g_hash_table_destroy(device->networks);
-       device->networks = NULL;
        g_free(device);
  }
  
@@@ -568,7 -567,7 +567,7 @@@ int connman_device_set_powered(struct c
  {
        enum connman_service_type type;
  
-       DBG("driver %p powered %d", device, powered);
+       DBG("device %p powered %d", device, powered);
  
        if (device->powered == powered)
                return -EALREADY;
  
        __connman_technology_enabled(type);
  
-       connman_device_set_disconnected(device, false);
        device->scanning = false;
  
        if (device->driver && device->driver->scan)
@@@ -623,8 -621,6 +621,6 @@@ int __connman_device_disconnect(struct 
  
        DBG("device %p", device);
  
-       connman_device_set_disconnected(device, true);
        g_hash_table_iter_init(&iter, device->networks);
  
        while (g_hash_table_iter_next(&iter, &key, &value)) {
@@@ -751,37 -747,6 +747,6 @@@ int connman_device_set_scanning(struct 
  }
  
  /**
-  * connman_device_set_disconnected:
-  * @device: device structure
-  * @disconnected: disconnected state
-  *
-  * Change disconnected state of device (only for device with networks)
-  */
- int connman_device_set_disconnected(struct connman_device *device,
-                                               bool disconnected)
- {
-       DBG("device %p disconnected %d", device, disconnected);
-       if (device->disconnected == disconnected)
-               return -EALREADY;
-       device->disconnected = disconnected;
-       return 0;
- }
- /**
-  * connman_device_get_disconnected:
-  * @device: device structure
-  *
-  * Get device disconnected state
-  */
- bool connman_device_get_disconnected(struct connman_device *device)
- {
-       return device->disconnected;
- }
- /**
   * connman_device_set_string:
   * @device: device structure
   * @key: unique identifier
@@@ -1077,73 -1042,6 +1042,73 @@@ void connman_device_regdom_notify(struc
        __connman_technology_notify_regdom_by_device(device, result, alpha2);
  }
  
 +#if defined TIZEN_EXT
 +static int device_specific_scan(enum connman_service_type type,
 +                              struct connman_device *device,
 +                              int scan_type, GSList *specific_scan_list)
 +{
 +      if (!device->driver || !device->driver->specific_scan)
 +              return -EOPNOTSUPP;
 +
 +      if (!device->powered)
 +              return -ENOLINK;
 +
 +      return device->driver->specific_scan(type, device, scan_type,
 +                      specific_scan_list, NULL);
 +}
 +
 +int __connman_device_request_specific_scan(enum connman_service_type type,
 +                              int scan_type, GSList *specific_scan_list)
 +{
 +      bool success = false;
 +      int last_err = -ENOSYS;
 +      GSList *list;
 +      int err;
 +
 +      switch (type) {
 +      case CONNMAN_SERVICE_TYPE_UNKNOWN:
 +      case CONNMAN_SERVICE_TYPE_SYSTEM:
 +      case CONNMAN_SERVICE_TYPE_ETHERNET:
 +      case CONNMAN_SERVICE_TYPE_BLUETOOTH:
 +      case CONNMAN_SERVICE_TYPE_CELLULAR:
 +      case CONNMAN_SERVICE_TYPE_GPS:
 +      case CONNMAN_SERVICE_TYPE_VPN:
 +      case CONNMAN_SERVICE_TYPE_GADGET:
 +              return -EOPNOTSUPP;
 +      case CONNMAN_SERVICE_TYPE_WIFI:
 +      case CONNMAN_SERVICE_TYPE_P2P:
 +              break;
 +      }
 +
 +      for (list = device_list; list; list = list->next) {
 +              struct connman_device *device = list->data;
 +              enum connman_service_type service_type =
 +                      __connman_device_get_service_type(device);
 +
 +              if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
 +                      if (type == CONNMAN_SERVICE_TYPE_P2P) {
 +                              if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
 +                                      continue;
 +                      } else if (service_type != type)
 +                              continue;
 +              }
 +
 +              err = device_specific_scan(type, device, scan_type, specific_scan_list);
 +              if (err == 0 || err == -EINPROGRESS) {
 +                      success = true;
 +              } else {
 +                      last_err = err;
 +                      DBG("device %p err %d", device, err);
 +              }
 +      }
 +
 +      if (success)
 +              return 0;
 +
 +      return last_err;
 +}
 +#endif
 +
  int __connman_device_request_scan(enum connman_service_type type)
  {
        bool success = false;
                }
  
                err = device_scan(type, device);
 +#if defined TIZEN_EXT
 +              /* When Scan is already in progress then return Error so that
 +               * wifi-manager can block the scan-done signal to be sent to
 +               * application and start requested scan after scan already in progress
 +               * is completed then notify to application about the scan event */
 +              if (err == 0 || err == -EINPROGRESS) {
 +#else
                if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
 +#endif
                        success = true;
                } else {
                        last_err = err;
@@@ -1218,11 -1108,7 +1183,11 @@@ int __connman_device_request_hidden_sca
                                        passphrase, security, user_data);
  }
  
 +#if defined TIZEN_EXT
 +char *index2ident(int index, const char *prefix)
 +#else
  static char *index2ident(int index, const char *prefix)
 +#endif
  {
        struct ifreq ifr;
        struct ether_addr eth;
        return str;
  }
  
 +#if defined TIZEN_EXT
 +char *index2addr(int index)
 +#else
  static char *index2addr(int index)
 +#endif
  {
        struct ifreq ifr;
        struct ether_addr eth;
@@@ -1435,6 -1317,11 +1400,11 @@@ nodevice
        }
  
  list:
+       if (__connman_inet_isrootnfs_device(devname)) {
+               DBG("ignoring device %s (rootnfs)", devname);
+               return true;
+       }
        blacklisted_interfaces =
                connman_setting_get_string_list("NetworkInterfaceBlacklist");
        if (!blacklisted_interfaces)
@@@ -1507,9 -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 --combined src/dhcp.c
index b627362,1af1eb5..c428c1d
mode 100755,100644..100755
  #include <errno.h>
  #include <string.h>
  #include <stdlib.h>
+ #include <net/ethernet.h>
+ #ifndef IPV6_MIN_MTU
+ #define IPV6_MIN_MTU 1280
+ #endif
  
  #include <connman/ipconfig.h>
  #include <include/setting.h>
@@@ -54,16 -59,14 +59,17 @@@ struct connman_dhcp 
        GDHCPClient *dhcp_client;
        char *ipv4ll_debug_prefix;
        char *dhcp_debug_prefix;
+       bool ipv4ll_running;
  };
  
  static GHashTable *ipconfig_table;
- static bool ipv4ll_running;
  
  static void dhcp_free(struct connman_dhcp *dhcp)
  {
 +#if defined TIZEN_EXT
 +      DBG("dhcp_free [%p]", dhcp);
 +#endif
        g_strfreev(dhcp->nameservers);
        g_strfreev(dhcp->timeservers);
        g_free(dhcp->pac);
        dhcp->pac = NULL;
  
        g_free(dhcp);
 +#if defined TIZEN_EXT
 +      dhcp = NULL;
 +#endif
  }
  
  static void ipv4ll_stop_client(struct connman_dhcp *dhcp)
  {
 +#if defined TIZEN_EXT
 +      DBG("dhcp [%p] ipv4ll_client [%p]", dhcp, dhcp->ipv4ll_client);
 +#endif
        if (!dhcp->ipv4ll_client)
                return;
  
        g_dhcp_client_stop(dhcp->ipv4ll_client);
        g_dhcp_client_unref(dhcp->ipv4ll_client);
        dhcp->ipv4ll_client = NULL;
-       ipv4ll_running = false;
+       dhcp->ipv4ll_running = false;
  
        g_free(dhcp->ipv4ll_debug_prefix);
        dhcp->ipv4ll_debug_prefix = NULL;
@@@ -117,18 -114,16 +123,22 @@@ static bool apply_dhcp_invalidate_on_ne
                        __connman_service_timeserver_remove(service,
                                                        dhcp->timeservers[i]);
                }
+               g_strfreev(dhcp->timeservers);
+               dhcp->timeservers = NULL;
        }
        if (dhcp->nameservers) {
                for (i = 0; dhcp->nameservers[i]; i++) {
 +#if defined TIZEN_EXT
                        __connman_service_nameserver_remove(service,
-                                               dhcp->nameservers[i], false,
-                                               CONNMAN_IPCONFIG_TYPE_IPV4);
 -                                              dhcp->nameservers[i], false);
++                                      dhcp->nameservers[i], false,
++                                      CONNMAN_IPCONFIG_TYPE_IPV4);
 +#else
 +                      __connman_service_nameserver_remove(service,
-                                               dhcp->nameservers[i], false);
++                                      dhcp->nameservers[i], false);
 +#endif
                }
+               g_strfreev(dhcp->nameservers);
+               dhcp->nameservers = NULL;
        }
  
        return true;
@@@ -198,10 -193,6 +208,10 @@@ static int ipv4ll_start_client(struct c
        int index;
        int err;
  
 +#if defined TIZEN_EXT
 +      DBG("dhcp %p", dhcp);
 +#endif
 +
        if (dhcp->ipv4ll_client)
                return -EALREADY;
  
        if (error != G_DHCP_CLIENT_ERROR_NONE)
                return -EINVAL;
  
 +#if !defined TIZEN_EXT
        if (getenv("CONNMAN_DHCP_DEBUG")) {
 +#endif
                dhcp->ipv4ll_debug_prefix = g_strdup_printf("IPv4LL index %d",
                                                        index);
                g_dhcp_client_set_debug(ipv4ll_client, dhcp_debug,
                                        dhcp->ipv4ll_debug_prefix);
 +#if !defined TIZEN_EXT
        }
 +#endif
  
        g_dhcp_client_set_id(ipv4ll_client);
  
                return err;
        }
  
-       ipv4ll_running = true;
+       dhcp->ipv4ll_running = true;
        return 0;
  }
  
@@@ -255,10 -242,7 +265,10 @@@ static gboolean dhcp_retry_cb(gpointer 
        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));
  
@@@ -270,16 -254,16 +280,16 @@@ static void no_lease_cb(GDHCPClient *dh
        struct connman_dhcp *dhcp = user_data;
        int err;
  
-       DBG("No lease available ipv4ll %d client %p", ipv4ll_running,
+       DBG("No lease available ipv4ll %d client %p", dhcp->ipv4ll_running,
                dhcp->ipv4ll_client);
  
        if (dhcp->timeout > 0)
                g_source_remove(dhcp->timeout);
  
        dhcp->timeout = g_timeout_add_seconds(RATE_LIMIT_INTERVAL,
-                       dhcp_retry_cb,
-                       dhcp);
-       if (ipv4ll_running)
+                                               dhcp_retry_cb,
+                                               dhcp);
+       if (dhcp->ipv4ll_running)
                return;
  
        err = ipv4ll_start_client(dhcp);
                DBG("Cannot start ipv4ll client (%d/%s)", err, strerror(-err));
  
        /* Only notify upper layer if we have a problem */
-       dhcp_invalidate(dhcp, !ipv4ll_running);
+       dhcp_invalidate(dhcp, !dhcp->ipv4ll_running);
  }
  
  static void lease_lost_cb(GDHCPClient *dhcp_client, gpointer user_data)
@@@ -352,6 -336,20 +362,20 @@@ static bool apply_lease_available_on_ne
                return false;
        }
  
+       option = g_dhcp_client_get_option(dhcp_client, G_DHCP_MTU);
+       if (option && option->data) {
+               int mtu, index, err;
+               mtu = atoi(option->data);
+               if (mtu >= IPV6_MIN_MTU && mtu <= ETH_DATA_LEN) {
+                       index = __connman_ipconfig_get_index(dhcp->ipconfig);
+                       err = connman_inet_set_mtu(index, mtu);
+                       DBG("MTU %d index %d err %d", mtu, index, err);
+               }
+       }
        option = g_dhcp_client_get_option(dhcp_client, 252);
        if (option)
                pac = g_strdup(option->data);
  
        if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
                if (dhcp->nameservers) {
 +#if defined TIZEN_EXT
 +                      for (i = 0; dhcp->nameservers[i] != NULL; i++) {
 +                              __connman_service_nameserver_remove(service,
 +                                              dhcp->nameservers[i], false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV4);
 +                      }
 +#else
                        for (i = 0; dhcp->nameservers[i]; i++) {
                                __connman_service_nameserver_remove(service,
                                                dhcp->nameservers[i], false);
                        }
 +#endif
                        g_strfreev(dhcp->nameservers);
                }
  
                dhcp->nameservers = nameservers;
  
                for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) {
 +#if defined TIZEN_EXT
 +                      __connman_service_nameserver_append(service,
 +                                              dhcp->nameservers[i], false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV4);
 +#else
                        __connman_service_nameserver_append(service,
                                                dhcp->nameservers[i], false);
 +#endif
                }
        } else {
                g_strfreev(nameservers);
@@@ -452,6 -436,7 +476,7 @@@ static void lease_available_cb(GDHCPCli
  {
        struct connman_dhcp *dhcp = user_data;
        GList *option = NULL;
+       enum connman_ipconfig_method old_method;
        char *address, *netmask = NULL, *gateway = NULL;
        const char *c_address, *c_gateway;
        unsigned char prefixlen, c_prefixlen;
        __connman_ipconfig_set_dhcp_address(dhcp->ipconfig, address);
        DBG("last address %s", address);
  
 +#if defined TIZEN_EXT
 +      int dhcp_lease_duration = g_dhcp_client_get_dhcp_lease_duration(dhcp_client);
 +#endif
 +
        option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET);
        if (option)
                netmask = g_strdup(option->data);
        } else if (prefixlen != c_prefixlen)
                ip_change = true;
  
+       old_method = __connman_ipconfig_get_method(dhcp->ipconfig);
        __connman_ipconfig_set_method(dhcp->ipconfig,
                                                CONNMAN_IPCONFIG_METHOD_DHCP);
  
 +#if defined TIZEN_EXT
 +      __connman_ipconfig_set_dhcp_lease_duration(dhcp->ipconfig, dhcp_lease_duration);
 +#endif
 +
+       /*
+        * Notify IPv4.Configuration's method moved back to DHCP.
+        *
+        * This is the case ConnMan initially set an address by using
+        * IPv4LL because DHCP failed but now we got an address from DHCP.
+        */
+       if (old_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+               struct connman_service *service =
+                       connman_service_lookup_from_network(dhcp->network);
+               if (service)
+                       __connman_service_notify_ipv4_configuration(service);
+       }
        if (ip_change) {
                __connman_ipconfig_set_local(dhcp->ipconfig, address);
                __connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
@@@ -535,8 -527,9 +575,9 @@@ done
  static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data)
  {
        struct connman_dhcp *dhcp = user_data;
-               char *address, *netmask;
-               unsigned char prefixlen;
+       enum connman_ipconfig_method old_method;
+       char *address, *netmask;
+       unsigned char prefixlen;
  
        DBG("IPV4LL available");
  
  
        prefixlen = connman_ipaddress_calc_netmask_len(netmask);
  
+       old_method = __connman_ipconfig_get_method(dhcp->ipconfig);
        __connman_ipconfig_set_method(dhcp->ipconfig,
-                                               CONNMAN_IPCONFIG_METHOD_DHCP);
+                                               CONNMAN_IPCONFIG_METHOD_AUTO);
+       /*
+        * Notify IPv4.Configuration's method is AUTO now.
+        *
+        * This is the case DHCP failed thus ConnMan used IPv4LL to get an
+        * address. Set IPv4.Configuration method to AUTO allows user to
+        * ask for a DHCP address by setting the method again to DHCP.
+        */
+       if (old_method == CONNMAN_IPCONFIG_METHOD_DHCP) {
+               struct connman_service *service =
+                       connman_service_lookup_from_network(dhcp->network);
+               if (service)
+                       __connman_service_notify_ipv4_configuration(service);
+       }
        __connman_ipconfig_set_local(dhcp->ipconfig, address);
        __connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
        __connman_ipconfig_set_gateway(dhcp->ipconfig, NULL);
@@@ -562,6 -572,7 +620,7 @@@ static int dhcp_initialize(struct connm
        GDHCPClient *dhcp_client;
        GDHCPClientError error;
        int index;
+       const char *vendor_class_id;
  
        DBG("dhcp %p", dhcp);
  
  
        dhcp_client = g_dhcp_client_new(G_DHCP_IPV4, index, &error);
        if (error != G_DHCP_CLIENT_ERROR_NONE)
 +#if defined TIZEN_EXT
 +      {
 +              DBG("failed g_dhcp_client_new(%d), index(%d)", error, index);
 +#endif
                return -EINVAL;
 +#if defined TIZEN_EXT
 +      }
 +#endif
  
 +#if !defined TIZEN_EXT
        if (getenv("CONNMAN_DHCP_DEBUG")) {
 +#endif
                dhcp->dhcp_debug_prefix = g_strdup_printf("DHCP index %d",
                                                        index);
                g_dhcp_client_set_debug(dhcp_client, dhcp_debug,
                                        dhcp->dhcp_debug_prefix);
 +#if !defined TIZEN_EXT
        }
 +#endif
  
        g_dhcp_client_set_id(dhcp_client);
  
                g_dhcp_client_set_request(dhcp_client, G_DHCP_DOMAIN_NAME);
                g_dhcp_client_set_request(dhcp_client, G_DHCP_NTP_SERVER);
                g_dhcp_client_set_request(dhcp_client, 252);
+               g_dhcp_client_set_request(dhcp_client, G_DHCP_MTU);
        }
  
-       g_dhcp_client_set_request(dhcp_client, G_DHCP_SUBNET);
        g_dhcp_client_set_request(dhcp_client, G_DHCP_ROUTER);
+       g_dhcp_client_set_request(dhcp_client, G_DHCP_SUBNET);
+       vendor_class_id = connman_option_get_string("VendorClassID");
+       if (vendor_class_id)
+               g_dhcp_client_set_send(dhcp_client, G_DHCP_VENDOR_CLASS_ID,
+                                       vendor_class_id);
  
        g_dhcp_client_register_event(dhcp_client,
                        G_DHCP_CLIENT_EVENT_LEASE_AVAILABLE,
@@@ -669,9 -675,7 +734,9 @@@ int __connman_dhcp_start(struct connman
                        struct connman_network *network, dhcp_cb callback,
                        gpointer user_data)
  {
 +#if !defined TIZEN_EXT
        const char *last_addr = NULL;
 +#endif
        struct connman_dhcp *dhcp;
        int err;
  
                        return -EINVAL;
        }
  
 +#if !defined TIZEN_EXT
        last_addr = __connman_ipconfig_get_dhcp_address(ipconfig);
 +#endif
  
        dhcp = g_hash_table_lookup(ipconfig_table, ipconfig);
        if (!dhcp) {
        dhcp->callback = callback;
        dhcp->user_data = user_data;
  
 +#if defined TIZEN_EXT
 +      DBG("Start DHCP with DHCPDISCOVER request");
 +
 +      return g_dhcp_client_start(dhcp->dhcp_client, NULL);
 +#else
        return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
 +#endif
  }
  
  void __connman_dhcp_stop(struct connman_ipconfig *ipconfig)
diff --combined src/dhcpv6.c
index adf8827,cbf7974..c624cb0
mode 100755,100644..100755
@@@ -105,20 -105,14 +105,14 @@@ static void clear_timer(struct connman_
        }
  }
  
- static inline guint get_random(void)
+ static guint compute_random(guint val)
  {
-       uint64_t val;
-       __connman_util_get_random(&val);
+       uint64_t rand;
  
-       /* Make sure the value is always positive so strip MSB */
-       return ((uint32_t)val) >> 1;
- }
+       __connman_util_get_random(&rand);
  
- static guint compute_random(guint val)
- {
        return val - val / 10 +
-               (get_random() % (2 * 1000)) * val / 10 / 1000;
+               ((guint) rand % (2 * 1000)) * val / 10 / 1000;
  }
  
  /* Calculate a random delay, RFC 3315 chapter 14 */
@@@ -203,23 -197,10 +197,23 @@@ static int set_duid(struct connman_serv
        int duid_len;
  
        ident = __connman_service_get_ident(service);
 +#if defined TIZEN_EXT
 +      if(ident != NULL)
 +              DBG("ident : %s", ident);
 +#endif
  
        keyfile = connman_storage_load_service(ident);
 +
 +#if defined TIZEN_EXT
 +      if (!keyfile) {
 +              keyfile = g_key_file_new();
 +              if (!keyfile)
 +                      return -EIO;
 +      }
 +#else
        if (!keyfile)
                return -EINVAL;
 +#endif
  
        hex_duid = g_key_file_get_string(keyfile, ident, "IPv6.DHCP.DUID",
                                        NULL);
  
                hex_duid = convert_to_hex(duid, duid_len);
                if (!hex_duid) {
+                       g_free(duid);
                        g_key_file_free(keyfile);
                        return -ENOMEM;
                }
@@@ -340,19 -322,9 +335,19 @@@ static void info_req_cb(GDHCPClient *dh
        if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
                if (dhcp->nameservers) {
                        for (i = 0; dhcp->nameservers[i]; i++)
 +#if defined TIZEN_EXT
 +                      {
                                __connman_service_nameserver_remove(service,
 -                                                      dhcp->nameservers[i],
 -                                                      false);
 +                                              dhcp->nameservers[i], false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV6);
 +#else
 +                              __connman_service_nameserver_remove(service,
 +                                              dhcp->nameservers[i],
 +                                              false);
 +#endif
 +#if defined TIZEN_EXT
 +                      }
 +#endif
                        g_strfreev(dhcp->nameservers);
                }
  
  
                for (i = 0; dhcp->nameservers &&
                                        dhcp->nameservers[i]; i++)
 +#if defined TIZEN_EXT
 +              {
 +                      __connman_service_nameserver_append(service,
 +                                              dhcp->nameservers[i], false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV6);
 +#else
                        __connman_service_nameserver_append(service,
                                                dhcp->nameservers[i],
                                                false);
 +#endif
 +#if defined TIZEN_EXT
 +              }
 +#endif
        } else
                g_strfreev(nameservers);
  
@@@ -430,9 -392,7 +425,9 @@@ static int dhcpv6_info_request(struct c
                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);
@@@ -481,7 -441,6 +476,6 @@@ static int check_ipv6_addr_prefix(GSLis
                if (!slash)
                        continue;
  
-               prefix = g_strndup(prefix, slash - prefix);
                len = strtol(slash + 1, NULL, 10);
                if (len < 3 || len > 128)
                        break;
                left = plen % 8;
                i = 16 - count;
  
+               prefix = g_strndup(prefix, slash - prefix);
                inet_pton(AF_INET6, prefix, &addr_prefix);
                inet_pton(AF_INET6, address, &addr);
  
@@@ -557,19 -517,9 +552,19 @@@ static int set_other_addresses(GDHCPCli
        if (!compare_string_arrays(nameservers, dhcp->nameservers)) {
                if (dhcp->nameservers) {
                        for (i = 0; dhcp->nameservers[i]; i++)
 +#if defined TIZEN_EXT
 +                      {
 +                              __connman_service_nameserver_remove(service,
 +                                              dhcp->nameservers[i],
 +                                              false, CONNMAN_IPCONFIG_TYPE_IPV6);
 +#else
                                __connman_service_nameserver_remove(service,
                                                        dhcp->nameservers[i],
                                                        false);
 +#endif
 +#if defined TIZEN_EXT
 +                      }
 +#endif
                        g_strfreev(dhcp->nameservers);
                }
  
  
                for (i = 0; dhcp->nameservers &&
                                        dhcp->nameservers[i]; i++)
 +#if defined TIZEN_EXT
 +              {
                        __connman_service_nameserver_append(service,
 -                                                      dhcp->nameservers[i],
 -                                                      false);
 +                                      dhcp->nameservers[i],
 +                                      false, CONNMAN_IPCONFIG_TYPE_IPV6);
 +#else
 +                      __connman_service_nameserver_append(service,
 +                                              dhcp->nameservers[i],
 +                                              false);
 +#endif
 +#if defined TIZEN_EXT
 +              }
 +#endif
        } else
                g_strfreev(nameservers);
  
@@@ -698,9 -638,6 +693,9 @@@ static void set_address(int ifindex, st
                /* Is this prefix part of the subnet we are suppose to use? */
                prefix_len = check_ipv6_addr_prefix(prefixes, address);
  
 +#if defined TIZEN_EXT
 +              char *gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig));
 +#endif
                __connman_ipconfig_address_remove(ipconfig);
                __connman_ipconfig_set_local(ipconfig, address);
                __connman_ipconfig_set_prefixlen(ipconfig, prefix_len);
                DBG("new address %s/%d", address, prefix_len);
  
                __connman_ipconfig_set_dhcp_address(ipconfig, address);
 +#if defined TIZEN_EXT
 +              DBG("Set gateway %s", gateway);
 +              __connman_ipconfig_set_gateway(ipconfig, gateway);
 +              g_free(gateway);
 +#endif
                __connman_service_save(
                        __connman_service_lookup_from_index(ifindex));
        }
@@@ -1781,9 -1713,7 +1776,9 @@@ static gboolean timeout_solicitation(gp
  static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp)
  {
        struct connman_service *service;
 +#if !defined TIZEN_EXT
        struct connman_ipconfig *ipconfig_ipv6;
 +#endif
        GDHCPClient *dhcp_client;
        GDHCPClientError error;
        int index, ret;
                return -EINVAL;
        }
  
 +#if !defined TIZEN_EXT
        if (getenv("CONNMAN_DHCPV6_DEBUG"))
 +#endif
                g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
  
        service = connman_service_lookup_from_network(dhcp->network);
        g_dhcpv6_client_set_oro(dhcp_client, 3, G_DHCPV6_DNS_SERVERS,
                                G_DHCPV6_DOMAIN_LIST, G_DHCPV6_SNTP_SERVERS);
  
 +#if defined TIZEN_EXT
 +      /**
 +        When privacy extension is enabled then connman requests
 +        OPTION_IA_TA (4) from DHCPv6 server. This option is used to request
 +        temporary IPv6 address from DHCPv6 server but we found that DHCPv6
 +        server never provided temporary IPv6 address and connman resend dhcpv6
 +        requests. So always set OPTION_IA_NA in dhcpv6 request to get IPv6
 +        address from DHCPv6 server.
 +       */
 +      dhcp->use_ta = FALSE;
 +#else
        ipconfig_ipv6 = __connman_service_get_ip6config(service);
        dhcp->use_ta = __connman_ipconfig_ipv6_privacy_enabled(ipconfig_ipv6);
 +#endif
  
        g_dhcpv6_client_set_ia(dhcp_client, index,
                        dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
@@@ -2129,9 -2045,7 +2124,9 @@@ static GDHCPClient *create_pd_client(st
                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 --combined src/dnsproxy.c
index 55ba69a,40b4f15..3fa7bf4
mode 100755,100644..100755
  
  #include "connman.h"
  
 +#if defined TIZEN_EXT
 +#include <sys/smack.h>
 +#include <systemd/sd-daemon.h>
 +#endif
 +
+ #define debug(fmt...) do { } while (0)
  #if __BYTE_ORDER == __LITTLE_ENDIAN
  struct domain_hdr {
        uint16_t id;
@@@ -197,11 -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.
   */
@@@ -220,22 -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;
@@@ -301,7 -284,7 +303,7 @@@ static struct server_data *find_server(
  {
        GSList *list;
  
-       DBG("index %d server %s proto %d", index, server, protocol);
+       debug("index %d server %s proto %d", index, server, protocol);
  
        for (list = server_list; list; list = list->next) {
                struct server_data *data = list->data;
@@@ -352,14 -335,14 +354,14 @@@ static void refresh_dns_entry(struct ca
        }
  
        if (!entry->ipv4) {
-               DBG("Refresing A record for %s", name);
+               debug("Refreshing A record for %s", name);
                g_resolv_lookup_hostname(ipv4_resolve, name,
                                        dummy_resolve_func, NULL);
                age = 4;
        }
  
        if (!entry->ipv6) {
-               DBG("Refresing AAAA record for %s", name);
+               debug("Refreshing AAAA record for %s", name);
                g_resolv_lookup_hostname(ipv6_resolve, name,
                                        dummy_resolve_func, NULL);
                age = 4;
@@@ -374,7 -357,7 +376,7 @@@ static int dns_name_length(unsigned cha
  {
        if ((buf[0] & NS_CMPRSFLGS) == NS_CMPRSFLGS) /* compressed name */
                return 2;
-       return strlen((char *)buf);
+       return strlen((char *)buf) + 1;
  }
  
  static void update_cached_ttl(unsigned char *buf, int len, int new_ttl)
@@@ -471,7 -454,7 +473,7 @@@ static void send_cached_response(int sk
        else
                update_cached_ttl((unsigned char *)hdr, adj_len, ttl);
  
-       DBG("sk %d id 0x%04x answers %d ptr %p length %d dns %d",
+       debug("sk %d id 0x%04x answers %d ptr %p length %d dns %d",
                sk, hdr->id, answers, ptr, len, dns_len);
  
        err = sendto(sk, ptr, len, MSG_NOSIGNAL, to, tolen);
  
        if (err != len || (dns_len != (len - 2) && protocol == IPPROTO_TCP) ||
                                (dns_len != len && protocol == IPPROTO_UDP))
-               DBG("Packet length mismatch, sent %d wanted %d dns %d",
+               debug("Packet length mismatch, sent %d wanted %d dns %d",
                        err, len, dns_len);
  }
  
@@@ -494,7 -477,7 +496,7 @@@ static void send_response(int sk, unsig
        struct domain_hdr *hdr;
        int err, offset = protocol_offset(protocol);
  
-       DBG("sk %d", sk);
+       debug("sk %d", sk);
  
        if (offset < 0)
                return;
  
        hdr = (void *) (buf + offset);
  
-       DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
+       debug("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
  
        hdr->qr = 1;
        hdr->rcode = ns_r_servfail;
@@@ -556,7 -539,7 +558,7 @@@ static gboolean request_timeout(gpointe
        if (!req)
                return FALSE;
  
-       DBG("id 0x%04x", req->srcid);
+       debug("id 0x%04x", req->srcid);
  
        request_list = g_slist_remove(request_list, req);
  
         * if we get a request timeout from server.
         */
        if (req->protocol == IPPROTO_TCP) {
-               DBG("client %d removed", req->client_sk);
+               debug("client %d removed", req->client_sk);
                g_hash_table_remove(partial_tcp_req_table,
                                GINT_TO_POINTER(req->client_sk));
        }
@@@ -616,7 -599,7 +618,7 @@@ static int append_query(unsigned char *
        unsigned char *ptr = buf;
        int len;
  
-       DBG("query %s domain %s", query, domain);
+       debug("query %s domain %s", query, domain);
  
        while (query) {
                const char *tmp;
@@@ -686,7 -669,7 +688,7 @@@ static void cache_enforce_validity(stru
  
        if (!cache_check_is_valid(entry->ipv4, current_time)
                                                        && entry->ipv4) {
-               DBG("cache timeout \"%s\" type A", entry->key);
+               debug("cache timeout \"%s\" type A", entry->key);
                g_free(entry->ipv4->data);
                g_free(entry->ipv4);
                entry->ipv4 = NULL;
  
        if (!cache_check_is_valid(entry->ipv6, current_time)
                                                        && entry->ipv6) {
-               DBG("cache timeout \"%s\" type AAAA", entry->key);
+               debug("cache timeout \"%s\" type AAAA", entry->key);
                g_free(entry->ipv6->data);
                g_free(entry->ipv6);
                entry->ipv6 = NULL;
@@@ -720,7 -703,7 +722,7 @@@ static uint16_t cache_check_validity(ch
        switch (type) {
        case 1:         /* IPv4 */
                if (!cache_check_is_valid(entry->ipv4, current_time)) {
-                       DBG("cache %s \"%s\" type A", entry->ipv4 ?
+                       debug("cache %s \"%s\" type A", entry->ipv4 ?
                                        "timeout" : "entry missing", question);
  
                        if (want_refresh)
  
        case 28:        /* IPv6 */
                if (!cache_check_is_valid(entry->ipv6, current_time)) {
-                       DBG("cache %s \"%s\" type AAAA", entry->ipv6 ?
+                       debug("cache %s \"%s\" type AAAA", entry->ipv6 ?
                                        "timeout" : "entry missing", question);
  
                        if (want_refresh)
@@@ -785,7 -768,7 +787,7 @@@ static gboolean try_remove_cache(gpoint
        cache_timer = 0;
  
        if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) {
-               DBG("No cache users, removing it.");
+               debug("No cache users, removing it.");
  
                g_hash_table_destroy(cache);
                cache = NULL;
@@@ -1002,7 -985,7 +1004,7 @@@ static int parse_response(unsigned cha
        if (buflen < 12)
                return -EINVAL;
  
-       DBG("qr %d qdcount %d", hdr->qr, qdcount);
+       debug("qr %d qdcount %d", hdr->qr, qdcount);
  
        /* We currently only cache responses where question count is 1 */
        if (hdr->qr != 1 || qdcount != 1)
@@@ -1248,7 -1231,7 +1250,7 @@@ static void cache_cleanup(void
                count = g_hash_table_foreach_remove(cache, cache_check_entry,
                                                &data);
        }
-       DBG("removed %d in the first pass", count);
+       debug("removed %d in the first pass", count);
  
        /*
         * In the second pass, if the first pass turned up blank,
@@@ -1312,7 -1295,7 +1314,7 @@@ static gboolean cache_invalidate_entry(
   */
  static void cache_invalidate(void)
  {
-       DBG("Invalidating the DNS cache %p", cache);
+       debug("Invalidating the DNS cache %p", cache);
  
        if (!cache)
                return;
@@@ -1344,7 -1327,7 +1346,7 @@@ static void cache_refresh_entry(struct 
                        *c = '.';
                        c += jump + 1;
                }
-               DBG("Refreshing %s\n", dns_name);
+               debug("Refreshing %s\n", dns_name);
                /* then refresh the hostname */
                refresh_dns_entry(entry, &dns_name[1]);
        }
@@@ -1380,7 -1363,7 +1382,7 @@@ static int reply_query_type(unsigned ch
                return 0;
  
        /* now the query, which is a name and 2 16 bit words */
-       l = dns_name_length(c) + 1;
+       l = dns_name_length(c);
        c += l;
        type = c[0] << 8 | c[1];
  
@@@ -1421,7 -1404,7 +1423,7 @@@ static int cache_update(struct server_d
        if (offset < 0)
                return 0;
  
-       DBG("offset %d hdr %p msg %p rcode %d", offset, hdr, msg, hdr->rcode);
+       debug("offset %d hdr %p msg %p rcode %d", offset, hdr, msg, hdr->rcode);
  
        /* Continue only if response code is 0 (=ok) */
        if (hdr->rcode != ns_r_noerror)
                cache_size++;
        }
  
-       DBG("cache %d %squestion \"%s\" type %d ttl %d size %zd packet %u "
+       debug("cache %d %squestion \"%s\" type %d ttl %d size %zd packet %u "
                                                                "dns len %u",
                cache_size, new_entry ? "new " : "old ",
                question, type, ttl,
@@@ -1627,7 -1610,7 +1629,7 @@@ static int ns_resolv(struct server_dat
                int ttl_left = 0;
                struct cache_data *data;
  
-               DBG("cache hit %s type %s", lookup, type == 1 ? "A" : "AAAA");
+               debug("cache hit %s type %s", lookup, type == 1 ? "A" : "AAAA");
                if (type == 1)
                        data = entry->ipv4;
                else
                }
        }
  
 +#if defined TIZEN_EXT
 +      if (server->protocol == IPPROTO_UDP) {
 +              GList *domains;
 +              struct server_data *new_server = NULL;
 +
 +              new_server = create_server_sec(server->index, NULL,
 +                                              server->server, IPPROTO_UDP);
 +
 +              if (new_server != NULL) {
 +                      for (domains = server->domains; domains;
 +                                              domains = domains->next) {
 +                              char *dom = domains->data;
 +
 +                              DBG("Adding domain %s to %s",
 +                                              dom, new_server->server);
 +
 +                              new_server->domains = g_list_append(
 +                                              new_server->domains,
 +                                                      g_strdup(dom));
 +                      }
 +
 +                      server = new_server;
 +              }
 +      }
 +#endif
        sk = g_io_channel_unix_get_fd(server->channel);
  
        err = sendto(sk, request, req->request_len, MSG_NOSIGNAL,
                        server->server_addr, server->server_addr_len);
        if (err < 0) {
-               DBG("Cannot send message to server %s sock %d "
+               debug("Cannot send message to server %s sock %d "
                        "protocol %d (%s/%d)",
                        server->server, sk, server->protocol,
                        strerror(errno), errno);
                        alt[1] = req_len & 0xff;
                }
  
-               DBG("req %p dstid 0x%04x altid 0x%04x", req, req->dstid,
+               debug("req %p dstid 0x%04x altid 0x%04x", req, req->dstid,
                                req->altid);
  
                err = send(sk, alt, req->request_len + domlen, MSG_NOSIGNAL);
@@@ -1771,7 -1729,7 +1773,7 @@@ static char *convert_label(char *start
        pos = dn_expand((u_char *)start, (u_char *)end, (u_char *)ptr,
                        name, NS_MAXLABEL);
        if (pos < 0) {
-               DBG("uncompress error [%d/%s]", errno, strerror(errno));
+               debug("uncompress error [%d/%s]", errno, strerror(errno));
                goto out;
        }
  
         */
        comp_pos = dn_comp(name, (u_char *)uptr, remaining_len, NULL, NULL);
        if (comp_pos < 0) {
-               DBG("compress error [%d/%s]", errno, strerror(errno));
+               debug("compress error [%d/%s]", errno, strerror(errno));
                goto out;
        }
  
@@@ -1800,7 -1758,7 +1802,7 @@@ static char *uncompress(int16_t field_c
  {
        char *uptr = *uncompressed_ptr; /* position in result buffer */
  
-       DBG("count %d ptr %p end %p uptr %p", field_count, ptr, end, uptr);
+       debug("count %d ptr %p end %p uptr %p", field_count, ptr, end, uptr);
  
        while (field_count-- > 0 && ptr < end) {
                int dlen;               /* data field length */
                ulen = strlen(name);
                strncpy(uptr, name, uncomp_len - (uptr - uncompressed));
  
-               DBG("pos %d ulen %d left %d name %s", pos, ulen,
+               debug("pos %d ulen %d left %d name %s", pos, ulen,
                        (int)(uncomp_len - (uptr - uncompressed)), uptr);
  
                uptr += ulen;
                        dlen = uptr[-2] << 8 | uptr[-1];
  
                        if (ptr + dlen > end) {
-                               DBG("data len %d too long", dlen);
+                               debug("data len %d too long", dlen);
                                goto out;
                        }
  
@@@ -1977,13 -1935,13 +1979,13 @@@ static int forward_dns_reply(unsigned c
        hdr = (void *)(reply + offset);
        dns_id = reply[offset] | reply[offset + 1] << 8;
  
-       DBG("Received %d bytes (id 0x%04x)", reply_len, dns_id);
+       debug("Received %d bytes (id 0x%04x)", reply_len, dns_id);
  
        req = find_request(dns_id);
        if (!req)
                return -EINVAL;
  
-       DBG("req %p dstid 0x%04x altid 0x%04x rcode %d",
+       debug("req %p dstid 0x%04x altid 0x%04x rcode %d",
                        req, req->dstid, req->altid, hdr->rcode);
  
        reply[offset] = req->srcid & 0xff;
                                                        ptr[dns_type_pos + 3];
                        if (dns_type != ns_t_a && dns_type != ns_t_aaaa &&
                                        dns_class != ns_c_in) {
-                               DBG("Pass msg dns type %d class %d",
+                               debug("Pass msg dns type %d class %d",
                                        dns_type, dns_class);
                                goto pass;
                        }
                                                (char *)reply + offset, eom,
                                                ptr, uncompressed, NS_MAXDNAME,
                                                &uptr);
-                               if (ptr == NULL)
+                               if (!ptr)
                                        goto out;
  
                                ptr = uncompress(ntohs(hdr->nscount),
                                                (char *)reply + offset, eom,
                                                ptr, uncompressed, NS_MAXDNAME,
                                                &uptr);
-                               if (ptr == NULL)
+                               if (!ptr)
                                        goto out;
  
                                ptr = uncompress(ntohs(hdr->arcount),
                                                (char *)reply + offset, eom,
                                                ptr, uncompressed, NS_MAXDNAME,
                                                &uptr);
-                               if (ptr == NULL)
+                               if (!ptr)
                                        goto out;
  
                                /*
                                new_len = strip_domains(uncompressed, answers,
                                                        uptr - answers);
                                if (new_len < 0) {
-                                       DBG("Corrupted packet");
+                                       debug("Corrupted packet");
                                        return -EINVAL;
                                }
  
        }
  
        if (err < 0)
-               DBG("Cannot send msg, sk %d proto %d errno %d/%s", sk,
+               debug("Cannot send msg, sk %d proto %d errno %d/%s", sk,
                        protocol, errno, strerror(errno));
        else
-               DBG("proto %d sent %d bytes to %d", protocol, err, sk);
+               debug("proto %d sent %d bytes to %d", protocol, err, sk);
  
        destroy_request_data(req);
  
  
  static void server_destroy_socket(struct server_data *data)
  {
-       DBG("index %d server %s proto %d", data->index,
+       debug("index %d server %s proto %d", data->index,
                                        data->server, data->protocol);
  
        if (data->watch > 0) {
  
  static void destroy_server(struct server_data *server)
  {
-       DBG("index %d server %s sock %d", server->index, server->server,
+       debug("index %d server %s sock %d", server->index, server->server,
                        server->channel ?
                        g_io_channel_unix_get_fd(server->channel): -1);
  
        server_destroy_socket(server);
  
        if (server->protocol == IPPROTO_UDP && server->enabled)
-               DBG("Removing DNS server %s", server->server);
+               debug("Removing DNS server %s", server->server);
  
        g_free(server->server);
        g_list_free_full(server->domains, g_free);
@@@ -2282,19 -2240,6 +2284,19 @@@ static gboolean udp_server_event(GIOCha
        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;
  }
  
@@@ -2311,7 -2256,7 +2313,7 @@@ static gboolean tcp_server_event(GIOCha
        if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
                GSList *list;
  hangup:
-               DBG("TCP server channel closed, sk %d", sk);
+               debug("TCP server channel closed, sk %d", sk);
  
                /*
                 * Discard any partial response which is buffered; better
                g_free(server->incoming_reply);
                server->incoming_reply = NULL;
  
-               for (list = request_list; list; list = list->next) {
+               list = request_list;
+               while (list) {
                        struct request_data *req = list->data;
                        struct domain_hdr *hdr;
+                       list = list->next;
  
                        if (req->protocol == IPPROTO_UDP)
                                continue;
                                                domains = domains->next) {
                                char *dom = domains->data;
  
-                               DBG("Adding domain %s to %s",
+                               debug("Adding domain %s to %s",
                                                dom, server->server);
  
                                server->domains = g_list_append(server->domains,
                                continue;
                        }
  
-                       DBG("Sending req %s over TCP", (char *)req->name);
+                       debug("Sending req %s over TCP", (char *)req->name);
  
                        status = ns_resolv(server, req,
                                                req->request, req->name);
                        reply_len = reply_len_buf[1] | reply_len_buf[0] << 8;
                        reply_len += 2;
  
-                       DBG("TCP reply %d bytes from %d", reply_len, sk);
+                       debug("TCP reply %d bytes from %d", reply_len, sk);
  
                        reply = g_try_malloc(sizeof(*reply) + reply_len + 2);
                        if (!reply)
@@@ -2495,7 -2442,7 +2499,7 @@@ static gboolean tcp_idle_timeout(gpoint
  {
        struct server_data *server = user_data;
  
-       DBG("");
+       debug("");
  
        if (!server)
                return FALSE;
@@@ -2510,7 -2457,7 +2514,7 @@@ static int server_create_socket(struct 
        int sk, err;
        char *interface;
  
-       DBG("index %d server %s proto %d", data->index,
+       debug("index %d server %s proto %d", data->index,
                                        data->server, data->protocol);
  
        sk = socket(data->server_addr->sa_family,
                return -err;
        }
  
-       DBG("sk %d", sk);
+       debug("sk %d", sk);
  
        interface = connman_inet_ifname(data->index);
        if (interface) {
        return 0;
  }
  
+ static void enable_fallback(bool enable)
+ {
+       GSList *list;
+       for (list = server_list; list; list = list->next) {
+               struct server_data *data = list->data;
+               if (data->index != -1)
+                       continue;
+               if (enable)
+                       DBG("Enabling fallback DNS server %s", data->server);
+               else
+                       DBG("Disabling fallback DNS server %s", data->server);
+               data->enabled = enable;
+       }
+ }
 +#if defined TIZEN_EXT
 +
 +static void destroy_server_sec(struct server_data *server)
 +{
 +      GList *list;
 +      int fd;
 +
 +      if (server->channel)
 +              fd = g_io_channel_unix_get_fd(server->channel);
 +      else
 +              fd = -1;
 +
 +      DBG("index %d server %s sock %d", server->index, server->server, fd);
 +
 +      server_list_sec = g_slist_remove(server_list_sec, server);
 +
 +      if (fd > 0)
 +              close(fd);
 +
 +      server_destroy_socket(server);
 +
 +      if (server->protocol == IPPROTO_UDP && server->enabled)
 +              DBG("Removing DNS server %s", server->server);
 +
 +      g_free(server->server);
 +      for (list = server->domains; list; list = list->next) {
 +              char *domain = list->data;
 +
 +              server->domains = g_list_remove(server->domains, domain);
 +              g_free(domain);
 +      }
 +      g_free(server->server_addr);
 +
 +      /*
 +       * We do not remove cache right away but delay it few seconds.
 +       * The idea is that when IPv6 DNS server is added via RDNSS, it has a
 +       * lifetime. When the lifetime expires we decrease the refcount so it
 +       * is possible that the cache is then removed. Because a new DNS server
 +       * is usually created almost immediately we would then loose the cache
 +       * without any good reason. The small delay allows the new RDNSS to
 +       * create a new DNS server instance and the refcount does not go to 0.
 +       */
 +      /* TODO: Need to check this */
 +      /* g_timeout_add_seconds(3, try_remove_cache, NULL); */
 +
 +      g_free(server);
 +}
 +
 +static void destroy_all_server_sec()
 +{
 +      GSList *list;
 +
 +      DBG("remove all dns server");
 +
 +      for (list = server_list_sec; list; list = list->next) {
 +              struct server_data *server = list->data;
 +              destroy_server_sec(server);
 +      }
 +      server_list_sec = NULL;
 +}
 +
 +static gboolean sec_udp_idle_timeout(gpointer user_data)
 +{
 +      struct server_data *server = user_data;
 +
 +      DBG("");
 +
 +      if (server == NULL)
 +              return FALSE;
 +
 +      destroy_server_sec(server);
 +
 +      return FALSE;
 +}
 +
 +static struct server_data *create_server_sec(int index,
 +                                      const char *domain, const char *server,
 +                                      int protocol)
 +{
 +      struct server_data *data;
 +      struct addrinfo hints, *rp;
 +      int ret;
 +
 +      DBG("index %d server %s", index, server);
 +
 +      data = g_try_new0(struct server_data, 1);
 +      if (data == NULL) {
 +              connman_error("Failed to allocate server %s data", server);
 +              return NULL;
 +      }
 +
 +      data->index = index;
 +      if (domain)
 +              data->domains = g_list_append(data->domains, g_strdup(domain));
 +      data->server = g_strdup(server);
 +      data->protocol = protocol;
 +
 +      memset(&hints, 0, sizeof(hints));
 +
 +      switch (protocol) {
 +      case IPPROTO_UDP:
 +              hints.ai_socktype = SOCK_DGRAM;
 +              break;
 +
 +      case IPPROTO_TCP:
 +              hints.ai_socktype = SOCK_STREAM;
 +              break;
 +
 +      default:
 +              destroy_server_sec(data);
 +              return NULL;
 +      }
 +      hints.ai_family = AF_UNSPEC;
 +      hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST;
 +
 +      ret = getaddrinfo(data->server, "53", &hints, &rp);
 +      if (ret) {
 +              connman_error("Failed to parse server %s address: %s\n",
 +                              data->server, gai_strerror(ret));
 +              freeaddrinfo(rp);
 +              destroy_server_sec(data);
 +              return NULL;
 +      }
 +
 +      /* Do not blindly copy this code elsewhere; it doesn't loop over the
 +         results using ->ai_next as it should. That's OK in *this* case
 +         because it was a numeric lookup; we *know* there's only one. */
 +
 +      data->server_addr_len = rp->ai_addrlen;
 +
 +      switch (rp->ai_family) {
 +      case AF_INET:
 +              data->server_addr = (struct sockaddr *)
 +                                      g_try_new0(struct sockaddr_in, 1);
 +              break;
 +      case AF_INET6:
 +              data->server_addr = (struct sockaddr *)
 +                                      g_try_new0(struct sockaddr_in6, 1);
 +              break;
 +      default:
 +              connman_error("Wrong address family %d", rp->ai_family);
 +              break;
 +      }
 +      if (data->server_addr == NULL) {
 +              freeaddrinfo(rp);
 +              destroy_server_sec(data);
 +              return NULL;
 +      }
 +      memcpy(data->server_addr, rp->ai_addr, rp->ai_addrlen);
 +      freeaddrinfo(rp);
 +
 +      if (server_create_socket(data) != 0) {
 +              destroy_server_sec(data);
 +              return NULL;
 +      }
 +
 +      if (protocol == IPPROTO_UDP) {
 +              /* Enable new servers by default */
 +              data->enabled = TRUE;
 +              DBG("Adding DNS server %s", data->server);
 +
 +              data->timeout = g_timeout_add_seconds(30, sec_udp_idle_timeout,
 +                                                              data);
 +
 +              server_list_sec = g_slist_append(server_list_sec, data);
 +      }
 +
 +      return data;
 +}
 +#endif
 +
  static struct server_data *create_server(int index,
                                        const char *domain, const char *server,
                                        int protocol)
                                                                data->index)) {
                        data->enabled = true;
                        DBG("Adding DNS server %s", data->server);
+                       enable_fallback(false);
                }
  
                server_list = g_slist_append(server_list, data);
@@@ -2862,7 -2659,7 +2887,7 @@@ static bool resolv(struct request_data 
                        continue;
                }
  
-               DBG("server %s enabled %d", data->server, data->enabled);
+               debug("server %s enabled %d", data->server, data->enabled);
  
                if (!data->enabled)
                        continue;
        return false;
  }
  
- static void append_domain(int index, const char *domain)
+ static void update_domain(int index, const char *domain, bool append)
  {
        GSList *list;
  
                        }
                }
  
-               if (!dom_found) {
+               if (!dom_found && append) {
                        data->domains =
                                g_list_append(data->domains, g_strdup(domain));
+               } else if (dom_found && !append) {
+                       data->domains =
+                               g_list_remove(data->domains, dom);
+                       g_free(dom);
                }
        }
  }
  
+ static void append_domain(int index, const char *domain)
+ {
+       update_domain(index, domain, true);
+ }
+ static void remove_domain(int index, const char *domain)
+ {
+       update_domain(index, domain, false);
+ }
  static void flush_requests(struct server_data *server)
  {
        GSList *list;
@@@ -2988,12 -2799,22 +3027,22 @@@ static void remove_server(int index, co
                        const char *server, int protocol)
  {
        struct server_data *data;
+       GSList *list;
  
        data = find_server(index, server, protocol);
        if (!data)
                return;
  
        destroy_server(data);
+       for (list = server_list; list; list = list->next) {
+               struct server_data *data = list->data;
+               if (data->index != -1 && data->enabled == true)
+                       return;
+       }
+       enable_fallback(true);
  }
  
  int __connman_dnsproxy_remove(int index, const char *domain,
  {
        DBG("index %d server %s", index, server);
  
-       if (!server)
+       if (!server && !domain)
                return -EINVAL;
  
+       if (!server) {
+               remove_domain(index, domain);
+               return 0;
+       }
        if (g_str_equal(server, "127.0.0.1"))
                return -ENODEV;
  
        remove_server(index, domain, server, IPPROTO_UDP);
        remove_server(index, domain, server, IPPROTO_TCP);
  
 +#if defined TIZEN_EXT
 +      destroy_all_server_sec();
 +#endif
 +
        return 0;
  }
  
@@@ -3044,6 -2867,7 +3099,7 @@@ static void dnsproxy_offline_mode(bool 
  
  static void dnsproxy_default_changed(struct connman_service *service)
  {
+       bool server_enabled = false;
        GSList *list;
        int index;
  
                if (data->index == index) {
                        DBG("Enabling DNS server %s", data->server);
                        data->enabled = true;
+                       server_enabled = true;
                } else {
                        DBG("Disabling DNS server %s", data->server);
                        data->enabled = false;
                }
        }
  
+       if (!server_enabled)
+               enable_fallback(true);
        cache_refresh();
  }
  
@@@ -3098,7 -2926,7 +3158,7 @@@ static int parse_request(unsigned char 
        if (len < 12)
                return -EINVAL;
  
-       DBG("id 0x%04x qr %d opcode %d qdcount %d arcount %d",
+       debug("id 0x%04x qr %d opcode %d qdcount %d arcount %d",
                                        hdr->id, hdr->qr, hdr->opcode,
                                                        qdcount, arcount);
  
  
                edns0_bufsize = last_label[7] << 8 | last_label[8];
  
-               DBG("EDNS0 buffer size %u", edns0_bufsize);
+               debug("EDNS0 buffer size %u", edns0_bufsize);
  
                /* This is an evil hack until full TCP support has been
                 * implemented.
                }
        }
  
-       DBG("query %s", name);
+       debug("query %s", name);
  
        return 0;
  }
@@@ -3163,7 -2991,7 +3223,7 @@@ static void client_reset(struct tcp_par
                return;
  
        if (client->channel) {
-               DBG("client %d closing",
+               debug("client %d closing",
                        g_io_channel_unix_get_fd(client->channel));
  
                g_io_channel_unref(client->channel);
@@@ -3207,14 -3035,14 +3267,14 @@@ static bool read_tcp_data(struct tcp_pa
        client_sk = g_io_channel_unix_get_fd(client->channel);
  
        if (read_len == 0) {
-               DBG("client %d closed, pending %d bytes",
+               debug("client %d closed, pending %d bytes",
                        client_sk, client->buf_end);
                g_hash_table_remove(partial_tcp_req_table,
                                        GINT_TO_POINTER(client_sk));
                return false;
        }
  
-       DBG("client %d received %d bytes", client_sk, read_len);
+       debug("client %d received %d bytes", client_sk, read_len);
  
        client->buf_end += read_len;
  
  
        msg_len = get_msg_len(client->buf);
        if (msg_len > TCP_MAX_BUF_LEN) {
-               DBG("client %d sent too much data %d", client_sk, msg_len);
+               debug("client %d sent too much data %d", client_sk, msg_len);
                g_hash_table_remove(partial_tcp_req_table,
                                        GINT_TO_POINTER(client_sk));
                return false;
        }
  
  read_another:
-       DBG("client %d msg len %d end %d past end %d", client_sk, msg_len,
+       debug("client %d msg len %d end %d past end %d", client_sk, msg_len,
                client->buf_end, client->buf_end - (msg_len + 2));
  
        if (client->buf_end < (msg_len + 2)) {
-               DBG("client %d still missing %d bytes",
+               debug("client %d still missing %d bytes",
                        client_sk,
                        msg_len + 2 - client->buf_end);
                return true;
        }
  
-       DBG("client %d all data %d received", client_sk, msg_len);
+       debug("client %d all data %d received", client_sk, msg_len);
  
        err = parse_request(client->buf + 2, msg_len,
                        query, sizeof(query));
                int ttl_left = 0;
                struct cache_data *data;
  
-               DBG("cache hit %s type %s", query, qtype == 1 ? "A" : "AAAA");
+               debug("cache hit %s type %s", query, qtype == 1 ? "A" : "AAAA");
                if (qtype == 1)
                        data = entry->ipv4;
                else
                        g_free(req);
                        goto out;
                } else
-                       DBG("data missing, ignoring cache for this query");
+                       debug("data missing, ignoring cache for this query");
        }
  
        for (list = server_list; list; list = list->next) {
  
  out:
        if (client->buf_end > (msg_len + 2)) {
-               DBG("client %d buf %p -> %p end %d len %d new %d",
+               debug("client %d buf %p -> %p end %d len %d new %d",
                        client_sk,
                        client->buf + msg_len + 2,
                        client->buf, client->buf_end,
                 */
                msg_len = get_msg_len(client->buf);
                if ((msg_len + 2) == client->buf_end) {
-                       DBG("client %d reading another %d bytes", client_sk,
+                       debug("client %d reading another %d bytes", client_sk,
                                                                msg_len + 2);
                        goto read_another;
                }
        } else {
-               DBG("client %d clearing reading buffer", client_sk);
+               debug("client %d clearing reading buffer", client_sk);
  
                client->buf_end = 0;
                memset(client->buf, 0, TCP_MAX_BUF_LEN);
@@@ -3436,7 -3264,7 +3496,7 @@@ static gboolean tcp_client_event(GIOCha
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                        return TRUE;
  
-               DBG("client %d cannot read errno %d/%s", client_sk, -errno,
+               debug("client %d cannot read errno %d/%s", client_sk, -errno,
                        strerror(errno));
                g_hash_table_remove(partial_tcp_req_table,
                                        GINT_TO_POINTER(client_sk));
@@@ -3453,30 -3281,13 +3513,30 @@@ static gboolean client_timeout(gpointe
  
        sock = g_io_channel_unix_get_fd(client->channel);
  
-       DBG("client %d timeout pending %d bytes", sock, client->buf_end);
+       debug("client %d timeout pending %d bytes", sock, client->buf_end);
  
        g_hash_table_remove(partial_tcp_req_table, GINT_TO_POINTER(sock));
  
        return FALSE;
  }
  
 +#if defined TIZEN_EXT
 +static void recover_listener(GIOChannel *channel, struct listener_data *ifdata)
 +{
 +      int sk, index;
 +
 +      index = ifdata->index;
 +
 +      sk = g_io_channel_unix_get_fd(channel);
 +      close(sk);
 +
 +      __connman_dnsproxy_remove_listener(index);
 +
 +      if (__connman_dnsproxy_add_listener(index) == 0)
 +              DBG("listener %d successfully recovered", index);
 +}
 +#endif
 +
  static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition,
                                struct listener_data *ifdata, int family,
                                guint *listener_watch)
        struct timeval tv;
        fd_set readfds;
  
-       DBG("condition 0x%02x channel %p ifdata %p family %d",
+       debug("condition 0x%02x channel %p ifdata %p family %d",
                condition, channel, ifdata, family);
  
        if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
 +#if defined TIZEN_EXT
 +              connman_error("Error %d with TCP listener channel", condition);
 +
 +              recover_listener(channel, ifdata);
 +#else
                if (*listener_watch > 0)
                        g_source_remove(*listener_watch);
                *listener_watch = 0;
  
                connman_error("Error with TCP listener channel");
 +#endif
  
                return false;
        }
        select(sk + 1, &readfds, NULL, NULL, &tv);
        if (FD_ISSET(sk, &readfds)) {
                client_sk = accept(sk, client_addr, client_addr_len);
-               DBG("client %d accepted", client_sk);
+               debug("client %d accepted", client_sk);
        } else {
-               DBG("No data to read from master %d, waiting.", sk);
+               debug("No data to read from master %d, waiting.", sk);
                return true;
        }
  
  
                client->ifdata = ifdata;
  
-               DBG("client %d created %p", client_sk, client);
+               debug("client %d created %p", client_sk, client);
        } else {
-               DBG("client %d already exists %p", client_sk, client);
+               debug("client %d already exists %p", client_sk, client);
        }
  
        if (!client->buf) {
        len = recv(client_sk, client->buf, TCP_MAX_BUF_LEN, 0);
        if (len < 0) {
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
-                       DBG("client %d no data to read, waiting", client_sk);
+                       debug("client %d no data to read, waiting", client_sk);
                        return true;
                }
  
-               DBG("client %d cannot read errno %d/%s", client_sk, -errno,
+               debug("client %d cannot read errno %d/%s", client_sk, -errno,
                        strerror(errno));
                g_hash_table_remove(partial_tcp_req_table,
                                        GINT_TO_POINTER(client_sk));
        }
  
        if (len < 2) {
-               DBG("client %d not enough data to read, waiting", client_sk);
+               debug("client %d not enough data to read, waiting", client_sk);
                client->buf_end += len;
                return true;
        }
  
        msg_len = get_msg_len(client->buf);
        if (msg_len > TCP_MAX_BUF_LEN) {
-               DBG("client %d invalid message length %u ignoring packet",
+               debug("client %d invalid message length %u ignoring packet",
                        client_sk, msg_len);
                g_hash_table_remove(partial_tcp_req_table,
                                        GINT_TO_POINTER(client_sk));
         * The packet length bytes do not contain the total message length,
         * that is the reason to -2 below.
         */
 +#if defined TIZEN_EXT
 +      if (msg_len > (unsigned int)(len - 2)) {
 +#else
        if (msg_len != (unsigned int)(len - 2)) {
-               DBG("client %d sent %d bytes but expecting %u pending %d",
 +#endif
+               debug("client %d sent %d bytes but expecting %u pending %d",
                        client_sk, len, msg_len + 2, msg_len + 2 - len);
  
                client->buf_end += len;
@@@ -3670,14 -3471,8 +3730,14 @@@ static bool udp_listener_event(GIOChann
        int sk, err, len;
  
        if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
 +#if defined TIZEN_EXT
 +              connman_error("Error %d with UDP listener channel", condition);
 +
 +              recover_listener(channel, ifdata);
 +#else
                connman_error("Error with UDP listener channel");
                *listener_watch = 0;
 +#endif
                return false;
        }
  
        if (len < 2)
                return true;
  
-       DBG("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
+       debug("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
  
        err = parse_request(buf, len, query, sizeof(query));
        if (err < 0 || (g_slist_length(server_list) == 0)) {
        req->name = g_strdup(query);
        req->request = g_malloc(len);
        memcpy(req->request, buf, len);
 +#if defined TIZEN_EXT
 +      DBG("req %p dstid 0x%04x altid 0x%04x", req, req->dstid, req->altid);
 +      req->timeout = g_timeout_add_seconds(30, request_timeout, req);
 +#else
        req->timeout = g_timeout_add_seconds(5, request_timeout, req);
 +#endif
        request_list = g_slist_append(request_list, req);
  
        return true;
@@@ -3769,26 -3559,16 +3829,26 @@@ static GIOChannel *get_listener(int fam
  {
        GIOChannel *channel;
        const char *proto;
 +#if !defined TIZEN_EXT
        union {
                struct sockaddr sa;
                struct sockaddr_in6 sin6;
                struct sockaddr_in sin;
        } s;
        socklen_t slen;
 +#endif
        int sk, type;
 +#if !defined TIZEN_EXT
        char *interface;
 +#endif
 +#if defined TIZEN_EXT
 +      int option;
 +      int sd_num = 0;
 +      int rv;
 +      int is_socket_inet = 0;
 +#endif
  
-       DBG("family %d protocol %d index %d", family, protocol, index);
+       debug("family %d protocol %d index %d", family, protocol, index);
  
        switch (protocol) {
        case IPPROTO_UDP:
        default:
                return NULL;
        }
 +#if defined TIZEN_EXT
 +      sd_num = sd_listen_fds(0);
 +      DBG("socket type(%s) systemd number of fds(%d)", proto, sd_num);
 +      if(sd_num < 1){
 +              DBG("fail to get the fd from systemd");
 +              return NULL;
 +      }
  
 +      if(protocol == IPPROTO_TCP)
 +              type = SOCK_STREAM;
 +      else
 +              type = SOCK_DGRAM;
 +
 +      for(sk = SD_LISTEN_FDS_START; sk < SD_LISTEN_FDS_START+sd_num; ++sk){
 +              rv = sd_is_socket_inet(sk, family, type, -1, 53);
 +              if(rv > 0){
 +                      DBG("socket fd (%d) is passed by systemd", sk);
 +                      is_socket_inet = 1;
 +                      break;
 +              }
 +      }
 +
 +      if (!is_socket_inet) {
 +              DBG("socket fd is not matched what connman requests");
 +              return NULL;
 +      }
 +#else
        sk = socket(family, type, protocol);
        if (sk < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
                connman_error("No IPv6 support");
                return NULL;
        }
  
 +      /* ConnMan listens DNS from multiple interfaces
 +       * E.g. various technology based and tethering interfaces
 +       */
        interface = connman_inet_ifname(index);
        if (!interface || setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
                                        interface,
                s.sin.sin_family = AF_INET;
                s.sin.sin_port = htons(53);
                slen = sizeof(s.sin);
 -
                if (__connman_inet_get_interface_address(index,
                                                AF_INET,
                                                &s.sin.sin_addr) < 0) {
                close(sk);
                return NULL;
        }
 -
 +#endif
 +#if defined TIZEN_EXT
 +      /* When ConnMan crashed,
 +       * probably DNS listener cannot bind existing address */
 +      option = 1;
 +      setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
 +#endif
 +#if !defined TIZEN_EXT
        if (bind(sk, &s.sa, slen) < 0) {
                connman_error("Failed to bind %s listener socket", proto);
                close(sk);
                return NULL;
        }
 +#endif
  
        if (protocol == IPPROTO_TCP) {
 -
 +#if !defined TIZEN_EXT
                if (listen(sk, 10) < 0) {
                        connman_error("Failed to listen on TCP socket %d/%s",
                                -errno, strerror(errno));
                        close(sk);
                        return NULL;
                }
 -
 +#endif
                fcntl(sk, F_SETFL, O_NONBLOCK);
        }
  
@@@ -3947,68 -3691,40 +4007,68 @@@ static int create_dns_listener(int prot
                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;
        }
@@@ -4087,7 -3803,7 +4147,7 @@@ static void destroy_listener(struct lis
        for (list = request_list; list; list = list->next) {
                struct request_data *req = list->data;
  
-               DBG("Dropping request (id 0x%04x -> 0x%04x)",
+               debug("Dropping request (id 0x%04x -> 0x%04x)",
                                                req->srcid, req->dstid);
                destroy_request_data(req);
                list->data = NULL;
diff --combined src/inet.c
index 02d9604,b887aa0..008f3de
mode 100755,100644..100755
@@@ -330,61 -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;
@@@ -1307,13 -1252,12 +1307,12 @@@ static gboolean rs_timeout_cb(gpointer 
        return FALSE;
  }
  
- static int icmpv6_recv(int fd, gpointer user_data)
+ static int icmpv6_recv(int fd, struct xs_cb_data *data)
  {
        struct msghdr mhdr;
        struct iovec iov;
        unsigned char chdr[CMSG_BUF_LEN];
        unsigned char buf[1540];
-       struct xs_cb_data *data = user_data;
        struct nd_router_advert *hdr;
        struct sockaddr_in6 saddr;
        ssize_t len;
        len = recvmsg(fd, &mhdr, 0);
        if (len < 0) {
                cb(NULL, 0, data->user_data);
-               xs_cleanup(data);
                return -errno;
        }
  
 +#if defined TIZEN_EXT
 +      /* Set Received Source Address from router as IPv6 Gateway Address */
 +      char src_addr[INET6_ADDRSTRLEN];
 +      if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
 +                      == NULL) {
 +              xs_cleanup(data);
 +              return -errno;
 +      }
 +      DBG("Received Source Address %s from router", src_addr);
 +
 +      /* icmpv6_recv() function can be called in two scenarios :
 +       * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
 +       * 2. When __connman_inet_ipv6_send_rs() is called from
 +       * __connman_6to4_probe()
 +       * In the second case it is not  required to set DHCPv6 Gateway  Address
 +       * as DHCPv6 was not started and  network structure was not passed as
 +       * user_data. If it is tried  to add Source Address as  Gateway Address
 +       * then it will lead to  crash because of  user_data being ip_address
 +       * instead of network structure. So Adding Gateway Address in case 1st
 +       * case only.
 +       */
 +      char *address = data->user_data;
 +      int err = 0;
 +      unsigned char buffer[sizeof(struct in6_addr)] = {0, };
 +      /* Checking if user_data is an ip_address */
 +      err = inet_pton(AF_INET, address, buffer);
 +      /* Setting Received Source Address from
 +       * router as Gateway Address */
 +      if(err <= 0)
 +              __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
 +#endif
        hdr = (struct nd_router_advert *)buf;
        DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
                                sizeof(struct nd_router_advert));
                return 0;
  
        cb(hdr, len, data->user_data);
-       xs_cleanup(data);
  
        return len;
  }
  static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
  {
        int fd, ret;
+       struct xs_cb_data *xs_data = data;
  
        DBG("");
  
        if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
-               return FALSE;
+               goto cleanup;
  
        fd = g_io_channel_unix_get_fd(chan);
-       ret = icmpv6_recv(fd, data);
+       ret = icmpv6_recv(fd, xs_data);
        if (ret == 0)
                return TRUE;
  
-       return FALSE;
+ cleanup:
+       xs_cleanup(xs_data);
+       return TRUE;
  }
  
  /* Adapted from RFC 1071 "C" Implementation Example */
@@@ -1467,9 -1381,6 +1467,9 @@@ static int ndisc_send_unspec(int type, 
        char cbuf[CMSG_SPACE(sizeof(*pinfo))];
        struct iovec iov[2];
        int fd, datalen, ret, iovlen = 1;
 +#if defined TIZEN_EXT
 +      char ebuf[256];
 +#endif
  
        DBG("");
  
        msgh.msg_controllen = cmsg->cmsg_len;
  
        ret = sendmsg(fd, &msgh, 0);
 +#if defined TIZEN_EXT
 +      DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
 +#endif
  
        close(fd);
        return ret;
@@@ -1759,13 -1667,12 +1759,12 @@@ void __connman_inet_ipv6_stop_recv_rs(v
        xs_cleanup(context);
  }
  
- static int icmpv6_rs_recv(int fd, gpointer user_data)
+ static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
  {
        struct msghdr mhdr;
        struct iovec iov;
        unsigned char chdr[CMSG_BUF_LEN];
        unsigned char buf[1540];
-       struct xs_cb_data *data = user_data;
        struct nd_router_solicit *hdr;
        struct sockaddr_in6 saddr;
        ssize_t len;
@@@ -1804,17 -1711,20 +1803,20 @@@ static gboolean icmpv6_rs_event(GIOChan
                                                                gpointer data)
  {
        int fd, ret;
+       struct xs_cb_data *xs_data = data;
  
        DBG("");
  
        if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
-               return FALSE;
+               goto cleanup;
  
        fd = g_io_channel_unix_get_fd(chan);
-       ret = icmpv6_rs_recv(fd, data);
+       ret = icmpv6_rs_recv(fd, xs_data);
        if (ret == 0)
                return TRUE;
  
+ cleanup:
+       xs_data->watch_id = 0;
        return FALSE;
  }
  
@@@ -1889,13 -1799,12 +1891,12 @@@ static gboolean ns_timeout_cb(gpointer 
        return FALSE;
  }
  
- static int icmpv6_nd_recv(int fd, gpointer user_data)
+ static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
  {
        struct msghdr mhdr;
        struct iovec iov;
        unsigned char chdr[CMSG_BUF_LEN];
        unsigned char buf[1540];
-       struct xs_cb_data *data = user_data;
        struct nd_neighbor_advert *hdr;
        struct sockaddr_in6 saddr;
        ssize_t len;
        len = recvmsg(fd, &mhdr, 0);
        if (len < 0) {
                cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
-               xs_cleanup(data);
                return -errno;
        }
  
                return 0;
  
        cb(hdr, len, &data->addr.sin6_addr, data->user_data);
-       xs_cleanup(data);
  
        return len;
  }
@@@ -1945,18 -1852,21 +1944,21 @@@ static gboolean icmpv6_nd_event(GIOChan
                                                                gpointer data)
  {
        int fd, ret;
+       struct xs_cb_data *xs_data = data;
  
        DBG("");
  
        if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
-               return FALSE;
+               goto cleanup;
  
        fd = g_io_channel_unix_get_fd(chan);
-       ret = icmpv6_nd_recv(fd, data);
+       ret = icmpv6_nd_recv(fd, xs_data);
        if (ret == 0)
                return TRUE;
  
-       return FALSE;
+ cleanup:
+       xs_cleanup(xs_data);
+       return TRUE;
  }
  
  int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
@@@ -2280,9 -2190,8 +2282,8 @@@ static gboolean inet_rtnl_timeout_cb(gp
        return FALSE;
  }
  
- static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
+ static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
  {
-       struct inet_rtnl_cb_data *rtnl_data = user_data;
        struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
        struct nlmsghdr *h = NULL;
        struct sockaddr_nl nladdr;
@@@ -2364,17 -2273,20 +2365,20 @@@ static gboolean inet_rtnl_event(GIOChan
                                                        gpointer user_data)
  {
        int ret;
+       struct inet_rtnl_cb_data *rtnl_data = user_data;
  
        DBG("");
  
        if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
-               return FALSE;
+               goto cleanup;
  
-       ret = inet_rtnl_recv(chan, user_data);
-       if (ret != 0)
+       ret = inet_rtnl_recv(chan, rtnl_data);
+       if (ret == 0)
                return TRUE;
  
-       return FALSE;
+ cleanup:
+       inet_rtnl_cleanup(rtnl_data);
+       return TRUE;
  }
  
  int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
  {
        struct sockaddr_nl nladdr;
        struct inet_rtnl_cb_data *data;
-       unsigned seq;
        int err;
  
        memset(&nladdr, 0, sizeof(nladdr));
        nladdr.nl_family = AF_NETLINK;
  
-       n->nlmsg_seq = seq = ++rtnl->seq;
+       n->nlmsg_seq = ++rtnl->seq;
  
        if (callback) {
                data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
                                                inet_rtnl_timeout_cb, data);
  
                data->channel = g_io_channel_unix_new(rtnl->fd);
-               g_io_channel_set_close_on_unref(data->channel, TRUE);
  
                g_io_channel_set_encoding(data->channel, NULL, NULL);
                g_io_channel_set_buffered(data->channel, FALSE);
@@@ -2741,13 -2651,12 +2743,13 @@@ char **__connman_inet_get_running_inter
  
        g_free(ifr);
  
 -      if (count < numif) {
 +      if (count < numif)
 +      {
                char **prev_result = result;
                result = g_try_realloc(result, (count + 1) * sizeof(char *));
                if (!result) {
                        g_free(prev_result);
-                       goto error;
+                       return NULL;
                }
        }
  
        close(sk);
        return ret;
  }
+ static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
+                               struct in_addr *addr)
+ {
+       char *s, *nfsargs;
+       size_t len;
+       char addrstr[INET_ADDRSTRLEN];
+       struct in_addr taddr;
+       GError *error = NULL;
+       char *cmdline = NULL;
+       char *pnp = NULL;
+       char **args = NULL;
+       char **pnpent = NULL;
+       char **pp = NULL;
+       int err = -1;
+       if (!cmdline_file)
+               cmdline_file = "/proc/cmdline";
+       if (!pnp_file)
+               pnp_file = "/proc/net/pnp";
+       if (!addr)
+               addr = &taddr;
+       addr->s_addr = INADDR_NONE;
+       if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
+               connman_error("%s: Cannot read %s %s\n", __func__,
+                               cmdline_file, error->message);
+               goto out;
+       }
+       if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
+               if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
+                       connman_error("%s: Cannot read %s %s\n", __func__,
+                                                 pnp_file, error->message);
+                       goto out;
+               }
+       } else {
+               connman_error("%s: File %s doesn't exist\n", __func__, pnp_file);
+               goto out;
+       }
+       len = strlen(cmdline);
+       if (len <= 1) {
+               /* too short */
+               goto out;
+       }
+       /* remove newline */
+       if (cmdline[len - 1] == '\n')
+               cmdline[--len] = '\0';
+       /* split in arguments (seperated by space) */
+       args = g_strsplit(cmdline, " ", 0);
+       if (!args) {
+               connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
+                               cmdline);
+               goto out;
+       }
+       /* split in entries (by newlines) */
+       pnpent = g_strsplit(pnp, "\n", 0);
+       if (!pnpent) {
+               connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
+                               pnp_file);
+               goto out;
+       }
+       /* first find root argument */
+       for (pp = args; *pp; pp++) {
+               if (!strcmp(*pp, "root=/dev/nfs"))
+                       break;
+       }
+       /* no rootnfs found */
+       if (!*pp)
+               goto out;
+       /* locate nfsroot argument */
+       for (pp = args; *pp; pp++) {
+               if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
+                       break;
+       }
+       /* no nfsroot argument found */
+       if (!*pp)
+               goto out;
+       /* determine if nfsroot server is provided */
+       nfsargs = strchr(*pp, '=');
+       if (!nfsargs)
+               goto out;
+       nfsargs++;
+       /* find whether serverip is present */
+       s = strchr(nfsargs, ':');
+       if (s) {
+               len = s - nfsargs;
+               s = nfsargs;
+       } else {
+               /* no serverip, use bootserver */
+               for (pp = pnpent; *pp; pp++) {
+                       if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
+                               break;
+               }
+               /* no bootserver found */
+               if (!*pp)
+                       goto out;
+               s = *pp + strlen("bootserver ");
+               len = strlen(s);
+       }
+       /* copy to addr string buffer */
+       if (len >= sizeof(addrstr)) {
+               connman_error("%s: Bad server\n", __func__);
+               goto out;
+       }
+       memcpy(addrstr, s, len);
+       addrstr[len] = '\0';
+       err = inet_pton(AF_INET, addrstr, addr);
+       if (err <= 0) {
+               connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
+                               __func__, addrstr);
+               err = -1;
+               goto out;
+       }
+       /* all done */
+       err = 0;
+ out:
+       g_strfreev(pnpent);
+       g_strfreev(args);
+       if (error)
+               g_error_free(error);
+       g_free(pnp);
+       g_free(cmdline);
+       return err;
+ }
+ /* get interface out of which peer is reachable (IPv4 only) */
+ static int get_peer_iface(struct in_addr *addr, char *ifname)
+ {
+       struct ifaddrs *ifaddr, *ifa;
+       struct sockaddr_in saddr, *ifsaddr;
+       socklen_t socklen;
+       int s;
+       int err = -1;
+       /* Obtain address(es) matching host/port */
+       err = getifaddrs(&ifaddr);
+       if (err < 0) {
+               connman_error("%s: getifaddrs() failed %d (%s)\n",
+                               __func__, errno, strerror(errno));
+               return -1;
+       }
+       s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       if (s < 0) {
+               connman_error("%s: socket() failed %d (%s)\n",
+                               __func__, errno, strerror(errno));
+               return -1;
+       }
+       memset(&saddr, 0, sizeof(saddr));
+       saddr.sin_family = AF_INET;
+       saddr.sin_port = 0;     /* any port */
+       saddr.sin_addr = *addr;
+       /* no need to bind, connect will select iface */
+       err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
+       if (err < 0) {
+               connman_error("%s: connect() failed: %d (%s)\n",
+                               __func__, errno, strerror(errno));
+               goto out;
+       }
+       socklen = sizeof(saddr);
+       err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
+       if (err < 0) {
+               connman_error("%s: getsockname() failed: %d (%s)\n",
+                               __func__, errno, strerror(errno));
+               goto out;
+       }
+       err = -1;
+       for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+               if (!ifa->ifa_addr)
+                       continue;
+               /* only IPv4 address */
+               if (ifa->ifa_addr->sa_family != AF_INET)
+                       continue;
+               ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
+               /* match address? */
+               if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
+                       break;
+       }
+       if (ifa) {
+               err = 0;
+               if (ifname)
+                       strcpy(ifname, ifa->ifa_name);
+       }
+ out:
+       close(s);
+       freeifaddrs(ifaddr);
+       return err;
+ }
+ bool __connman_inet_isrootnfs_device(const char *devname)
+ {
+       struct in_addr addr;
+       char ifname[IFNAMSIZ];
+       return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
+              get_peer_iface(&addr, ifname) == 0 &&
+              strcmp(devname, ifname) == 0;
+ }
+ char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
+ {
+       char **pp;
+       char *s;
+       int pass, count;
+       GError *error = NULL;
+       char *pnp = NULL;
+       char **pnpent = NULL;
+       char **nameservers = NULL;
+       if (!pnp_file)
+               pnp_file = "/proc/net/pnp";
+       if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
+               connman_error("%s: Cannot read %s %s\n", __func__,
+                               pnp_file, error->message);
+               goto out;
+       }
+       /* split in entries (by newlines) */
+       pnpent = g_strsplit(pnp, "\n", 0);
+       if (!pnpent) {
+               connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
+                               pnp_file);
+               goto out;
+       }
+       /*
+        * Perform two passes to retreive a char ** array of
+        * nameservers that are not 0.0.0.0
+        *
+        * The first pass counts them, the second fills in the
+        * array.
+        */
+       count = 0;
+       nameservers = NULL;
+       for (pass = 1; pass <= 2; pass++) {
+               /* at the start of the second pass allocate */
+               if (pass == 2)
+                       nameservers = g_new(char *, count + 1);
+               count = 0;
+               for (pp = pnpent; *pp; pp++) {
+                       /* match 'nameserver ' at the start of each line */
+                       if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
+                               continue;
+                       /* compare it against 0.0.0.0 */
+                       s = *pp + strlen("nameserver ");
+                       if (!strcmp(s, "0.0.0.0"))
+                               continue;
+                       /* on second pass fill in array */
+                       if (pass == 2)
+                               nameservers[count] = g_strdup(s);
+                       count++;
+               }
+               /* no nameservers? */
+               if (count == 0)
+                       goto out;
+               /* and terminate char ** array with NULL */
+               if (pass == 2)
+                       nameservers[count] = NULL;
+       }
+ out:
+       g_strfreev(pnpent);
+       g_free(pnp);
+       if (error)
+               g_error_free(error);
+       return nameservers;
+ }
diff --combined src/ipconfig.c
index ff1909d,2565773..d94b873
mode 100755,100644..100755
@@@ -48,15 -48,10 +48,14 @@@ struct connman_ipconfig 
        const struct connman_ipconfig_ops *ops;
        void *ops_data;
  
-       bool enabled;
        enum connman_ipconfig_method method;
        struct connman_ipaddress *address;
        struct connman_ipaddress *system;
  
 +#if defined TIZEN_EXT
 +      int dhcp_lease_duration;
 +#endif
 +
        int ipv6_privacy_config;
        char *last_dhcp_address;
        char **last_dhcpv6_prefixes;
@@@ -413,40 -408,6 +412,6 @@@ static void free_ipdevice(gpointer data
        g_free(ipdevice);
  }
  
- static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice)
- {
-       DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
-                       ipdevice->config_ipv6);
- #if defined TIZEN_EXT
-       if (ipdevice->config_ipv6 != NULL &&
-                       ipdevice->config_ipv6->enabled == TRUE)
-               return;
-       char *ifname = connman_inet_ifname(ipdevice->index);
-       if (__connman_device_isfiltered(ifname) == FALSE) {
-               ipdevice->ipv6_enabled = get_ipv6_state(ifname);
-               set_ipv6_state(ifname, FALSE);
-       }
-       g_free(ifname);
- #endif
- }
- static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
- {
-       DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
-                                       ipdevice->config_ipv6);
-       if (ipdevice->config_ipv4)
-               connman_inet_clear_address(ipdevice->index,
-                                       ipdevice->config_ipv4->address);
-       if (ipdevice->config_ipv6)
-               connman_inet_clear_ipv6_address(ipdevice->index,
-                               ipdevice->config_ipv6->address->local,
-                               ipdevice->config_ipv6->address->prefixlen);
- }
  static void update_stats(struct connman_ipdevice *ipdevice,
                        const char *ifname, struct rtnl_link_stats *stats)
  {
@@@ -527,16 -488,6 +492,16 @@@ void __connman_ipconfig_newlink(int ind
                                                index, type, type2str(type));
  
  update:
 +#if defined TIZEN_EXT
 +      if (g_strcmp0(ipdevice->address, address) != 0) {
 +              /* If an original address is built-in physical device,
 +               * it's hardly get an address at a initial creation
 +               */
 +              g_free(ipdevice->address);
 +              ipdevice->address = g_strdup(address);
 +      }
 +#endif
 +
        ipdevice->mtu = mtu;
  
        update_stats(ipdevice, ifname, stats);
  
        g_list_free(ipconfig_copy);
  
-       if (lower_up)
-               __connman_ipconfig_lower_up(ipdevice);
-       if (lower_down)
-               __connman_ipconfig_lower_down(ipdevice);
  out:
        g_free(ifname);
  }
@@@ -651,8 -597,6 +611,6 @@@ void __connman_ipconfig_dellink(int ind
  
        g_free(ifname);
  
-       __connman_ipconfig_lower_down(ipdevice);
        g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
  }
  
@@@ -1103,32 -1047,16 +1061,32 @@@ void __connman_ipconfig_set_gateway(str
        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;
  
@@@ -1178,8 -1106,6 +1136,6 @@@ static struct connman_ipconfig *create_
        struct connman_ipconfig *ipv6config;
        struct connman_ipdevice *ipdevice;
  
-       DBG("index %d", index);
        ipv6config = g_try_new0(struct connman_ipconfig, 1);
        if (!ipv6config)
                return NULL;
        ipv6config->refcount = 1;
  
        ipv6config->index = index;
-       ipv6config->enabled = false;
        ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
  
        if (!is_ipv6_supported)
  
        ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
        if (ipdevice)
 +#if !defined TIZEN_EXT
                ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
 -
 +#else
 +              ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy = 2;
 +#endif
        ipv6config->address = connman_ipaddress_alloc(AF_INET6);
        if (!ipv6config->address) {
                g_free(ipv6config);
  
        ipv6config->system = connman_ipaddress_alloc(AF_INET6);
  
-       DBG("ipconfig %p method %s", ipv6config,
+       DBG("ipconfig %p index %d method %s", ipv6config, index,
                __connman_ipconfig_method2string(ipv6config->method));
  
        return ipv6config;
@@@ -1231,8 -1153,6 +1186,6 @@@ struct connman_ipconfig *__connman_ipco
        if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
                return create_ipv6config(index);
  
-       DBG("index %d", index);
        ipconfig = g_try_new0(struct connman_ipconfig, 1);
        if (!ipconfig)
                return NULL;
        ipconfig->refcount = 1;
  
        ipconfig->index = index;
-       ipconfig->enabled = false;
        ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
  
        ipconfig->address = connman_ipaddress_alloc(AF_INET);
  
        ipconfig->system = connman_ipaddress_alloc(AF_INET);
  
-       DBG("ipconfig %p", ipconfig);
+       DBG("ipconfig %p index %d", ipconfig, index);
  
        return ipconfig;
  }
@@@ -1384,8 -1303,6 +1336,6 @@@ enum connman_ipconfig_method __connman_
  
  int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig)
  {
-       DBG("");
        switch (ipconfig->method) {
        case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
        case CONNMAN_IPCONFIG_METHOD_OFF:
@@@ -1409,13 -1326,9 +1359,9 @@@ int __connman_ipconfig_address_remove(s
  {
        int err;
  
-       DBG("");
        if (!ipconfig)
                return 0;
  
-       DBG("method %d", ipconfig->method);
        switch (ipconfig->method) {
        case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
        case CONNMAN_IPCONFIG_METHOD_OFF:
@@@ -1437,17 -1350,9 +1383,15 @@@ int __connman_ipconfig_address_unset(st
  {
        int err;
  
-       DBG("");
        if (!ipconfig)
                return 0;
  
 +#if defined TIZEN_EXT
 +      DBG("ipconfig method %d type %d", ipconfig->method, ipconfig->type);
 +#else
 +      DBG("method %d", ipconfig->method);
 +#endif
 +
        switch (ipconfig->method) {
        case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
        case CONNMAN_IPCONFIG_METHOD_OFF:
@@@ -1478,8 -1383,6 +1422,6 @@@ int __connman_ipconfig_set_proxy_autoco
  {
        struct connman_ipdevice *ipdevice;
  
-       DBG("ipconfig %p", ipconfig);
        if (!ipconfig || ipconfig->index < 0)
                return -ENODEV;
  
@@@ -1498,8 -1401,6 +1440,6 @@@ const char *__connman_ipconfig_get_prox
  {
        struct connman_ipdevice *ipdevice;
  
-       DBG("ipconfig %p", ipconfig);
        if (!ipconfig || ipconfig->index < 0)
                return NULL;
  
@@@ -1652,8 -1553,6 +1592,6 @@@ int __connman_ipconfig_enable(struct co
        } else
                return -EINVAL;
  
-       ipconfig->enabled = true;
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
                                        ipdevice->config_ipv4) {
                ipconfig_list = g_list_remove(ipconfig_list,
@@@ -1728,8 -1627,6 +1666,6 @@@ int __connman_ipconfig_disable(struct c
        if (!ipdevice->config_ipv4 && !ipdevice->config_ipv6)
                return -EINVAL;
  
-       ipconfig->enabled = false;
        if (ipdevice->config_ipv4 == ipconfig) {
                ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
  
        if (ipdevice->config_ipv6 == ipconfig) {
                ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
  
 +#if defined TIZEN_EXT
 +              if (ipdevice->config_ipv6->method ==
 +                              CONNMAN_IPCONFIG_METHOD_AUTO)
 +                      disable_ipv6(ipdevice->config_ipv6);
 +#endif
                connman_ipaddress_clear(ipdevice->config_ipv6->system);
                __connman_ipconfig_unref(ipdevice->config_ipv6);
                ipdevice->config_ipv6 = NULL;
@@@ -1843,8 -1735,6 +1779,6 @@@ int __connman_ipconfig_ipv6_set_privacy
        if (!ipconfig)
                return -EINVAL;
  
-       DBG("ipconfig %p privacy %s", ipconfig, value);
        privacy = string2privacy(value);
  
        ipconfig->ipv6_privacy_config = privacy;
@@@ -1859,9 -1749,6 +1793,6 @@@ void __connman_ipconfig_append_ipv4(str
  {
        struct connman_ipaddress *append_addr = NULL;
        const char *str;
- #if defined TIZEN_EXT
-       DBG("");
- #endif
  
        if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
                return;
        switch (ipconfig->method) {
        case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
        case CONNMAN_IPCONFIG_METHOD_OFF:
-       case CONNMAN_IPCONFIG_METHOD_AUTO:
                return;
  
        case CONNMAN_IPCONFIG_METHOD_FIXED:
                append_addr = ipconfig->address;
                break;
  
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
        case CONNMAN_IPCONFIG_METHOD_DHCP:
                append_addr = ipconfig->system;
 +#if defined TIZEN_EXT
 +              /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
 +              if (append_addr && append_addr->local == NULL)
 +                      append_addr = ipconfig->address;
 +#endif
                break;
        }
  
        if (append_addr->gateway)
                connman_dbus_dict_append_basic(iter, "Gateway",
                                DBUS_TYPE_STRING, &append_addr->gateway);
 +
 +#if defined TIZEN_EXT
 +      if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_DHCP) {
 +              char *server_ip;
 +              server_ip = __connman_dhcp_get_server_address(ipconfig);
 +              if (server_ip) {
 +                      connman_dbus_dict_append_basic(iter, "DHCPServerIP",
 +                                      DBUS_TYPE_STRING, &server_ip);
 +                      g_free(server_ip);
 +              }
 +              connman_dbus_dict_append_basic(iter, "DHCPLeaseDuration",
 +                              DBUS_TYPE_INT32, &ipconfig->dhcp_lease_duration);
 +      }
 +#endif
  }
  
  void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
  {
        struct connman_ipaddress *append_addr = NULL;
        const char *str, *privacy;
- #if defined TIZEN_EXT
-       DBG("");
- #endif
  
        if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
                return;
        case CONNMAN_IPCONFIG_METHOD_DHCP:
        case CONNMAN_IPCONFIG_METHOD_AUTO:
                append_addr = ipconfig->system;
 +#if defined TIZEN_EXT
 +              /* TIZEN enables get_properties before __connman_ipconfig_newaddr */
 +              if (append_addr && append_addr->local == NULL)
 +                      append_addr = ipconfig->address;
 +#endif
                break;
        }
  
@@@ -2000,9 -1860,6 +1928,6 @@@ void __connman_ipconfig_append_ipv6conf
                                                        DBusMessageIter *iter)
  {
        const char *str, *privacy;
- #if !defined TIZEN_EXT
-       DBG("");
- #endif
  
        str = __connman_ipconfig_method2string(ipconfig->method);
        if (!str)
@@@ -2045,9 -1902,6 +1970,6 @@@ void __connman_ipconfig_append_ipv4conf
                                                        DBusMessageIter *iter)
  {
        const char *str;
- #if !defined TIZEN_EXT
-       DBG("");
- #endif
  
        str = __connman_ipconfig_method2string(ipconfig->method);
        if (!str)
@@@ -2099,8 -1953,6 +2021,6 @@@ int __connman_ipconfig_set_config(struc
        DBusMessageIter dict;
        int type = -1;
  
-       DBG("ipconfig %p", ipconfig);
        if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
                return -EINVAL;
  
  
        case CONNMAN_IPCONFIG_METHOD_OFF:
                ipconfig->method = method;
 -
 +#if defined TIZEN_EXT
 +              if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
 +                      disable_ipv6(ipconfig);
 +#endif
                break;
  
        case CONNMAN_IPCONFIG_METHOD_AUTO:
                ipconfig->method = method;
                if (privacy_string)
                        ipconfig->ipv6_privacy_config = privacy;
 -
 +#if defined TIZEN_EXT
 +              enable_ipv6(ipconfig);
 +#endif
                break;
  
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
@@@ -2375,6 -2222,20 +2295,20 @@@ int __connman_ipconfig_load(struct conn
                g_free(key);
                break;
  
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
+               if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
+                       break;
+               /*
+                * If the last used method for IPv4 was AUTO then we
+                * try first DHCP. We will try also to use the last
+                * used DHCP address, if exits.
+                */
+               __connman_ipconfig_set_method(ipconfig,
+                                       CONNMAN_IPCONFIG_METHOD_DHCP);
+               /* fall through */
        case CONNMAN_IPCONFIG_METHOD_DHCP:
  
                key = g_strdup_printf("%sDHCP.LastAddress", prefix);
                g_free(key);
  
                break;
-       case CONNMAN_IPCONFIG_METHOD_AUTO:
-               break;
        }
  
        return 0;
@@@ -2488,6 -2346,8 +2419,8 @@@ int __connman_ipconfig_save(struct conn
        if (ipconfig->address->gateway)
                g_key_file_set_string(keyfile, identifier,
                        key, ipconfig->address->gateway);
+       else
+               g_key_file_remove_key(keyfile, identifier, key, NULL);
        g_free(key);
  
        return 0;
diff --combined src/ippool.c
index bb8568d,cea1dcc..cea1dcc
mode 100755,100644..100755
@@@ -58,7 -58,6 +58,6 @@@ struct connman_ippool 
  };
  
  GSList *allocated_blocks;
- GHashTable *pool_hash;
  
  static uint32_t last_block;
  static uint32_t block_16_bits;
@@@ -90,7 -89,18 +89,18 @@@ void __connman_ippool_unref_debug(struc
        if (__sync_fetch_and_sub(&pool->refcount, 1) != 1)
                return;
  
-       g_hash_table_remove(pool_hash, pool);
+       if (pool->info) {
+               allocated_blocks = g_slist_remove(allocated_blocks, pool->info);
+               g_free(pool->info);
+       }
+       g_free(pool->gateway);
+       g_free(pool->broadcast);
+       g_free(pool->start_ip);
+       g_free(pool->end_ip);
+       g_free(pool->subnet_mask);
+       g_free(pool);
  }
  
  static char *get_ip(uint32_t ip)
@@@ -181,10 -191,10 +191,10 @@@ static uint32_t get_free_block(unsigne
         * To only thing we have to make sure is that we terminated if
         * there is no block left.
         */
-       if (last_block == 0)
-               block = block_16_bits;
+       if (last_block)
+               block = last_block;
        else
-               block = next_block(last_block);
+               block = block_16_bits;
  
        do {
                collision = false;
@@@ -393,7 -403,6 +403,6 @@@ struct connman_ippool *__connman_ippool
        pool->end_ip = get_ip(block + start + range);
  
        allocated_blocks = g_slist_prepend(allocated_blocks, info);
-       g_hash_table_insert(pool_hash, pool, pool);
  
        return pool;
  }
@@@ -423,24 -432,6 +432,6 @@@ const char *__connman_ippool_get_subnet
        return pool->subnet_mask;
  }
  
- static void pool_free(gpointer data)
- {
-       struct connman_ippool *pool = data;
-       if (pool->info) {
-               allocated_blocks = g_slist_remove(allocated_blocks, pool->info);
-               g_free(pool->info);
-       }
-       g_free(pool->gateway);
-       g_free(pool->broadcast);
-       g_free(pool->start_ip);
-       g_free(pool->end_ip);
-       g_free(pool->subnet_mask);
-       g_free(pool);
- }
  int __connman_ippool_init(void)
  {
        DBG("");
        block_24_bits = ntohl(inet_addr("10.0.0.0"));
        subnet_mask_24 = ntohl(inet_addr("255.255.255.0"));
  
-       pool_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
-                                       pool_free);
        return 0;
  }
  
@@@ -460,9 -448,6 +448,6 @@@ void __connman_ippool_cleanup(void
  {
        DBG("");
  
-       g_hash_table_destroy(pool_hash);
-       pool_hash = NULL;
        g_slist_free_full(allocated_blocks, g_free);
        last_block = 0;
        allocated_blocks = NULL;
diff --combined src/iptables.c
index a5774ad,5ef757a..aaddf9d
mode 100755,100644..100755
@@@ -31,6 -31,7 +31,7 @@@
  #include <sys/errno.h>
  #include <sys/socket.h>
  #include <xtables.h>
+ #include <inttypes.h>
  
  #include <linux/netfilter_ipv4/ip_tables.h>
  
@@@ -154,6 -155,7 +155,7 @@@ struct error_target 
  struct connman_iptables_entry {
        int offset;
        int builtin;
+       int counter_idx;
  
        struct ipt_entry *entry;
  };
@@@ -251,8 -253,9 +253,9 @@@ static int print_entry(struct ipt_entr
  {
        iterate_entries_cb_t cb = user_data;
  
-       DBG("entry %p  hook %d  offset %d  size %d", entry, hook,
-                       offset, entry->next_offset);
+       DBG("entry %p  hook %u  offset %u  size %u  packets %"PRIu64"  bytes %"PRIu64,
+                       entry, hook, offset, (unsigned int) entry->next_offset,
+                       (uint64_t) entry->counters.pcnt, (uint64_t) entry->counters.bcnt);
  
        return cb(entry, builtin, hook, size, offset, NULL);
  }
@@@ -460,7 -463,7 +463,7 @@@ static void update_targets_reference(st
  
  static int iptables_add_entry(struct connman_iptables *table,
                                struct ipt_entry *entry, GList *before,
-                                       int builtin)
+                                       int builtin, int counter_idx)
  {
        struct connman_iptables_entry *e, *entry_before;
  
  
        e->entry = entry;
        e->builtin = builtin;
+       e->counter_idx = counter_idx;
  
        table->entries = g_list_insert_before(table->entries, before, e);
        table->num_entries++;
@@@ -620,7 -624,7 +624,7 @@@ static int iptables_add_chain(struct co
        error->t.u.user.target_size = ALIGN(sizeof(struct error_target));
        g_stpcpy(error->error, name);
  
-       if (iptables_add_entry(table, entry_head, last, -1) < 0)
+       if (iptables_add_entry(table, entry_head, last, -1, -1) < 0)
                goto err_head;
  
        /* tail entry */
                                ALIGN(sizeof(struct ipt_standard_target));
        standard->verdict = XT_RETURN;
  
-       if (iptables_add_entry(table, entry_return, last, -1) < 0)
+       if (iptables_add_entry(table, entry_return, last, -1, -1) < 0)
                goto err;
  
        return 0;
@@@ -826,7 -830,7 +830,7 @@@ static int iptables_append_rule(struct 
        if (!new_entry)
                return -EINVAL;
  
-       ret = iptables_add_entry(table, new_entry, chain_tail->prev, builtin);
+       ret = iptables_add_entry(table, new_entry, chain_tail->prev, builtin, -1);
        if (ret < 0)
                g_free(new_entry);
  
@@@ -857,7 -861,7 +861,7 @@@ static int iptables_insert_rule(struct 
        if (builtin == -1)
                chain_head = chain_head->next;
  
-       ret = iptables_add_entry(table, new_entry, chain_head, builtin);
+       ret = iptables_add_entry(table, new_entry, chain_head, builtin, -1);
        if (ret < 0)
                g_free(new_entry);
  
@@@ -1128,6 -1132,8 +1132,8 @@@ static int iptables_change_policy(struc
        target = ipt_get_target(entry->entry);
  
        t = (struct xt_standard_target *)target;
+       if (t->verdict != verdict)
+               entry->counter_idx = -1;
        t->verdict = verdict;
  
        return 0;
@@@ -1405,6 -1411,19 +1411,19 @@@ static int iptables_replace(struct conn
        return 0;
  }
  
+ static int iptables_add_counters(struct connman_iptables *table,
+               struct xt_counters_info *c)
+ {
+       int err;
+       err = setsockopt(table->ipt_sock, IPPROTO_IP, IPT_SO_SET_ADD_COUNTERS, c,
+                       sizeof(*c) + sizeof(struct xt_counters) * c->num_counters);
+       if (err < 0)
+               return -errno;
+       return 0;
+ }
  static int add_entry(struct ipt_entry *entry, int builtin, unsigned int hook,
                        size_t size, unsigned offset, void *user_data)
  {
  
        memcpy(new_entry, entry, entry->next_offset);
  
-       return iptables_add_entry(table, new_entry, NULL, builtin);
+       return iptables_add_entry(table, new_entry, NULL, builtin,
+                       table->num_entries);
  }
  
  static void table_cleanup(struct connman_iptables *table)
@@@ -1748,6 -1768,7 +1768,7 @@@ struct parse_context 
        struct xtables_target *xt_t;
        GList *xt_m;
        struct xtables_rule_match *xt_rm;
+       int proto;
  };
  
  static int prepare_getopt_args(const char *str, struct parse_context *ctx)
@@@ -1787,6 -1808,14 +1808,14 @@@ static int parse_xt_modules(int c, boo
  {
        struct xtables_match *m;
        struct xtables_rule_match *rm;
+       struct ipt_entry fw;
+       memset(&fw, 0, sizeof(fw));
+       /* The SNAT parser wants to know the protocol. */
+       if (ctx->proto == 0)
+               ctx->proto = IPPROTO_IP;
+       fw.ip.proto = ctx->proto;
  
        for (rm = ctx->xt_rm; rm; rm = rm->next) {
                if (rm->completed != 0)
                                        + XT_OPTION_OFFSET_SCALE)
                        continue;
  
-               xtables_option_mpcall(c, ctx->argv, invert, m, NULL);
+               xtables_option_mpcall(c, ctx->argv, invert, m, &fw);
        }
  
        if (!ctx->xt_t)
                                        + XT_OPTION_OFFSET_SCALE)
                return 0;
  
-       xtables_option_tpcall(c, ctx->argv, invert, ctx->xt_t, NULL);
+       xtables_option_tpcall(c, ctx->argv, invert, ctx->xt_t, &fw);
  
        return 0;
  }
@@@ -1991,6 -2020,9 +2020,9 @@@ static int parse_rule_spec(struct connm
                        ctx->xt_m = g_list_append(ctx->xt_m, xt_m);
  
                        break;
+               case 'p':
+                       ctx->proto = xtables_parse_protocol(optarg);
+                       break;
                case 'j':
                        /* Target */
                        ctx->xt_t = prepare_target(table, optarg);
@@@ -2306,6 -2338,10 +2338,10 @@@ int __connman_iptables_commit(const cha
        struct connman_iptables *table;
        struct ipt_replace *repl;
        int err;
+       struct xt_counters_info *counters;
+       struct connman_iptables_entry *e;
+       GList *list;
+       unsigned int cnt;
  
        DBG("%s", table_name);
  
                return -EINVAL;
  
        repl = iptables_blob(table);
- #if defined TIZEN_EXT
 -      if (!repl)
 +      if(!repl)
                return -ENOMEM;
- #endif
  
        if (debug_enabled)
                dump_ipt_replace(repl);
  
        err = iptables_replace(table, repl);
  
-       g_free(repl->counters);
-       g_free(repl);
+       if (err < 0)
+               goto out_free;
+       counters = g_try_malloc0(sizeof(*counters) +
+                       sizeof(struct xt_counters) * table->num_entries);
+       if (!counters) {
+               err = -ENOMEM;
+               goto out_hash_remove;
+       }
+       g_stpcpy(counters->name, table->info->name);
+       counters->num_counters = table->num_entries;
+       for (list = table->entries, cnt = 0; list; list = list->next, cnt++) {
+               e = list->data;
+               if (e->counter_idx >= 0)
+                       counters->counters[cnt] = repl->counters[e->counter_idx];
+       }
+       err = iptables_add_counters(table, counters);
+       g_free(counters);
  
        if (err < 0)
-               return err;
+               goto out_hash_remove;
  
-       g_hash_table_remove(table_hash, table_name);
+       err = 0;
  
-       return 0;
+ out_hash_remove:
+       g_hash_table_remove(table_hash, table_name);
+ out_free:
+       g_free(repl->counters);
+       g_free(repl);
+       return err;
  }
  
  static void remove_table(gpointer user_data)
diff --combined src/log.c
index 32b35bc,9bae4a3..fa8ac31
mode 100755,100644..100755
+++ b/src/log.c
@@@ -30,7 -30,6 +30,7 @@@
  #include <stdlib.h>
  #include <string.h>
  #include <syslog.h>
 +#include <execinfo.h>
  #include <dlfcn.h>
  
  #include "connman.h"
  static const char *program_exec;
  static const char *program_path;
  
 +#if defined TIZEN_EXT
 +#include <sys/stat.h>
 +#include <sys/time.h>
 +
 +#define LOG_FILE_PATH "/opt/usr/data/network/connman.log"
 +#define MAX_LOG_SIZE  1 * 1024 * 1024
 +#define MAX_LOG_COUNT 1
 +
 +#define openlog __connman_log_open
 +#define closelog __connman_log_close
 +#define vsyslog __connman_log
 +#define syslog __connman_log_s
 +
 +static FILE *log_file = NULL;
 +
 +void __connman_log_open(const char *ident, int option, int facility)
 +{
 +      if (!log_file)
 +              log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
 +}
 +
 +void __connman_log_close(void)
 +{
 +      fclose(log_file);
 +      log_file = NULL;
 +}
 +
 +static void __connman_log_update_file_revision(int rev)
 +{
 +      int next_log_rev = 0;
 +      char *log_file = NULL;
 +      char *next_log_file = NULL;
 +
 +      next_log_rev = rev + 1;
 +
 +      log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev);
 +      next_log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, next_log_rev);
 +
 +      if (next_log_rev >= MAX_LOG_COUNT)
 +              remove(next_log_file);
 +
 +      if (access(next_log_file, F_OK) == 0)
 +              __connman_log_update_file_revision(next_log_rev);
 +
 +      if (rename(log_file, next_log_file) != 0)
 +              remove(log_file);
 +
 +      g_free(log_file);
 +      g_free(next_log_file);
 +}
 +
 +static void __connman_log_make_backup(void)
 +{
 +      const int rev = 0;
 +      char *backup = NULL;
 +
 +      backup = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev);
 +
 +      if (access(backup, F_OK) == 0)
 +              __connman_log_update_file_revision(rev);
 +
 +      if (rename(LOG_FILE_PATH, backup) != 0)
 +              remove(LOG_FILE_PATH);
 +
 +      g_free(backup);
 +}
 +
 +static void __connman_log_get_local_time(char *strtime, const int size)
 +{
 +      struct timeval tv;
 +      struct tm *local_ptm;
 +      char buf[32];
 +
 +      gettimeofday(&tv, NULL);
 +      local_ptm = localtime(&tv.tv_sec);
 +
 +      strftime(buf, sizeof(buf), "%m/%d %H:%M:%S", local_ptm);
 +      snprintf(strtime, size, "%s.%03ld", buf, tv.tv_usec / 1000);
 +}
 +
 +void __connman_log(const int log_priority, const char *format, va_list ap)
 +{
 +      int log_size = 0;
 +      struct stat buf;
 +      char str[256];
 +      char strtime[40];
 +
 +      if (!log_file)
 +              log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
 +
 +      if (!log_file)
 +              return;
 +
 +      fstat(fileno(log_file), &buf);
 +      log_size = buf.st_size;
 +
 +      if (log_size >= MAX_LOG_SIZE) {
 +              fclose(log_file);
 +              log_file = NULL;
 +
 +              __connman_log_make_backup();
 +
 +              log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
 +
 +              if (!log_file)
 +                      return;
 +      }
 +
 +      __connman_log_get_local_time(strtime, sizeof(strtime));
 +
 +      if (vsnprintf(str, sizeof(str), format, ap) > 0)
 +              fprintf(log_file, "%s %s\n", strtime, str);
 +}
 +
 +void __connman_log_s(int log_priority, const char *format, ...)
 +{
 +      va_list ap;
 +
 +      va_start(ap, format);
 +
 +      vsyslog(LOG_DEBUG, format, ap);
 +
 +      va_end(ap);
 +}
 +#endif
 +
  /**
   * connman_info:
   * @format: format string
@@@ -216,6 -89,6 +216,7 @@@ void connman_error(const char *format, 
        vsyslog(LOG_ERR, format, ap);
  
        va_end(ap);
++      fflush(log_file);
  }
  
  /**
@@@ -234,115 -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 --combined src/main.c
index 21ed25f,b78a046..4bc2266
mode 100755,100644..100755
@@@ -30,8 -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>
@@@ -59,6 -57,8 +59,8 @@@ static char *default_blacklist[] = 
        "vboxnet",
        "virbr",
        "ifb",
+       "ve-",
+       "vb-",
        NULL
  };
  
@@@ -67,6 -67,7 +69,7 @@@ static struct 
        char **pref_timeservers;
        unsigned int *auto_connect;
        unsigned int *preferred_techs;
+       unsigned int *always_connected_techs;
        char **fallback_nameservers;
        unsigned int timeout_inputreq;
        unsigned int timeout_browserlaunch;
        char **tethering_technologies;
        bool persistent_tethering_mode;
        bool enable_6to4;
+       char *vendor_class_id;
+       bool enable_online_check;
 +#if defined TIZEN_EXT
 +      char **cellular_interfaces;
 +      bool tizen_tv_extension;
 +#endif
  } connman_settings  = {
        .bg_scan = true,
        .pref_timeservers = NULL,
        .auto_connect = NULL,
        .preferred_techs = NULL,
+       .always_connected_techs = NULL,
        .fallback_nameservers = NULL,
        .timeout_inputreq = DEFAULT_INPUT_REQUEST_TIMEOUT,
        .timeout_browserlaunch = DEFAULT_BROWSER_LAUNCH_TIMEOUT,
        .tethering_technologies = NULL,
        .persistent_tethering_mode = false,
        .enable_6to4 = false,
+       .vendor_class_id = NULL,
+       .enable_online_check = true,
 +#if defined TIZEN_EXT
 +      .cellular_interfaces = NULL,
 +      .tizen_tv_extension = false,
 +#endif
  };
  
  #define CONF_BG_SCAN                    "BackgroundScanning"
  #define CONF_PREF_TIMESERVERS           "FallbackTimeservers"
  #define CONF_AUTO_CONNECT               "DefaultAutoConnectTechnologies"
+ #define CONF_ALWAYS_CONNECTED_TECHS     "AlwaysConnectedTechnologies"
  #define CONF_PREFERRED_TECHS            "PreferredTechnologies"
  #define CONF_FALLBACK_NAMESERVERS       "FallbackNameservers"
  #define CONF_TIMEOUT_INPUTREQ           "InputRequestTimeout"
  #define CONF_TETHERING_TECHNOLOGIES      "TetheringTechnologies"
  #define CONF_PERSISTENT_TETHERING_MODE  "PersistentTetheringMode"
  #define CONF_ENABLE_6TO4                "Enable6to4"
+ #define CONF_VENDOR_CLASS_ID            "VendorClassID"
+ #define CONF_ENABLE_ONLINE_CHECK        "EnableOnlineCheck"
 +#if defined TIZEN_EXT
 +#define CONF_CELLULAR_INTERFACE         "NetworkCellularInterfaceList"
 +#define CONF_TIZEN_TV_EXT             "TizenTVExtension"
 +#endif
  
  static const char *supported_options[] = {
        CONF_BG_SCAN,
        CONF_PREF_TIMESERVERS,
        CONF_AUTO_CONNECT,
+       CONF_ALWAYS_CONNECTED_TECHS,
        CONF_PREFERRED_TECHS,
        CONF_FALLBACK_NAMESERVERS,
        CONF_TIMEOUT_INPUTREQ,
        CONF_TETHERING_TECHNOLOGIES,
        CONF_PERSISTENT_TETHERING_MODE,
        CONF_ENABLE_6TO4,
 -      CONF_VENDOR_CLASS_ID,
+       CONF_ENABLE_ONLINE_CHECK,
 +#if defined TIZEN_EXT
 +      CONF_CELLULAR_INTERFACE,
 +      CONF_TIZEN_TV_EXT,
 +#endif
        NULL
  };
  
@@@ -250,46 -246,6 +263,46 @@@ static void check_config(GKeyFile *conf
        g_strfreev(keys);
  }
  
 +#if defined TIZEN_EXT
 +static void check_Tizen_configuration(GKeyFile *config)
 +{
 +      GError *error = NULL;
 +      char **cellular_interfaces;
 +      bool boolean;
 +      gsize len;
 +
 +      cellular_interfaces = g_key_file_get_string_list(config, "General",
 +                      CONF_CELLULAR_INTERFACE, &len, &error);
 +
 +      if (error == NULL)
 +              connman_settings.cellular_interfaces = cellular_interfaces;
 +
 +      g_clear_error(&error);
 +
 +      boolean = __connman_config_get_bool(config, "General",
 +                      CONF_TIZEN_TV_EXT, &error);
 +      if (!error)
 +              connman_settings.tizen_tv_extension = boolean;
 +
 +      g_clear_error(&error);
 +}
 +
 +static void set_nofile_inc(void)
 +{
 +      int err;
 +      struct rlimit rlim;
 +
 +      rlim.rlim_cur = 8192;
 +      rlim.rlim_max = 8192;
 +
 +      err = setrlimit(RLIMIT_NOFILE, &rlim);
 +      if (err)
 +              DBG("fail to increase FILENO err(%d)", err);
 +
 +      return;
 +}
 +#endif
 +
  static void parse_config(GKeyFile *config)
  {
        GError *error = NULL;
        char **interfaces;
        char **str_list;
        char **tethering;
+         char *vendor_class_id;
        gsize len;
        int timeout;
  
        g_clear_error(&error);
  
        str_list = __connman_config_get_string_list(config, "General",
+                       CONF_ALWAYS_CONNECTED_TECHS, &len, &error);
+       if (!error)
+               connman_settings.always_connected_techs =
+                       parse_service_types(str_list, len);
+       g_strfreev(str_list);
+       g_clear_error(&error);
+       str_list = __connman_config_get_string_list(config, "General",
                        CONF_FALLBACK_NAMESERVERS, &len, &error);
  
        if (!error)
  
        g_clear_error(&error);
  
+       vendor_class_id = __connman_config_get_string(config, "General",
+                                       CONF_VENDOR_CLASS_ID, &error);
+       if (!error)
+               connman_settings.vendor_class_id = vendor_class_id;
+       g_clear_error(&error);
+       boolean = __connman_config_get_bool(config, "General",
+                                       CONF_ENABLE_ONLINE_CHECK, &error);
+       if (!error) {
+               connman_settings.enable_online_check = boolean;
+               if (!boolean)
+                       connman_info("Online check disabled by main config.");
+       }
+       g_clear_error(&error);
++
 +#if defined TIZEN_EXT
 +      check_Tizen_configuration(config);
 +#endif
  }
  
  static int config_init(const char *file)
  {
        GKeyFile *config;
  
 +#if defined TIZEN_EXT
 +      set_nofile_inc();
 +#endif
        config = load_config(file);
        check_config(config);
        parse_config(config);
@@@ -539,10 -517,34 +581,34 @@@ static gboolean option_version = FALSE
  static bool parse_debug(const char *key, const char *value,
                                        gpointer user_data, GError **error)
  {
-       if (value)
-               option_debug = g_strdup(value);
-       else
+       if (value) {
+               if (option_debug) {
+                       char *prev = option_debug;
+                       option_debug = g_strconcat(prev, ",", value, NULL);
+                       g_free(prev);
+               } else {
+                       option_debug = g_strdup(value);
+               }
+       } else {
+               g_free(option_debug);
                option_debug = g_strdup("*");
+       }
+       return true;
+ }
+ static bool parse_noplugin(const char *key, const char *value,
+                                       gpointer user_data, GError **error)
+ {
+       if (option_noplugin) {
+               char *prev = option_noplugin;
+               option_noplugin = g_strconcat(prev, ",", value, NULL);
+               g_free(prev);
+       } else {
+               option_noplugin = g_strdup(value);
+       }
  
        return true;
  }
@@@ -560,7 -562,7 +626,7 @@@ static GOptionEntry options[] = 
                        "Specify networking interface to ignore", "DEV" },
        { "plugin", 'p', 0, G_OPTION_ARG_STRING, &option_plugin,
                                "Specify plugins to load", "NAME,..." },
-       { "noplugin", 'P', 0, G_OPTION_ARG_STRING, &option_noplugin,
+       { "noplugin", 'P', 0, G_OPTION_ARG_CALLBACK, &parse_noplugin,
                                "Specify plugins not to load", "NAME,..." },
        { "wifi", 'W', 0, G_OPTION_ARG_STRING, &option_wifi,
                                "Specify driver for WiFi/Supplicant", "NAME" },
  
  const char *connman_option_get_string(const char *key)
  {
+       if (g_str_equal(key, CONF_VENDOR_CLASS_ID))
+               return connman_settings.vendor_class_id;
        if (g_strcmp0(key, "wifi") == 0) {
                if (!option_wifi)
                        return "nl80211,wext";
@@@ -607,6 -612,9 +676,9 @@@ bool connman_setting_get_bool(const cha
        if (g_str_equal(key, CONF_ENABLE_6TO4))
                return connman_settings.enable_6to4;
  
+       if (g_str_equal(key, CONF_ENABLE_ONLINE_CHECK))
+               return connman_settings.enable_online_check;
        return false;
  }
  
@@@ -624,11 -632,6 +696,11 @@@ char **connman_setting_get_string_list(
        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;
  }
  
@@@ -640,6 -643,9 +712,9 @@@ unsigned int *connman_setting_get_uint_
        if (g_str_equal(key, CONF_PREFERRED_TECHS))
                return connman_settings.preferred_techs;
  
+       if (g_str_equal(key, CONF_ALWAYS_CONNECTED_TECHS))
+               return connman_settings.always_connected_techs;
        return NULL;
  }
  
@@@ -737,7 -743,6 +812,6 @@@ int main(int argc, char *argv[]
        __connman_device_init(option_device, option_nodevice);
  
        __connman_ippool_init();
-       __connman_iptables_init();
        __connman_firewall_init();
        __connman_nat_init();
        __connman_tethering_init();
        __connman_stats_init();
        __connman_clock_init();
  
-       __connman_resolver_init(option_dnsproxy);
        __connman_ipconfig_init();
        __connman_rtnl_init();
        __connman_task_init();
  
        __connman_plugin_init(option_plugin, option_noplugin);
  
+       __connman_resolver_init(option_dnsproxy);
        __connman_rtnl_start();
        __connman_dhcp_init();
        __connman_dhcpv6_init();
        __connman_wpad_init();
        __connman_wispr_init();
 +#if !defined TIZEN_EXT
        __connman_rfkill_init();
        __connman_machine_init();
 +#endif
  
        g_free(option_config);
        g_free(option_device);
  
        g_source_remove(signal);
  
 +#if !defined TIZEN_EXT
        __connman_machine_cleanup();
        __connman_rfkill_cleanup();
 +#endif
        __connman_wispr_cleanup();
        __connman_wpad_cleanup();
        __connman_dhcpv6_cleanup();
        __connman_tethering_cleanup();
        __connman_nat_cleanup();
        __connman_firewall_cleanup();
-       __connman_iptables_cleanup();
        __connman_peer_service_cleanup();
        __connman_peer_cleanup();
        __connman_ippool_cleanup();
diff --combined src/main.conf
index d0edbdf,68870b2..a2cc1e2
mode 100755,100644..100755
@@@ -19,7 -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
@@@ -27,7 -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
  # the default route when compared to either a non-preferred
  # type or a preferred type further down in the list.
  # PreferredTechnologies =
 +PreferredTechnologies = wifi, ethernet
  
  # List of blacklisted network interfaces separated by ",".
  # Found interfaces will be compared to the list and will
  # not be handled by connman, if their first characters
  # match any of the list entries. Default value is
- # vmnet,vboxnet,virbr,ifb.
- # NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb
+ # vmnet,vboxnet,virbr,ifb,ve-,vb-.
+ # NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,ve-,vb-
 +NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w
  
  # Allow connman to change the system hostname. This can
  # happen for example if we receive DHCP hostname option.
@@@ -80,7 -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
  # section 4.1).
  # Enable6to4 = false
  
+ # Enable use of http get as on online status check.
+ # When a service is in a READY state, and is selected as default,
+ # ConnMan will issue an HTTP GET request to verify that end-to-end
+ # connectivity is successful. Only then the service will be
+ # transitioned to ONLINE state.
+ # If this setting is false, the default service will remain in READY state.
+ # Default value is true.
+ # EnableOnlineCheck = false
+ # List of technologies with AutoConnect = true which are always connected
+ # regardless of PreferredTechnologies setting. Default value is empty and
+ # will connect a technology only if it is at a higher preference than any
+ # other which is already connected.
+ # This setting has no effect if SingleConnectedTechnologies is enabled.
+ # AlwaysConnectedTechnologies =
++
 +NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w
diff --combined src/nat.c
index 063f085,fb55710..fb55710
mode 100755,100644..100755
+++ b/src/nat.c
  #endif
  
  #include <errno.h>
- #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
  
  #include "connman.h"
  
@@@ -42,46 -45,52 +45,52 @@@ struct connman_nat 
  
  static int enable_ip_forward(bool enable)
  {
-       FILE *f;
+       static char value = 0;
+       int f, err = 0;
  
-       f = fopen("/proc/sys/net/ipv4/ip_forward", "r+");
-       if (!f)
+       if ((f = open("/proc/sys/net/ipv4/ip_forward", O_CLOEXEC | O_RDWR)) < 0)
                return -errno;
  
-       if (enable)
-               fprintf(f, "1");
-       else
-               fprintf(f, "0");
+       if (!value) {
+               if (read(f, &value, sizeof(value)) < 0)
+                       value = 0;
  
-       fclose(f);
+               if (lseek(f, 0, SEEK_SET) < 0)
+                       return -errno;
+       }
+       if (enable) {
+               char allow = '1';
+               if (write (f, &allow, sizeof(allow)) < 0)
+                       err = -errno;
+       } else {
+               char deny = '0';
+               if (value)
+                       deny = value;
+               if (write(f, &deny, sizeof(deny)) < 0)
+                       err = -errno;
+               value = 0;
+       }
+       close(f);
  
-       return 0;
+       return err;
  }
  
  static int enable_nat(struct connman_nat *nat)
  {
-       char *cmd;
-       int err;
        g_free(nat->interface);
        nat->interface = g_strdup(default_interface);
  
        if (!nat->interface)
                return 0;
  
-       /* Enable masquerading */
-       cmd = g_strdup_printf("-s %s/%d -o %s -j MASQUERADE",
-                                       nat->address,
-                                       nat->prefixlen,
-                                       nat->interface);
-       err = __connman_firewall_add_rule(nat->fw, "nat",
-                               "POSTROUTING", cmd);
-       g_free(cmd);
-       if (err < 0)
-               return err;
-       return __connman_firewall_enable(nat->fw);
+       return __connman_firewall_enable_nat(nat->fw, nat->address,
+                                       nat->prefixlen, nat->interface);
  }
  
  static void disable_nat(struct connman_nat *nat)
@@@ -89,8 -98,7 +98,7 @@@
        if (!nat->interface)
                return;
  
-       /* Disable masquerading */
-       __connman_firewall_disable(nat->fw);
+       __connman_firewall_disable_nat(nat->fw);
  }
  
  int __connman_nat_enable(const char *name, const char *address,
diff --combined src/network.c
index f7a9925,ed56210..d38fc0a
mode 100755,100644..100755
   */
  #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;
  
@@@ -90,8 -78,13 +90,13 @@@ struct connman_network 
                char *passphrase;
                char *eap;
                char *identity;
+               char *anonymous_identity;
                char *agent_identity;
                char *ca_cert_path;
+               char *subject_match;
+               char *altsubject_match;
+               char *domain_suffix_match;
+               char *domain_match;
                char *client_cert_path;
                char *private_key_path;
                char *private_key_passphrase;
                bool wps;
                bool use_wps;
                char *pin_wps;
-               GSList *vsie_list;
 +#if defined TIZEN_EXT
 +              char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX];
 +              unsigned char bssid[WIFI_BSSID_LEN_MAX];
 +              unsigned int maxrate;
 +              bool isHS20AP;
 +              unsigned int keymgmt;
 +              char *keymgmt_type;
 +              bool rsn_mode;
 +              int disconnect_reason;
 +              int assoc_status_code;
++              void *wifi_vsie;
++              unsigned int wifi_vsie_len;
 +#endif
        } wifi;
  
 +#if defined TIZEN_EXT
 +      /* Multiple APN services and a default APN which a user selected */
 +      bool default_internet;
 +#endif
 +
  };
  
  static const char *type2string(enum connman_network_type type)
@@@ -164,8 -140,6 +170,6 @@@ static void set_configuration(struct co
  
        __connman_device_set_network(network->device, network);
  
-       connman_device_set_disconnected(network->device, false);
        service = connman_service_lookup_from_network(network);
        __connman_service_ipconfig_indicate_state(service,
                                        CONNMAN_SERVICE_STATE_CONFIGURATION,
@@@ -193,14 -167,12 +197,16 @@@ static void dhcp_success(struct connman
        if (err < 0)
                goto err;
  
 +#if defined TIZEN_EXT
 +      err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
 +#else
        err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
 +#endif
        if (err < 0)
                goto err;
  
+       __connman_service_save(service);
        return;
  
  err:
@@@ -251,8 -223,8 +257,8 @@@ static int set_connected_manual(struct 
        network->connecting = false;
  
        service = connman_service_lookup_from_network(network);
        ipconfig = __connman_service_get_ip4config(service);
+       __connman_ipconfig_enable(ipconfig);
  
        if (!__connman_ipconfig_get_local(ipconfig))
                __connman_service_read_ip4config(service);
        if (err < 0)
                goto err;
  
 +#if defined TIZEN_EXT
 +      err = __connman_ipconfig_gateway_add(ipconfig, service);
 +#else
        err = __connman_ipconfig_gateway_add(ipconfig);
 +#endif
        if (err < 0)
                goto err;
  
@@@ -283,6 -251,7 +289,7 @@@ static int set_connected_dhcp(struct co
  
        service = connman_service_lookup_from_network(network);
        ipconfig_ipv4 = __connman_service_get_ip4config(service);
+       __connman_ipconfig_enable(ipconfig_ipv4);
  
        err = __connman_dhcp_start(ipconfig_ipv4, network,
                                                        dhcp_callback, NULL);
@@@ -318,21 -287,12 +325,16 @@@ static int manual_ipv6_set(struct connm
                return err;
        }
  
 +#if defined TIZEN_EXT
 +      err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service);
 +#else
        err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
 +#endif
        if (err < 0)
                return err;
  
-       __connman_connection_gateway_activate(service,
-                                               CONNMAN_IPCONFIG_TYPE_IPV6);
        __connman_device_set_network(network->device, network);
  
-       connman_device_set_disconnected(network->device, false);
        connman_network_set_associating(network, false);
  
        network->connecting = false;
@@@ -467,13 -427,10 +469,13 @@@ static void check_dhcpv6(struct nd_rout
                        DBG("re-send router solicitation %d",
                                                network->router_solicit_count);
                        network->router_solicit_count--;
 -                      __connman_inet_ipv6_send_rs(network->index, 1,
 +                      __connman_inet_ipv6_send_rs(network->index, RTR_SOLICITATION_INTERVAL,
                                                check_dhcpv6, network);
                        return;
                }
 +#if defined TIZEN_EXT
 +              DBG("RA message is not received from server in reply of RS.");
 +#endif
                connman_network_unref(network);
                return;
        }
         */
        if (!network->connected) {
                connman_network_unref(network);
 +#if defined TIZEN_EXT
 +              DBG("Network is not connected");
 +#endif
                return;
        }
  
         * We do stateful/stateless DHCPv6 if router advertisement says so.
         */
        if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) {
 +#if defined TIZEN_EXT
 +              DBG("IPv6 ND_RA_FLAG_MANAGED");
 +#endif
                __connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
        } else {
                if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
 +#if defined TIZEN_EXT
 +              {
 +                      DBG("IPv6 ND_RA_FLAG_OTHER");
 +#endif
                        __connman_dhcpv6_start_info(network,
                                                        dhcpv6_info_callback);
 +#if defined TIZEN_EXT
 +              }
 +#endif
  
                g_slist_free_full(prefixes, g_free);
                network->connecting = false;
@@@ -613,13 -557,6 +615,11 @@@ static void autoconf_ipv6_set(struct co
  
        __connman_device_set_network(network->device, network);
  
-       connman_device_set_disconnected(network->device, false);
 +#if defined TIZEN_EXT
 +      if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
 +              return;
 +#endif
 +
        service = connman_service_lookup_from_network(network);
        if (!service)
                return;
        if (!ipconfig)
                return;
  
+       __connman_ipconfig_enable(ipconfig);
        __connman_ipconfig_enable_ipv6(ipconfig);
  
        __connman_ipconfig_address_remove(ipconfig);
  
        /* Try to get stateless DHCPv6 information, RFC 3736 */
        network->router_solicit_count = 3;
 -      __connman_inet_ipv6_send_rs(index, 1, check_dhcpv6, network);
 +      __connman_inet_ipv6_send_rs(index, RTR_SOLICITATION_INTERVAL,
 +                      check_dhcpv6, network);
  }
  
  static void set_connected(struct connman_network *network)
@@@ -710,10 -648,20 +712,20 @@@ static void set_disconnected(struct con
                switch (ipv4_method) {
                case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
                case CONNMAN_IPCONFIG_METHOD_OFF:
-               case CONNMAN_IPCONFIG_METHOD_AUTO:
                case CONNMAN_IPCONFIG_METHOD_FIXED:
                case CONNMAN_IPCONFIG_METHOD_MANUAL:
                        break;
+               case CONNMAN_IPCONFIG_METHOD_AUTO:
+                       /*
+                        * If the current method is AUTO then next time we
+                        * try first DHCP. DHCP also needs to be stopped
+                        * in this case because if we fell in AUTO means
+                        * that DHCP  was launched for IPv4 but it failed.
+                        */
+                       __connman_ipconfig_set_method(ipconfig_ipv4,
+                                               CONNMAN_IPCONFIG_METHOD_DHCP);
+                       __connman_service_notify_ipv4_configuration(service);
+                       /* fall through */
                case CONNMAN_IPCONFIG_METHOD_DHCP:
                        __connman_dhcp_stop(ipconfig_ipv4);
                        break;
                                        CONNMAN_IPCONFIG_TYPE_IPV6);
  
        if (network->connected) {
 +#if defined TIZEN_EXT
 +              /**
 +               * Do not remove gateway and its address,
 +               * if there are connected profiles that use same interface (multiple PDN)
 +               */
 +              if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_CELLULAR ||
 +                              __connman_service_get_connected_count_of_iface(service) <= 0) {
 +#endif
                __connman_connection_gateway_remove(service,
                                                CONNMAN_IPCONFIG_TYPE_ALL);
  
                __connman_ipconfig_address_unset(ipconfig_ipv4);
                __connman_ipconfig_address_unset(ipconfig_ipv6);
 -
 +#if defined TIZEN_EXT
 +              }
 +#endif
                /*
                 * Special handling for IPv6 autoconfigured address.
                 * The simplest way to remove autoconfigured routes is to
@@@ -895,20 -833,6 +907,6 @@@ static void probe_driver(struct connman
        }
  }
  
- static void remove_driver(struct connman_network_driver *driver)
- {
-       GSList *list;
-       DBG("driver %p name %s", driver, driver->name);
-       for (list = network_list; list; list = list->next) {
-               struct connman_network *network = list->data;
-               if (network->driver == driver)
-                       network_remove(network);
-       }
- }
  static gint compare_priority(gconstpointer a, gconstpointer b)
  {
        const struct connman_network_driver *driver1 = a;
@@@ -945,11 -869,18 +943,18 @@@ int connman_network_driver_register(str
   */
  void connman_network_driver_unregister(struct connman_network_driver *driver)
  {
+       GSList *list;
        DBG("driver %p name %s", driver, driver->name);
  
        driver_list = g_slist_remove(driver_list, driver);
  
-       remove_driver(driver);
+       for (list = network_list; list; list = list->next) {
+               struct connman_network *network = list->data;
+               if (network->driver == driver)
+                       network_remove(network);
+       }
  }
  
  static void network_destruct(struct connman_network *network)
        g_free(network->wifi.passphrase);
        g_free(network->wifi.eap);
        g_free(network->wifi.identity);
+       g_free(network->wifi.anonymous_identity);
        g_free(network->wifi.agent_identity);
        g_free(network->wifi.ca_cert_path);
+       g_free(network->wifi.subject_match);
+       g_free(network->wifi.altsubject_match);
+       g_free(network->wifi.domain_suffix_match);
+       g_free(network->wifi.domain_match);
        g_free(network->wifi.client_cert_path);
        g_free(network->wifi.private_key_path);
        g_free(network->wifi.private_key_passphrase);
        g_free(network->wifi.phase2_auth);
        g_free(network->wifi.pin_wps);
 -
 +#if defined TIZEN_EXT
-       g_slist_free_full(network->wifi.vsie_list, g_free);
++      g_free(network->wifi.wifi_vsie);
 +#endif
        g_free(network->path);
        g_free(network->group);
        g_free(network->node);
@@@ -997,14 -931,10 +1007,10 @@@ struct connman_network *connman_network
        struct connman_network *network;
        char *ident;
  
-       DBG("identifier %s type %d", identifier, type);
        network = g_try_new0(struct connman_network, 1);
        if (!network)
                return NULL;
  
-       DBG("network %p", network);
        network->refcount = 1;
  
        ident = g_strdup(identifier);
  
        network_list = g_slist_prepend(network_list, network);
  
+       DBG("network %p identifier %s type %s", network, identifier,
+               type2string(type));
        return network;
  }
  
@@@ -1215,15 -1147,6 +1223,15 @@@ bool __connman_network_get_weakness(str
        return false;
  }
  
 +#if defined TIZEN_EXT
 +void connman_network_set_connecting(struct connman_network *network)
 +{
 +      DBG("set network connecting true");
 +      network->connecting = TRUE;
 +      return;
 +}
 +#endif
 +
  bool connman_network_get_connecting(struct connman_network *network)
  {
        return network->connecting;
  int connman_network_set_available(struct connman_network *network,
                                                bool available)
  {
 +#if !defined TIZEN_EXT
        DBG("network %p available %d", network, available);
 +#endif
  
        if (network->available == available)
                return -EALREADY;
@@@ -1262,113 -1183,6 +1270,113 @@@ bool connman_network_get_available(stru
        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
@@@ -1398,14 -1212,6 +1406,14 @@@ int connman_network_set_associating(str
                                        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;
  }
  
@@@ -1415,13 -1221,8 +1423,13 @@@ static void set_associate_error(struct 
  
        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)
@@@ -1440,10 -1241,6 +1448,10 @@@ static void set_invalid_key_error(struc
  
        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);
  }
@@@ -1468,22 -1265,6 +1476,22 @@@ static void set_blocked_error(struct co
                                        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)
  {
@@@ -1538,16 -1319,9 +1546,16 @@@ void connman_network_set_error(struct c
        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);
@@@ -1687,21 -1461,13 +1695,21 @@@ int __connman_network_connect(struct co
  
        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;
@@@ -1732,9 -1498,7 +1740,9 @@@ int __connman_network_disconnect(struc
                return -EUNATCH;
  
        network->connecting = false;
 -
 +#if defined TIZEN_EXT
 +      DBG("ConnMan, Disconnect request");
 +#endif
        if (network->driver->disconnect)
                err = network->driver->disconnect(network);
  
@@@ -1788,38 -1552,12 +1796,38 @@@ int __connman_network_clear_ipconfig(st
        return 0;
  }
  
 +#if defined TIZEN_EXT
 +void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data)
 +{
 +      DBG("");
 +
 +      struct connman_network *network = user_data;
 +      struct connman_service *service;
 +      struct connman_ipconfig *ipconfig = NULL;
 +
 +      service = connman_service_lookup_from_network(network);
 +      if (service == NULL)
 +              return;
 +
 +      ipconfig = __connman_service_get_ipconfig(service, AF_INET6);
 +      if (ipconfig == NULL)
 +              return;
 +
 +      __connman_ipconfig_set_gateway(ipconfig, gateway);
 +
 +      return;
 +}
 +#endif
 +
  int __connman_network_enable_ipconfig(struct connman_network *network,
                                struct connman_ipconfig *ipconfig)
  {
        int r = 0;
        enum connman_ipconfig_type type;
        enum connman_ipconfig_method method;
 +#if defined TIZEN_EXT
 +      struct connman_service *service;
 +#endif
  
        if (!network || !ipconfig)
                return -EINVAL;
                        break;
  
                case CONNMAN_IPCONFIG_METHOD_AUTO:
 +#if defined TIZEN_EXT
 +              service = connman_service_lookup_from_network(network);
 +
 +              if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
 +                      __connman_service_ipconfig_indicate_state(service,
 +                              CONNMAN_SERVICE_STATE_CONFIGURATION,
 +                                      CONNMAN_IPCONFIG_TYPE_IPV6);
 +#endif
                        autoconf_ipv6_set(network);
                        break;
  
@@@ -1931,155 -1661,6 +1939,142 @@@ int connman_network_set_ipaddress(struc
        return 0;
  }
  
- int connman_network_set_assoc_status_code(struct connman_network *network,
-                               int assoc_status_code)
- {
-       if (network == NULL)
-               return 0;
-       network->wifi.assoc_status_code = assoc_status_code;
-       return 0;
- }
 +#if defined TIZEN_EXT
 +/*
 + * Description: Network client requires additional wifi specific info
 + */
 +int connman_network_set_bssid(struct connman_network *network,
 +                              const unsigned char *bssid)
 +{
 +      int i = 0;
 +
 +      if (bssid == NULL)
 +              return -EINVAL;
 +
 +      DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
 +                      bssid[0], bssid[1], bssid[2],
 +                      bssid[3], bssid[4], bssid[5]);
 +
 +      for (;i < WIFI_BSSID_LEN_MAX;i++)
 +              network->wifi.bssid[i] = bssid[i];
 +
 +      return 0;
 +}
 +
 +unsigned char *connman_network_get_bssid(struct connman_network *network)
 +{
 +      return (unsigned char *)network->wifi.bssid;
 +}
 +
 +int connman_network_set_maxrate(struct connman_network *network,
 +                              unsigned int maxrate)
 +{
 +#if !defined TIZEN_EXT
 +      DBG("network %p maxrate %d", network, maxrate);
 +#endif
 +
 +      network->wifi.maxrate = maxrate;
 +
 +      return 0;
 +}
 +
 +unsigned int connman_network_get_maxrate(struct connman_network *network)
 +{
 +      return network->wifi.maxrate;
 +}
 +
 +int connman_network_set_enc_mode(struct connman_network *network,
 +                              const char *encryption_mode)
 +{
 +      if (encryption_mode == NULL)
 +              return -EINVAL;
 +
 +      DBG("network %p encryption mode %s", network, encryption_mode);
 +
 +      g_strlcpy(network->wifi.encryption_mode, encryption_mode,
 +                                      WIFI_ENCYPTION_MODE_LEN_MAX);
 +
 +      return 0;
 +}
 +
 +const char *connman_network_get_enc_mode(struct connman_network *network)
 +{
 +      return (const char *)network->wifi.encryption_mode;
 +}
 +
 +int connman_network_set_rsn_mode(struct connman_network *network,
 +                              bool rsn_mode)
 +{
 +      network->wifi.rsn_mode = rsn_mode;
 +
 +      return 0;
 +}
 +
 +int connman_network_set_proxy(struct connman_network *network,
 +                              const char *proxies)
 +{
 +      struct connman_service *service;
 +
 +      DBG("network %p proxies %s", network, proxies);
 +
 +      service = connman_service_lookup_from_network(network);
 +      if (service == NULL)
 +              return -EINVAL;
 +
 +      __connman_service_set_proxy(service, proxies);
 +
 +      connman_service_set_proxy_method(service,
 +                              CONNMAN_SERVICE_PROXY_METHOD_MANUAL);
 +
 +      return 0;
 +}
 +
 +int connman_network_set_keymgmt(struct connman_network *network,
 +                              unsigned int keymgmt)
 +{
 +      if (network == NULL)
 +              return 0;
 +
 +      network->wifi.keymgmt = keymgmt;
 +
 +      return 0;
 +}
 +
 +unsigned int connman_network_get_keymgmt(struct connman_network *network)
 +{
 +      if (network == NULL)
 +              return 0;
 +
 +      return network->wifi.keymgmt;
 +}
 +
 +int connman_network_set_disconnect_reason(struct connman_network *network,
 +                              int reason_code)
 +{
 +      if (network == NULL)
 +              return 0;
 +
 +      network->wifi.disconnect_reason = reason_code;
 +
 +      return 0;
 +}
 +
 +int connman_network_get_disconnect_reason(struct connman_network *network)
 +{
 +      if (network == NULL)
 +              return 0;
 +
 +      return network->wifi.disconnect_reason;
 +}
 +int connman_network_get_assoc_status_code(struct connman_network *network)
 +{
 +      if (network == NULL)
 +              return 0;
 +
 +      return network->wifi.assoc_status_code;
 +}
 +#endif
 +
  int connman_network_set_nameservers(struct connman_network *network,
                                const char *nameservers)
  {
        nameservers_array = g_strsplit(nameservers, " ", 0);
  
        for (i = 0; nameservers_array[i]; i++) {
 +#if defined TIZEN_EXT
 +              __connman_service_nameserver_append(service,
 +                                              nameservers_array[i], false,
 +                                              CONNMAN_IPCONFIG_TYPE_ALL);
 +#else
                __connman_service_nameserver_append(service,
                                                nameservers_array[i], false);
 +#endif
        }
  
        g_strfreev(nameservers_array);
@@@ -2161,10 -1736,6 +2156,6 @@@ int connman_network_set_name(struct con
  int connman_network_set_strength(struct connman_network *network,
                                                uint8_t strength)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p strengh %d", network, strength);
- #endif
        network->strength = strength;
  
        return 0;
@@@ -2178,10 -1749,6 +2169,6 @@@ uint8_t connman_network_get_strength(st
  int connman_network_set_frequency(struct connman_network *network,
                                                uint16_t frequency)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p frequency %d", network, frequency);
- #endif
        network->frequency = frequency;
  
        return 0;
@@@ -2195,8 -1762,6 +2182,6 @@@ uint16_t connman_network_get_frequency(
  int connman_network_set_wifi_channel(struct connman_network *network,
                                                uint16_t channel)
  {
-       DBG("network %p wifi channel %d", network, channel);
        network->wifi.channel = channel;
  
        return 0;
@@@ -2218,10 -1783,6 +2203,6 @@@ uint16_t connman_network_get_wifi_chann
  int connman_network_set_string(struct connman_network *network,
                                        const char *key, const char *value)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p key %s value %s", network, key, value);
- #endif
        if (g_strcmp0(key, "Name") == 0)
                return connman_network_set_name(network, value);
  
                g_free(network->wifi.security);
                network->wifi.security = g_strdup(value);
        } else if (g_str_equal(key, "WiFi.Passphrase")) {
 +#if defined TIZEN_EXT
 +              DBG("ConnMan, %p key %s", network, key);
 +#endif
                g_free(network->wifi.passphrase);
                network->wifi.passphrase = g_strdup(value);
        } else if (g_str_equal(key, "WiFi.EAP")) {
        } else if (g_str_equal(key, "WiFi.Identity")) {
                g_free(network->wifi.identity);
                network->wifi.identity = g_strdup(value);
+       } else if (g_str_equal(key, "WiFi.AnonymousIdentity")) {
+               g_free(network->wifi.anonymous_identity);
+               network->wifi.anonymous_identity = g_strdup(value);
        } else if (g_str_equal(key, "WiFi.AgentIdentity")) {
                g_free(network->wifi.agent_identity);
                network->wifi.agent_identity = g_strdup(value);
        } else if (g_str_equal(key, "WiFi.CACertFile")) {
                g_free(network->wifi.ca_cert_path);
                network->wifi.ca_cert_path = g_strdup(value);
+       } else if (g_str_equal(key, "WiFi.SubjectMatch")) {
+               g_free(network->wifi.subject_match);
+               network->wifi.subject_match = g_strdup(value);
+       } else if (g_str_equal(key, "WiFi.AltSubjectMatch")) {
+               g_free(network->wifi.altsubject_match);
+               network->wifi.altsubject_match = g_strdup(value);
+       } else if (g_str_equal(key, "WiFi.DomainSuffixMatch")) {
+               g_free(network->wifi.domain_suffix_match);
+               network->wifi.domain_suffix_match = g_strdup(value);
+       } else if (g_str_equal(key, "WiFi.DomainMatch")) {
+               g_free(network->wifi.domain_match);
+               network->wifi.domain_match = g_strdup(value);
        } else if (g_str_equal(key, "WiFi.ClientCertFile")) {
                g_free(network->wifi.client_cert_path);
                network->wifi.client_cert_path = g_strdup(value);
  const char *connman_network_get_string(struct connman_network *network,
                                                        const char *key)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p key %s", network, key);
- #endif
        if (g_str_equal(key, "Path"))
                return network->path;
        else if (g_str_equal(key, "Name"))
        else if (g_str_equal(key, "WiFi.Mode"))
                return network->wifi.mode;
        else if (g_str_equal(key, "WiFi.Security"))
 +#if defined TIZEN_EXT
 +              if (network->wifi.rsn_mode != true ||
 +                  g_str_equal(network->wifi.security, "ieee8021x"))
 +                      return network->wifi.security;
 +              else
 +                      return "rsn";
 +#else
                return network->wifi.security;
 +#endif
        else if (g_str_equal(key, "WiFi.Passphrase"))
                return network->wifi.passphrase;
        else if (g_str_equal(key, "WiFi.EAP"))
                return network->wifi.eap;
        else if (g_str_equal(key, "WiFi.Identity"))
                return network->wifi.identity;
+       else if (g_str_equal(key, "WiFi.AnonymousIdentity"))
+               return network->wifi.anonymous_identity;
        else if (g_str_equal(key, "WiFi.AgentIdentity"))
                return network->wifi.agent_identity;
        else if (g_str_equal(key, "WiFi.CACertFile"))
                return network->wifi.ca_cert_path;
+       else if (g_str_equal(key, "WiFi.SubjectMatch"))
+               return network->wifi.subject_match;
+       else if (g_str_equal(key, "WiFi.AltSubjectMatch"))
+               return network->wifi.altsubject_match;
+       else if (g_str_equal(key, "WiFi.DomainSuffixMatch"))
+               return network->wifi.domain_suffix_match;
+       else if (g_str_equal(key, "WiFi.DomainMatch"))
+               return network->wifi.domain_match;
        else if (g_str_equal(key, "WiFi.ClientCertFile"))
                return network->wifi.client_cert_path;
        else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
  int connman_network_set_bool(struct connman_network *network,
                                        const char *key, bool value)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p key %s value %d", network, key, value);
- #endif
        if (g_strcmp0(key, "Roaming") == 0)
                network->roaming = value;
        else if (g_strcmp0(key, "WiFi.WPS") == 0)
                network->wifi.wps = value;
        else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
                network->wifi.use_wps = value;
 +#if defined TIZEN_EXT
 +      else if (g_strcmp0(key, "DefaultInternet") == 0)
 +              network->default_internet = value;
 +      else if (g_strcmp0(key, "WiFi.HS20AP") == 0)
 +              network->wifi.isHS20AP = value;
 +#endif
  
        return -EINVAL;
  }
  bool connman_network_get_bool(struct connman_network *network,
                                                        const char *key)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p key %s", network, key);
- #endif
        if (g_str_equal(key, "Roaming"))
                return network->roaming;
        else if (g_str_equal(key, "WiFi.WPS"))
                return network->wifi.wps;
        else if (g_str_equal(key, "WiFi.UseWPS"))
                return network->wifi.use_wps;
 +#if defined TIZEN_EXT
 +      else if (g_str_equal(key, "DefaultInternet"))
 +              return network->default_internet;
 +      else if (g_str_equal(key, "WiFi.HS20AP"))
 +              return network->wifi.isHS20AP;
 +#endif
  
        return false;
  }
  
- #if defined TIZEN_EXT
- /**
-  * connman_network_set_vsie_list:
-  * @network: network structure
-  * @vsie_list: GSList pointer
-  *
-  * Set vendor specific list pointer
-  */
- void connman_network_set_vsie_list(struct connman_network *network, GSList *vsie_list)
- {
-       network->wifi.vsie_list = vsie_list;
- }
- /**
-  * connman_network_get_vsie_list:
-  * @network: network structure
-  *
-  * Get vendor specific list pointer
-  */
- void *connman_network_get_vsie_list(struct connman_network *network)
- {
-       return network->wifi.vsie_list;
- }
- #endif
  /**
   * connman_network_set_blob:
   * @network: network structure
  int connman_network_set_blob(struct connman_network *network,
                        const char *key, const void *data, unsigned int size)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p key %s size %d", network, key, size);
- #endif
        if (g_str_equal(key, "WiFi.SSID")) {
                g_free(network->wifi.ssid);
                network->wifi.ssid = g_try_malloc(size);
                        network->wifi.ssid_len = size;
                } else
                        network->wifi.ssid_len = 0;
++#if defined TIZEN_EXT
++      } else if (g_str_equal(key, "WiFi.Vsie")){
++              g_free(network->wifi.wifi_vsie);
++              network->wifi.wifi_vsie = g_try_malloc(size);
++              if (network->wifi.wifi_vsie) {
++                      memcpy(network->wifi.wifi_vsie, data, size);
++                      network->wifi.wifi_vsie_len = size;
++              } else
++                      network->wifi.wifi_vsie_len = 0;
++#endif
        } else {
                return -EINVAL;
        }
  const void *connman_network_get_blob(struct connman_network *network,
                                        const char *key, unsigned int *size)
  {
- #if !defined TIZEN_EXT
-       DBG("network %p key %s", network, key);
- #endif
        if (g_str_equal(key, "WiFi.SSID")) {
                if (size)
                        *size = network->wifi.ssid_len;
                return network->wifi.ssid;
        }
  
++#if defined TIZEN_EXT
++      if (g_str_equal(key, "WiFi.Vsie")) {
++              if (size)
++                      *size = network->wifi.wifi_vsie_len;
++
++              return network->wifi.wifi_vsie;
++      }
++#endif
++
        return NULL;
  }
  
diff --combined src/ntp.c
index bc553bf,0e80c3e..11512a0
mode 100755,100644..100755
+++ b/src/ntp.c
  #include <stdlib.h>
  #include <string.h>
  #include <sys/time.h>
+ #include <sys/timex.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <netinet/ip.h>
  #include <arpa/inet.h>
+ #include <netdb.h>
  
  #include <glib.h>
  
@@@ -65,9 -67,13 +67,13 @@@ struct ntp_msg 
  
  #define OFFSET_1900_1970  2208988800UL        /* 1970 - 1900 in seconds */
  
- #define STEPTIME_MIN_OFFSET  0.128
+ #define STEPTIME_MIN_OFFSET  0.4
  
  #define LOGTOD(a)  ((a) < 0 ? 1. / (1L << -(a)) : 1L << (int)(a))
+ #define NSEC_PER_SEC  ((uint64_t)1000000000ULL)
+ #ifndef ADJ_SETOFFSET
+ #define ADJ_SETOFFSET         0x0100  /* add 'time' to current time */
+ #endif
  
  #define NTP_SEND_TIMEOUT       2
  #define NTP_SEND_RETRIES       3
@@@ -117,12 -123,12 +123,12 @@@ static struct timespec mtx_time
  static int transmit_fd = 0;
  
  static char *timeserver = NULL;
- static struct sockaddr_in timeserver_addr;
+ static struct sockaddr_in6 timeserver_addr;
  static gint poll_id = 0;
  static gint timeout_id = 0;
  static guint retries = 0;
  
- static void send_packet(int fd, const char *server, uint32_t timeout);
+ static void send_packet(int fd, struct sockaddr *server, uint32_t timeout);
  
  static void next_server(void)
  {
@@@ -143,17 -149,19 +149,19 @@@ static gboolean send_timeout(gpointer u
        if (retries++ == NTP_SEND_RETRIES)
                next_server();
        else
-               send_packet(transmit_fd, timeserver, timeout << 1);
+               send_packet(transmit_fd, (struct sockaddr *)&timeserver_addr, timeout << 1);
  
        return FALSE;
  }
  
- static void send_packet(int fd, const char *server, uint32_t timeout)
+ static void send_packet(int fd, struct sockaddr *server, uint32_t timeout)
  {
        struct ntp_msg msg;
-       struct sockaddr_in addr;
        struct timeval transmit_timeval;
        ssize_t len;
+       void * addr;
+       int size;
+       char ipaddrstring[INET6_ADDRSTRLEN + 1];
  
        /*
         * At some point, we could specify the actual system precision with:
        memset(&msg, 0, sizeof(msg));
        msg.flags = NTP_FLAGS_ENCODE(NTP_FLAG_LI_NOTINSYNC, NTP_FLAG_VN_VER4,
            NTP_FLAG_MD_CLIENT);
-       msg.poll = 4;   // min
-       msg.poll = 10;  // max
+       msg.poll = 10;
        msg.precision = NTP_PRECISION_S;
  
-       memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
-       addr.sin_port = htons(123);
-       addr.sin_addr.s_addr = inet_addr(server);
+       if (server->sa_family == AF_INET) {
+               size = sizeof(struct sockaddr_in);
+               addr = (void *)&(((struct sockaddr_in *)&timeserver_addr)->sin_addr);
+       } else if (server->sa_family == AF_INET6) {
+               size = sizeof(struct sockaddr_in6);
+               addr = (void *)&timeserver_addr.sin6_addr;
+       } else {
+               connman_error("Family is neither ipv4 nor ipv6");
+               return;
+       }
  
        gettimeofday(&transmit_timeval, NULL);
        clock_gettime(CLOCK_MONOTONIC, &mtx_time);
        msg.xmttime.fraction = htonl(transmit_timeval.tv_usec * 1000);
  
        len = sendto(fd, &msg, sizeof(msg), MSG_DONTWAIT,
-                                               &addr, sizeof(addr));
+                                               server, size);
        if (len < 0) {
                connman_error("Time request for server %s failed (%d/%s)",
-                       server, errno, strerror(errno));
+                       inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)),
+                       errno, strerror(errno));
  
                if (errno == ENETUNREACH)
                        __connman_timeserver_sync_next();
        }
  
        if (len != sizeof(msg)) {
-               connman_error("Broken time request for server %s", server);
+               connman_error("Broken time request for server %s",
+                       inet_ntop(server->sa_family, addr, ipaddrstring, sizeof(ipaddrstring)));
                return;
        }
  
@@@ -213,7 -229,7 +229,7 @@@ static gboolean next_poll(gpointer user
        if (!timeserver || transmit_fd == 0)
                return FALSE;
  
-       send_packet(transmit_fd, timeserver, NTP_SEND_TIMEOUT);
+       send_packet(transmit_fd, (struct sockaddr *)&timeserver_addr, NTP_SEND_TIMEOUT);
  
        return FALSE;
  }
@@@ -235,7 -251,8 +251,9 @@@ static void decode_msg(void *base, size
        double m_delta, org, rec, xmt, dst;
        double delay, offset;
        static guint transmit_delay;
++#if !defined TIZEN_EXT
+       struct timex tmx = {};
 -
++#endif
        if (len < sizeof(*msg)) {
                connman_error("Invalid response from time server");
                return;
  
        poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL);
  
-       connman_info("ntp: time slew %+.6f s", offset);
 +#if defined TIZEN_EXT
 +      //send the dbus message to alram-manager
 +      {
 +#define TIME_BUS_NAME "org.tizen.alarm.manager"
 +#define TIME_INTERFACE "org.tizen.alarm.manager"
 +#define TIME_PATH "/org/tizen/alarm/manager"
 +#define TIME_METHOD "alarm_set_time_with_propagation_delay"
 +
 +              struct timespec cur = {0};
 +              struct timespec req = {0};
 +              double dtime;
 +
 +              DBusConnection *connection = NULL;
 +              DBusMessage *msg = NULL, *reply = NULL;
 +              DBusError error;
 +
 +              dbus_error_init(&error);
 +
 +              connection = connman_dbus_get_connection();
 +              if(!connection){
 +                      DBG("dbus connection does not exist");
 +                      return;
 +              }
 +
 +              clock_gettime(CLOCK_REALTIME, &cur);
 +              dtime = offset + cur.tv_sec + 1.0e-9 * cur.tv_nsec;
 +              cur.tv_sec = (long) dtime;
 +              cur.tv_nsec = (dtime - cur.tv_sec) * 1000000000;
 +
 +              clock_gettime(CLOCK_REALTIME, &req);
 +              msg = dbus_message_new_method_call(TIME_BUS_NAME, TIME_PATH,
 +                      TIME_INTERFACE, TIME_METHOD);
 +              dbus_message_append_args(msg, DBUS_TYPE_UINT32, &(cur.tv_sec),
 +                      DBUS_TYPE_UINT32, &(cur.tv_nsec),
 +                      DBUS_TYPE_UINT32, &(req.tv_sec),
 +                      DBUS_TYPE_UINT32, &(req.tv_nsec), DBUS_TYPE_INVALID);
 +              reply = dbus_connection_send_with_reply_and_block(connection, msg,
 +                              DBUS_TIMEOUT_USE_DEFAULT, &error);
 +              if(reply == NULL){
 +                      if(dbus_error_is_set(&error)){
 +                              DBG("%s", error.message);
 +                              dbus_error_free(&error);
 +                      }
 +                      else{
 +                              DBG("Failed to request set time");
 +                      }
 +                      dbus_connection_unref(connection);
 +                      dbus_message_unref(msg);
 +                      return;
 +              }
 +
 +              dbus_message_unref(msg);
 +              dbus_message_unref(reply);
 +              dbus_connection_unref(connection);
 +
 +              DBG("%lu cur seconds, %lu cur nsecs, %lu req seconds, %lu req nsecs",
 +                      cur.tv_sec, cur.tv_nsec, req.tv_sec, req.tv_nsec);
 +              DBG("setting time");
 +      }
 +#else
        if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
-               struct timeval adj;
-               adj.tv_sec = (long) offset;
-               adj.tv_usec = (offset - adj.tv_sec) * 1000000;
-               DBG("adjusting time");
-               if (adjtime(&adj, &adj) < 0) {
-                       connman_error("Failed to adjust time");
-                       return;
-               }
-               DBG("%lu seconds, %lu msecs", adj.tv_sec, adj.tv_usec);
+               tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
+               tmx.status = STA_PLL;
+               tmx.offset = offset * NSEC_PER_SEC;
+               tmx.constant = msg->poll - 4;
+               tmx.maxerror = 0;
+               tmx.esterror = 0;
+               connman_info("ntp: adjust (slew): %+.6f sec", offset);
        } else {
-               struct timeval cur;
-               double dtime;
-               gettimeofday(&cur, NULL);
-               dtime = offset + cur.tv_sec + 1.0e-6 * cur.tv_usec;
-               cur.tv_sec = (long) dtime;
-               cur.tv_usec = (dtime - cur.tv_sec) * 1000000;
+               tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET | ADJ_MAXERROR | ADJ_ESTERROR;
+               /* ADJ_NANO uses nanoseconds in the microseconds field */
+               tmx.time.tv_sec = (long)offset;
+               tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
+               tmx.maxerror = 0;
+               tmx.esterror = 0;
+               /* the kernel expects -0.3s as {-1, 7000.000.000} */
+               if (tmx.time.tv_usec < 0) {
+                       tmx.time.tv_sec  -= 1;
+                       tmx.time.tv_usec += NSEC_PER_SEC;
+               }
  
-               DBG("setting time");
+               connman_info("ntp: adjust (jump): %+.6f sec", offset);
+       }
  
-               if (settimeofday(&cur, NULL) < 0) {
-                       connman_error("Failed to set time");
-                       return;
-               }
+       if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_ADDSECOND)
+               tmx.status |= STA_INS;
+       else if (NTP_FLAGS_LI_DECODE(msg->flags) & NTP_FLAG_LI_DELSECOND)
+               tmx.status |= STA_DEL;
  
-               DBG("%lu seconds, %lu msecs", cur.tv_sec, cur.tv_usec);
+       if (adjtimex(&tmx) < 0) {
+               connman_error("Failed to adjust time");
+               return;
        }
 -              LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
+       DBG("interval/delta/delay/drift %fs/%+.3fs/%.3fs/%+ldppm",
++                      LOGTOD(msg->poll), offset, delay, tmx.freq / 65536);
 +#endif
  }
  
  static gboolean received_data(GIOChannel *channel, GIOCondition condition,
                                                        gpointer user_data)
  {
        unsigned char buf[128];
-       struct sockaddr_in sender_addr;
+       struct sockaddr_in6 sender_addr;
        struct msghdr msg;
        struct iovec iov;
        struct cmsghdr *cmsg;
        char aux[128];
        ssize_t len;
        int fd;
+       int size;
+       void * addr_ptr;
+       void * src_ptr;
  
        if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
                connman_error("Problem with timer server channel");
        if (len < 0)
                return TRUE;
  
-       if (timeserver_addr.sin_addr.s_addr != sender_addr.sin_addr.s_addr)
-               /* only accept messages from the timeserver */
+       if (sender_addr.sin6_family == AF_INET) {
+               size = 4;
+               addr_ptr = &((struct sockaddr_in *)&timeserver_addr)->sin_addr;
+               src_ptr = &((struct sockaddr_in *)&sender_addr)->sin_addr;
+       } else if (sender_addr.sin6_family == AF_INET6) {
+               size = 16;
+               addr_ptr = &((struct sockaddr_in6 *)&timeserver_addr)->sin6_addr;
+               src_ptr = &((struct sockaddr_in6 *)&sender_addr)->sin6_addr;
+       } else {
+               connman_error("Not a valid family type");
+               return TRUE;
+       }
+       if(memcmp(addr_ptr, src_ptr, size) != 0)
                return TRUE;
  
        tv = NULL;
  static void start_ntp(char *server)
  {
        GIOChannel *channel;
-       struct sockaddr_in addr;
+       struct addrinfo hint;
+       struct addrinfo *info;
+       struct sockaddr * addr;
+       struct sockaddr_in  * in4addr;
+       struct sockaddr_in6 in6addr;
+       int size;
+       int family;
        int tos = IPTOS_LOWDELAY, timestamp = 1;
+       int ret;
  
        if (!server)
                return;
  
-       DBG("server %s", server);
+       memset(&hint, 0, sizeof(hint));
+       hint.ai_family = AF_UNSPEC;
+       hint.ai_socktype = SOCK_DGRAM;
+       hint.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
+       ret = getaddrinfo(server, NULL, &hint, &info);
  
-       if (channel_watch > 0)
-               goto send;
+       if (ret) {
+               connman_error("cannot get server info");
+               return;
+       }
  
-       transmit_fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
-       if (transmit_fd < 0) {
-               connman_error("Failed to open time server socket");
+       family = info->ai_family;
+       memcpy(&timeserver_addr, info->ai_addr, info->ai_addrlen);
+       freeaddrinfo(info);
+       memset(&in6addr, 0, sizeof(in6addr));
+       if (family == AF_INET) {
+               ((struct sockaddr_in *)&timeserver_addr)->sin_port = htons(123);
+               in4addr = (struct sockaddr_in *)&in6addr;
+               in4addr->sin_family = family;
+               addr = (struct sockaddr *)in4addr;
+               size = sizeof(struct sockaddr_in);
+       } else if (family == AF_INET6) {
+               timeserver_addr.sin6_port = htons(123);
+               in6addr.sin6_family = family;
+               addr = (struct sockaddr *)&in6addr;
+               size = sizeof(in6addr);
+       } else {
+               connman_error("Family is neither ipv4 nor ipv6");
                return;
        }
  
-       memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
+       DBG("server %s family %d", server, family);
  
-       if (bind(transmit_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+       if (channel_watch > 0)
+               goto send;
+       transmit_fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+       if (transmit_fd <= 0) {
+                 connman_error("Failed to open time server socket");
+                 return;
+       }
+       if (bind(transmit_fd, (struct sockaddr *) addr, size) < 0) {
                connman_error("Failed to bind time server socket");
                close(transmit_fd);
                return;
        }
  
-       if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
-               connman_error("Failed to set type of service option");
-               close(transmit_fd);
-               return;
+       if (family == AF_INET) {
+               if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
+                       connman_error("Failed to set type of service option");
+                       close(transmit_fd);
+                       return;
+               }
        }
  
        if (setsockopt(transmit_fd, SOL_SOCKET, SO_TIMESTAMP, &timestamp,
        g_io_channel_unref(channel);
  
  send:
-       send_packet(transmit_fd, server, NTP_SEND_TIMEOUT);
+       send_packet(transmit_fd, (struct sockaddr*)&timeserver_addr, NTP_SEND_TIMEOUT);
  }
  
  int __connman_ntp_start(char *server)
                g_free(timeserver);
  
        timeserver = g_strdup(server);
-       timeserver_addr.sin_addr.s_addr = inet_addr(server);
  
        start_ntp(timeserver);
  
diff --combined src/peer.c
index 206b799,340cbcc..340cbcc
mode 100755,100644..100755
@@@ -176,7 -176,7 +176,7 @@@ static int start_dhcp_server(struct con
        if (err < 0)
                goto error;
  
-       g_timeout_add_seconds(0, dhcp_server_started, connman_peer_ref(peer));
+       g_idle_add(dhcp_server_started, connman_peer_ref(peer));
  
        return 0;
  
@@@ -758,7 -758,7 +758,7 @@@ void connman_peer_set_name(struct connm
  void connman_peer_set_iface_address(struct connman_peer *peer,
                                        const unsigned char *iface_address)
  {
-       memset(peer->iface_address, 0, ETH_ALEN);
+       memset(peer->iface_address, 0, sizeof(peer->iface_address));
        memcpy(peer->iface_address, iface_address, ETH_ALEN);
  }
  
@@@ -905,13 -905,16 +905,16 @@@ int connman_peer_set_state(struct connm
                break;
        case CONNMAN_PEER_STATE_READY:
                reply_pending(peer, 0);
+               __connman_technology_set_connected(CONNMAN_SERVICE_TYPE_P2P, true);
                break;
        case CONNMAN_PEER_STATE_DISCONNECT:
                if (peer->connection_master)
                        stop_dhcp_server(peer);
+               else
+                       __connman_dhcp_stop(peer->ipconfig);
                peer->connection_master = false;
                peer->sub_device = NULL;
+               __connman_technology_set_connected(CONNMAN_SERVICE_TYPE_P2P, false);
                break;
        case CONNMAN_PEER_STATE_FAILURE:
                if (manage_peer_error(peer) == 0)
diff --combined src/peer_service.c
index 053672a,a457bff..a457bff
mode 100755,100644..100755
@@@ -293,9 -293,6 +293,6 @@@ int __connman_peer_service_register(con
        if (service) {
                DBG("Found one existing service %p", service);
  
-               if (g_strcmp0(service->owner, owner))
-                       ret = -EBUSY;
                if (service->pending)
                        ret = -EINPROGRESS;
                else
diff --combined src/provider.c
index 521346b,9c71a20..c0d69e4
mode 100755,100644..100755
@@@ -141,12 -141,12 +141,12 @@@ int connman_provider_disconnect(struct 
                provider_indicate_state(provider,
                                        CONNMAN_SERVICE_STATE_DISCONNECT);
  
-       if (err < 0) {
-               if (err != -EINPROGRESS)
-                       return err;
+       if (err < 0)
+               return err;
  
-               return -EINPROGRESS;
-       }
+       if (provider->vpn_service)
+               provider_indicate_state(provider,
+                                       CONNMAN_SERVICE_STATE_IDLE);
  
        return 0;
  }
@@@ -164,14 -164,15 +164,15 @@@ int connman_provider_remove(struct conn
        return 0;
  }
  
- int __connman_provider_connect(struct connman_provider *provider)
+ int __connman_provider_connect(struct connman_provider *provider,
+                                       const char *dbus_sender)
  {
        int err;
  
        DBG("provider %p", provider);
  
        if (provider->driver && provider->driver->connect)
-               err = provider->driver->connect(provider);
+               err = provider->driver->connect(provider, dbus_sender);
        else
                return -EOPNOTSUPP;
  
@@@ -242,11 -243,7 +243,11 @@@ static int set_connected(struct connman
                }
  
                __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);
@@@ -576,14 -573,8 +577,14 @@@ int connman_provider_set_nameservers(st
                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 --combined src/proxy.c
index f331de9,e1bc420..e1bc420
mode 100755,100644..100755
@@@ -123,7 -123,7 +123,7 @@@ unsigned int connman_proxy_lookup(cons
        lookup->url = g_strdup(url);
        lookup->service = connman_service_ref(service);
  
-       lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup);
+       lookup->watch = g_idle_add(lookup_callback, lookup);
        if (lookup->watch == 0) {
                g_free(lookup->url);
                g_free(lookup);
diff --combined src/resolver.c
index 8a7fa66,75ea5ba..d6c20cd
mode 100755,100644..100755
@@@ -35,6 -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)
  
  /*
@@@ -97,9 -100,9 +97,9 @@@ static int resolvfile_export(void
         * MAXDNSRCH/MAXNS entries are used.
         */
  
-       for (count = 0, list = g_list_last(resolvfile_list);
+       for (count = 0, list = g_list_first(resolvfile_list);
                                                list && (count < MAXDNSRCH);
-                                               list = g_list_previous(list)) {
+                                               list = g_list_next(list)) {
                struct resolvfile_entry *entry = list->data;
  
                if (!entry->domain)
        if (count)
                g_string_append_printf(content, "\n");
  
-       for (count = 0, list = g_list_last(resolvfile_list);
+       for (count = 0, list = g_list_first(resolvfile_list);
                                                list && (count < MAXNS);
-                                               list = g_list_previous(list)) {
+                                               list = g_list_next(list)) {
                struct resolvfile_entry *entry = list->data;
  
                if (!entry->server)
  
        old_umask = umask(022);
  
 -      fd = open(RESOLV_CONF_STATEDIR, O_RDWR | O_CREAT | O_CLOEXEC,
 +      fd = open("/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC,
                                        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
        if (fd < 0) {
 -              connman_warn_once("Cannot create "RESOLV_CONF_STATEDIR" "
 -                      "falling back to "RESOLV_CONF_ETC);
 -
 -              fd = open(RESOLV_CONF_ETC, O_RDWR | O_CREAT | O_CLOEXEC,
 -                                      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 -
 -              if (fd < 0) {
 -                      err = -errno;
 -                      goto done;
 -              }
 +              err = -errno;
 +              goto done;
        }
  
        if (ftruncate(fd, 0) < 0) {
@@@ -207,7 -218,7 +207,7 @@@ int __connman_resolvfile_remove(int ind
        return resolvfile_export();
  }
  
static void append_fallback_nameservers(void)
void __connman_resolver_append_fallback_nameservers(void)
  {
        GSList *list;
  
@@@ -284,7 -295,7 +284,7 @@@ static void remove_entries(GSList *entr
  
        g_slist_free(entries);
  
-       append_fallback_nameservers();
+       __connman_resolver_append_fallback_nameservers();
  }
  
  static gboolean resolver_expire_cb(gpointer user_data)
                struct connman_service *service;
                service = __connman_service_lookup_from_index(entry->index);
                if (service)
 +#if defined TIZEN_EXT
 +                      __connman_service_nameserver_remove(service,
 +                                      entry->server, true,
 +                                      CONNMAN_IPCONFIG_TYPE_ALL);
 +#else
                        __connman_service_nameserver_remove(service,
                                                        entry->server, true);
 +#endif
        }
  
        remove_entries(list);
@@@ -362,11 -367,6 +362,11 @@@ static int append_resolver(int index, c
        if (!server && !domain)
                return -EINVAL;
  
 +#ifdef TIZEN_EXT
 +      if (g_strcmp0(server, "0.0.0.0") == 0)
 +              return -EINVAL;
 +#endif
 +
        entry = g_try_new0(struct entry_data, 1);
        if (!entry)
                return -ENOMEM;
  
                entry->timeout = g_timeout_add_seconds(interval,
                                resolver_refresh_cb, entry);
-               /*
-                * We update the service only for those nameservers
-                * that are automagically added via netlink (lifetime > 0)
-                */
-               if (server && entry->index >= 0) {
-                       struct connman_service *service;
-                       service = __connman_service_lookup_from_index(entry->index);
-                       if (service)
- #if defined TIZEN_EXT
-                               __connman_service_nameserver_append(service,
-                                               server, true,
-                                               CONNMAN_IPCONFIG_TYPE_ALL);
- #else
-                               __connman_service_nameserver_append(service,
-                                                               server, true);
- #endif
-               }
        }
  
        if (entry->index >= 0 && entry->server)
        else
                __connman_resolvfile_append(entry->index, domain, server);
  
+       /*
+        * We update the service only for those nameservers
+        * that are automagically added via netlink (lifetime > 0)
+        */
+       if (server && entry->index >= 0 && lifetime) {
+               struct connman_service *service;
+               service = __connman_service_lookup_from_index(entry->index);
+               if (service)
++#if defined TIZEN_EXT
++                      __connman_service_nameserver_append(service,
++                                      server, true,
++                                      CONNMAN_IPCONFIG_TYPE_ALL);
++#else
+                       __connman_service_nameserver_append(service,
+                                                       server, true);
++#endif
+       }
        return 0;
  }
  
@@@ -617,6 -611,28 +617,28 @@@ int __connman_resolver_redo_servers(in
                                        entry->server);
        }
  
+       /*
+        * We want to re-add all search domains back to search
+        * domain lists as they just got removed for RDNSS IPv6-servers
+        * (above).
+        * Removal of search domains is not necessary
+        * as there can be only one instance of each search domain
+        * in the each dns-servers search domain list.
+         */
+       for (list = entry_list; list; list = list->next) {
+               struct entry_data *entry = list->data;
+               if (entry->index != index)
+                       continue;
+               if (entry->server)
+                       continue;
+               __connman_dnsproxy_append(entry->index, entry->domain,
+                                       NULL);
+       }
        return 0;
  }
  
@@@ -643,6 -659,14 +665,14 @@@ int __connman_resolver_init(gboolean dn
  
        DBG("dnsproxy %d", dnsproxy);
  
+       /* get autoip nameservers */
+       ns = __connman_inet_get_pnp_nameservers(NULL);
+       for (i = 0; ns && ns[i]; i += 1) {
+               DBG("pnp server %s", ns[i]);
+               append_resolver(i, NULL, ns[i], 86400, 0);
+       }
+       g_strfreev(ns);
        if (!dnsproxy)
                return 0;
  
diff --combined src/rfkill.c
index 36426e0,d9bed4d..fce9d72
mode 100755,100644..100755
@@@ -73,7 -73,6 +73,7 @@@ static enum connman_service_type conver
        return CONNMAN_SERVICE_TYPE_UNKNOWN;
  }
  
 +#if !defined TIZEN_EXT
  static enum rfkill_type convert_service_type(enum connman_service_type type)
  {
        switch (type) {
@@@ -96,7 -95,6 +96,7 @@@
  
        return NUM_RFKILL_TYPES;
  }
 +#endif
  
  static GIOStatus rfkill_process(GIOChannel *chan)
  {
@@@ -159,20 -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;
        close(fd);
  
        return err;
 +#endif
  }
  
  int __connman_rfkill_init(void)
  
        DBG("");
  
-       fd = open("/dev/rfkill", O_RDWR | O_CLOEXEC);
+       fd = open("/dev/rfkill", O_RDONLY | O_CLOEXEC);
        if (fd < 0) {
                connman_error("Failed to open RFKILL control device");
                return -EIO;
diff --combined src/rtnl.c
index 5690c48,a094e25..35ae0a9
mode 100755,100644..100755
  #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)
  
@@@ -100,7 -94,6 +100,7 @@@ static bool ether_blacklisted(const cha
        return false;
  }
  
 +#if !defined TIZEN_EXT
  static bool wext_interface(char *ifname)
  {
        struct iwreq wrq;
  
        return true;
  }
 +#endif
 +
 +#if defined TIZEN_EXT
 +static bool __connman_rtnl_is_cellular_device(const char *name)
 +{
 +      char **pattern;
 +      char **cellular_interfaces;
 +
 +      cellular_interfaces =
 +                      connman_setting_get_string_list(
 +                                      "NetworkCellularInterfaceList");
 +      if (!cellular_interfaces)
 +              return false;
 +
 +      for (pattern = cellular_interfaces; *pattern; pattern++) {
 +              if (g_str_has_prefix(name, *pattern)) {
 +                      DBG("Cellular interface: %s", name);
 +                      return true;
 +              }
 +      }
 +
 +      return false;
 +}
 +#endif
  
  static void read_uevent(struct interface_data *interface)
  {
  
        name = connman_inet_ifname(interface->index);
  
 +#if defined TIZEN_EXT
 +      if (__connman_rtnl_is_cellular_device(name)) {
 +              interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
 +              interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
 +              return;
 +      }
 +#endif
 +
        if (ether_blacklisted(name)) {
                interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
                interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
                } else if (strcmp(line + 8, "vlan") == 0) {
                        interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
                        interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
+               } else if (strcmp(line + 8, "bond") == 0) {
+                       interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
+                       interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
                } else {
                        interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
                        interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
        if (found_devtype)
                goto out;
  
 +#if !defined TIZEN_EXT
 +      /* TIZEN does not use old wext interface */
        /* We haven't got a DEVTYPE, let's check if it's a wireless device */
        if (wext_interface(name)) {
                interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
  
                connman_error("%s runs an unsupported 802.11 driver", name);
        }
 +#endif
  
  out:
        g_free(name);
@@@ -459,14 -419,6 +461,14 @@@ static void process_newlink(unsigned sh
        if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats))
                return;
  
 +#if defined TIZEN_EXT
 +      /* Do not accept Wi-Fi P2P interface */
 +      if (g_strrstr(ifname, "p2p") != NULL) {
 +              DBG("Newlink event for Wi-Fi P2P interface ignored");
 +              return;
 +      }
 +#endif
 +
        snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
                                                address.ether_addr_octet[0],
                                                address.ether_addr_octet[1],
                return;
        }
  
 +#ifdef TIZEN_EXT
 +      if (TIZEN_TV_EXT && g_strcmp0(ident, "eeeeeeeeeeee") == 0) {
 +              DBG("Newlink event with Dummy MAC. Ignored!");
 +              return;
 +      }
 +#endif
 +
        switch (type) {
        case ARPHRD_ETHER:
        case ARPHRD_LOOPBACK:
        case ARPHDR_PHONET_PIPE:
        case ARPHRD_PPP:
        case ARPHRD_NONE:
 +#if defined TIZEN_EXT
 +/*
 + * Description: ARPHDR_RMNET for QC modem using QMI
 + */
 +      case ARPHDR_RMNET:
 +#endif
                __connman_ipconfig_newlink(index, type, flags,
                                                        str, mtu, &stats);
                break;
  
                if (type == ARPHRD_ETHER)
                        read_uevent(interface);
-       } else
 +#if defined TIZEN_EXT
 +              if (type == ARPHRD_PPP || type == ARPHDR_RMNET)
 +                      read_uevent(interface);
 +
 +      } else if (g_strcmp0(interface->ident, ident) != 0) {
 +              /* If an original address is built-in physical device,
 +               * it's hardly get an address at a initial creation
 +               */
 +              __connman_technology_remove_interface(interface->service_type,
 +                              interface->index, interface->ident);
 +
 +              g_free(interface->ident);
 +              interface->ident = g_strdup(ident);
 +
 +              __connman_technology_add_interface(interface->service_type,
 +                              interface->index, interface->ident);
 +
 +              interface = NULL;
 +#endif
+       } else if (type == ARPHRD_ETHER && interface->device_type == CONNMAN_DEVICE_TYPE_UNKNOWN)
+               read_uevent(interface);
+       else
                interface = NULL;
  
        for (list = rtnl_list; list; list = list->next) {
@@@ -612,13 -534,6 +616,13 @@@ static void process_dellink(unsigned sh
        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;
        }
@@@ -1314,37 -1229,6 +1318,37 @@@ static void rtnl_newnduseropt(struct nl
        if (index < 0)
                return;
  
 +#if defined TIZEN_EXT
 +      struct connman_service *service;
 +      enum connman_service_state state;
 +      enum connman_dnsconfig_method ipv6_dns_method;
 +
 +      service = __connman_service_lookup_from_index(index);
 +      if (!service) {
 +              DBG("Invalid service");
 +              return;
 +      }
 +
 +      DBG("service: %p index: %d\n", service, index);
 +
 +      if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
 +              state = __connman_service_ipconfig_get_state(service, CONNMAN_IPCONFIG_TYPE_IPV6);
 +              if (state != CONNMAN_SERVICE_STATE_ASSOCIATION &&
 +                              state != CONNMAN_SERVICE_STATE_CONFIGURATION &&
 +                              state != CONNMAN_SERVICE_STATE_READY &&
 +                              state != CONNMAN_SERVICE_STATE_ONLINE) {
 +                      DBG("Service state[%d] is not connecting/connected", state);
 +                      return;
 +              }
 +      }
 +
 +      ipv6_dns_method = connman_service_get_ipv6_dns_method(service);
 +      if (ipv6_dns_method != CONNMAN_DNSCONFIG_METHOD_DHCP) {
 +              DBG("IPv6 DNS method is not Auto ignore RA!!! [DNS method: %d]", ipv6_dns_method);
 +              return;
 +      }
 +#endif
 +
        for (opt = (void *)&msg[1];
                        msglen > 0;
                        msglen -= opt->nd_opt_len * 8,
  
                if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */
                        char buf[40];
++#if defined TIZEN_EXT
++                      struct connman_service *service;
  
++                      service = __connman_service_lookup_from_index(index);
++                      DBG("service: %p\n",service);
++#endif
                        servers = rtnl_nd_opt_rdnss(opt, &lifetime,
 -                                                              &nr_servers);
 +                                      &nr_servers);
                        for (i = 0; i < nr_servers; i++) {
                                if (!inet_ntop(AF_INET6, servers + i, buf,
 -                                                              sizeof(buf)))
 +                                                      sizeof(buf)))
                                        continue;
  
 +#if defined TIZEN_EXT
 +                              __connman_service_nameserver_remove(service,
 +                                              buf, false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV6);
 +                              __connman_service_nameserver_append(service,
 +                                              buf, false,
 +                                              CONNMAN_IPCONFIG_TYPE_IPV6);
 +#endif
                                connman_resolver_append_lifetime(index,
 -                                                      NULL, buf, lifetime);
 +                                              NULL, buf, lifetime);
                        }
                } else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */
                        g_free(domains);
  
@@@ -1499,8 -1376,6 +1509,6 @@@ static int process_response(guint32 seq
  
  static void rtnl_message(void *buf, size_t len)
  {
-       DBG("buf %p len %zd", buf, len);
        while (len > 0) {
                struct nlmsghdr *hdr = buf;
                struct nlmsgerr *err;
diff --combined src/service.c
index 033c8f8,02cd51f..d0543ae
mode 100755,100644..100755
@@@ -30,8 -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>
  
  #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;
@@@ -58,10 -49,6 +58,10 @@@ static unsigned int vpn_autoconnect_tim
  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;
@@@ -76,11 -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;
        char *name;
        char *passphrase;
        bool roaming;
 +      bool request_passphrase_input;
 +      struct connman_service_user user;
        struct connman_ipconfig *ipconfig_ipv4;
        struct connman_ipconfig *ipconfig_ipv6;
        struct connman_network *network;
        char **nameservers;
        char **nameservers_config;
        char **nameservers_auto;
+       int nameservers_timeout;
        char **domains;
        char *hostname;
        char *domainname;
        /* 802.1x settings from the config files */
        char *eap;
        char *identity;
+       char *anonymous_identity;
        char *agent_identity;
        char *ca_cert_file;
+       char *subject_match;
+       char *altsubject_match;
+       char *domain_suffix_match;
+       char *domain_match;
        char *client_cert_file;
        char *private_key_file;
        char *private_key_passphrase;
        bool hidden_service;
        char *config_file;
        char *config_entry;
 +#if defined TIZEN_EXT
 +      /*
 +       * Description: TIZEN implements system global connection management.
 +       *              It's only for PDP (cellular) bearer. Wi-Fi is managed
 +       *              by ConnMan automatically. Reference count can help to
 +       *              manage open/close connection requests by each application.
 +       */
 +      int user_pdn_connection_refcount;
 +      bool storage_reload;
 +      /*
 +       * Description: In case of EAP security type,
 +       *                                user can select the keymgmt type for roaming(802.11r).
 +       *                                - FT, CCKM, OKC, ...
 +       */
 +      char *keymgmt_type;
 +      int disconnect_reason;
 +      int assoc_status_code;
 +#endif
 +#ifdef TIZEN_EXT
 +      enum connman_dnsconfig_method dns_config_method_ipv4;
 +      enum connman_dnsconfig_method dns_config_method_ipv6;
 +#endif
  };
  
  static bool allow_property_changed(struct connman_service *service);
@@@ -174,57 -138,13 +180,57 @@@ static struct connman_ipconfig *create_
                int index, enum connman_ipconfig_method method);
  static struct connman_ipconfig *create_ip6config(struct connman_service *service,
                int index);
+ static void dns_changed(struct connman_service *service);
  
  struct find_data {
        const char *path;
        struct connman_service *service;
  };
  
 +#if defined TIZEN_EXT
 +/*
 + * Public APIs to use user_pdn_connection_refcount
 + */
 +void connman_service_user_pdn_connection_ref(struct connman_service *service)
 +{
 +      __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1);
 +
 +      DBG("User made PDN connection referenced: %d",
 +                              service->user_pdn_connection_refcount);
 +}
 +
 +gboolean connman_service_user_pdn_connection_unref_and_test(
 +                                      struct connman_service *service)
 +{
 +      __sync_synchronize();
 +
 +      DBG("User made PDN connection referenced: %d, which will be decreased",
 +                              service->user_pdn_connection_refcount);
 +
 +      if (service->user_pdn_connection_refcount < 1)
 +              return TRUE;
 +
 +      if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1) == 0)
 +              return TRUE;
 +
 +      return FALSE;
 +}
 +
 +gboolean connman_service_is_no_ref_user_pdn_connection(
 +                                      struct connman_service *cellular)
 +{
 +      if (cellular == NULL)
 +              return TRUE;
 +
 +      __sync_synchronize();
 +      if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
 +                      cellular->user_pdn_connection_refcount == 0)
 +              return TRUE;
 +
 +      return FALSE;
 +}
 +#endif
 +
  static void compare_path(gpointer value, gpointer user_data)
  {
        struct connman_service *service = value;
@@@ -327,16 -247,12 +333,16 @@@ enum connman_service_security __connman
  
        if (!strcmp(str, "psk"))
                return CONNMAN_SERVICE_SECURITY_PSK;
-       if (!strcmp(str, "ieee8021x"))
+       if (!strcmp(str, "ieee8021x") || !strcmp(str, "8021x"))
                return CONNMAN_SERVICE_SECURITY_8021X;
-       if (!strcmp(str, "none"))
+       if (!strcmp(str, "none") || !strcmp(str, "open"))
                return CONNMAN_SERVICE_SECURITY_NONE;
        if (!strcmp(str, "wep"))
                return CONNMAN_SERVICE_SECURITY_WEP;
 +#if defined TIZEN_EXT
 +      if (!strcmp(str, "rsn"))
 +              return CONNMAN_SERVICE_SECURITY_RSN;
 +#endif
  
        return CONNMAN_SERVICE_SECURITY_UNKNOWN;
  }
@@@ -352,14 -268,8 +358,14 @@@ static const char *security2string(enu
                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";
        }
@@@ -445,116 -355,19 +451,129 @@@ static enum connman_service_proxy_metho
                return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
  }
  
 +#ifdef TIZEN_EXT
 +static const char *__connman_dnsconfig_method2string(enum connman_dnsconfig_method method)
 +{
 +      switch (method) {
 +      case CONNMAN_DNSCONFIG_METHOD_UNKNOWN:
 +              return "unknown";
 +      case CONNMAN_DNSCONFIG_METHOD_MANUAL:
 +              return "manual";
 +      case CONNMAN_DNSCONFIG_METHOD_DHCP:
 +              return "dhcp";
 +      }
 +
 +      return NULL;
 +}
 +
 +static enum connman_dnsconfig_method __connman_dnsconfig_string2method(
 +              const char *method)
 +{
 +      if (g_strcmp0(method, "manual") == 0)
 +              return CONNMAN_DNSCONFIG_METHOD_MANUAL;
 +      else if (g_strcmp0(method, "dhcp") == 0)
 +              return CONNMAN_DNSCONFIG_METHOD_DHCP;
 +      else
 +              return CONNMAN_DNSCONFIG_METHOD_UNKNOWN;
 +}
 +#endif
 +
 +static bool
 +connman_service_is_user_allowed(struct connman_service *service, uid_t uid)
 +{
 +      uid_t favorite_user = service->user.favorite_user;
 +      uid_t current_user = uid;
 +
 +      DBG("Service favorite UID: %d, current UID: %d", favorite_user, current_user);
 +      if (favorite_user == USER_NONE || current_user == USER_ROOT)
 +              return true;
 +
 +      if (favorite_user != current_user || current_user == USER_NONE) {
 +              DBG("Current user is not a favorite user to this service!");
 +              return false;
 +      }
 +
 +      return true;
 +}
 +
 +#if !defined TIZEN_EXT
 +static GList *connman_service_get_login_users()
 +{
 +      struct utmpx *utmp;
 +      struct passwd *pwd;
 +      GList *user_list = NULL;
 +
 +      setutxent();
 +
 +      while ((utmp = getutxent()) != NULL) {
 +              DBG("User Name: %s", utmp->ut_user);
 +
 +              pwd = getpwnam(utmp->ut_user);
 +              if (pwd) {
 +                      if (!g_list_find(user_list, GUINT_TO_POINTER(pwd->pw_uid)))
 +                              user_list = g_list_append(user_list,
 +                                              GUINT_TO_POINTER(pwd->pw_uid));
 +
 +                      DBG("User Name: %s, UID: %d", utmp->ut_user, pwd->pw_uid);
 +              }
 +      }
 +
 +      endutxent();
 +
 +      return user_list;
 +}
 +#endif
 +
 +static bool is_service_owner_user_login(struct connman_service *service)
 +{
 +#if defined TIZEN_EXT
 +      return true;
 +#else
 +      GList *list, *user_list;
 +      bool ret = false;
 +
 +      /* Here we only care about wifi service */
 +      if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
 +              return true;
 +
 +      DBG("service favorite user id is: %d", service->user.favorite_user);
 +
 +      user_list = connman_service_get_login_users();
 +      if (user_list == NULL) {
 +              DBG("Can not get any logged in user info.");
 +              return true;
 +      }
 +
 +      for (list = user_list; list; list = list->next) {
 +              uid_t uid = GPOINTER_TO_UINT(list->data);
 +
 +              DBG("login user id is %d", uid);
 +
 +              if (service->user.favorite_user == uid) {
 +                      ret = true;
 +                      break;
 +              }
 +      }
 +
 +      g_list_free(user_list);
 +
 +      return ret;
 +#endif
 +}
 +
+ static void set_split_routing(struct connman_service *service, bool value)
+ {
+       if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+               return;
+       service->do_split_routing = value;
+       if (service->do_split_routing)
+               service->order = 0;
+       else
+               service->order = 10;
+ }
  int __connman_service_load_modifiable(struct connman_service *service)
  {
        GKeyFile *keyfile;
        case CONNMAN_SERVICE_TYPE_P2P:
                break;
        case CONNMAN_SERVICE_TYPE_VPN:
-               service->do_split_routing = g_key_file_get_boolean(keyfile,
-                               service->identifier, "SplitRouting", NULL);
+               set_split_routing(service, g_key_file_get_boolean(keyfile,
+                                                       service->identifier,
+                                                       "SplitRouting", NULL));
                /* fall through */
        case CONNMAN_SERVICE_TYPE_WIFI:
        case CONNMAN_SERVICE_TYPE_GADGET:
        return 0;
  }
  
 +static int service_load_passphrase(struct connman_service *service)
 +{
 +      GKeyFile *keyfile;
 +      gchar *str;
 +
 +      keyfile = connman_storage_load_service(service->identifier);
 +      if (!keyfile)
 +              return -EIO;
 +
 +      str = g_key_file_get_string(keyfile,
 +                              service->identifier, "Passphrase", NULL);
 +      if (str)
 +              service->passphrase = str;
 +
 +      g_key_file_free(keyfile);
 +
 +      return 0;
 +}
 +
  static int service_load(struct connman_service *service)
  {
        GKeyFile *keyfile;
        case CONNMAN_SERVICE_TYPE_P2P:
                break;
        case CONNMAN_SERVICE_TYPE_VPN:
-               service->do_split_routing = g_key_file_get_boolean(keyfile,
-                               service->identifier, "SplitRouting", NULL);
+               set_split_routing(service, g_key_file_get_boolean(keyfile,
+                                                       service->identifier,
+                                                       "SplitRouting", NULL));
                autoconnect = g_key_file_get_boolean(keyfile,
                                service->identifier, "AutoConnect", &error);
                if (!error)
                service->nameservers_config = NULL;
        }
  
 +#ifdef TIZEN_EXT
 +      char *dns_method;
 +
 +      dns_method = g_key_file_get_string(keyfile, service->identifier,
 +                      "Nameservers.IPv4method", NULL);
 +      service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method);
 +
 +      dns_method = g_key_file_get_string(keyfile, service->identifier,
 +                      "Nameservers.IPv6method", NULL);
 +      service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method);
 +#endif
 +
        service->timeservers_config = g_key_file_get_string_list(keyfile,
                        service->identifier, "Timeservers", &length, NULL);
        if (service->timeservers_config && length == 0) {
        service->hidden_service = g_key_file_get_boolean(keyfile,
                                        service->identifier, "Hidden", NULL);
  
 +#if defined TIZEN_EXT
 +      if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
 +                      service->security == CONNMAN_SERVICE_SECURITY_8021X) {
 +              str = g_key_file_get_string(keyfile,
 +                              service->identifier, "EAP", NULL);
 +              if (str != NULL) {
 +                      g_free(service->eap);
 +                      service->eap = str;
 +              }
 +
 +              str = g_key_file_get_string(keyfile,
 +                              service->identifier, "Phase2", NULL);
 +              if (str != NULL) {
 +                      g_free(service->phase2);
 +                      service->phase2 = str;
 +              }
 +
 +              str = g_key_file_get_string(keyfile,
 +                              service->identifier, "Identity", NULL);
 +              if (str != NULL) {
 +                      g_free(service->identity);
 +                      service->identity = str;
 +              }
 +
 +              str = g_key_file_get_string(keyfile,
 +                              service->identifier, "CACertFile", NULL);
 +              if (str != NULL) {
 +                      g_free(service->ca_cert_file);
 +                      service->ca_cert_file = str;
 +              }
 +
 +              str = g_key_file_get_string(keyfile,
 +                              service->identifier, "ClientCertFile", NULL);
 +              if (str != NULL) {
 +                      g_free(service->client_cert_file);
 +                      service->client_cert_file = str;
 +              }
 +
 +              str = g_key_file_get_string(keyfile,
 +                              service->identifier, "PrivateKeyFile", NULL);
 +              if (str != NULL) {
 +                      g_free(service->private_key_file);
 +                      service->private_key_file = str;
 +              }
 +
 +              str = g_key_file_get_string(keyfile,
 +                              service->identifier, "PrivateKeyPassphrase", NULL);
 +              if (str != NULL) {
 +                      g_free(service->private_key_passphrase);
 +                      service->private_key_passphrase = str;
 +              }
 +      }
 +#endif
 +
 +      if (g_key_file_has_key(keyfile, service->identifier, "UID", NULL))
 +              service->user.favorite_user = g_key_file_get_integer(keyfile,
 +                                      service->identifier, "UID", NULL);
  done:
        g_key_file_free(keyfile);
  
@@@ -913,13 -642,6 +936,13 @@@ static int service_save(struct connman_
                        const unsigned char *ssid;
                        unsigned int ssid_len = 0;
  
 +                      if (service->user.favorite_user == USER_NONE)
 +                              g_key_file_remove_key(keyfile, service->identifier,
 +                                                      "UID", NULL);
 +                      else
 +                              g_key_file_set_integer(keyfile, service->identifier,
 +                                                      "UID", service->user.favorite_user);
 +
                        ssid = connman_network_get_blob(service->network,
                                                        "WiFi.SSID", &ssid_len);
  
                g_free(str);
        }
  
 -      if (service->passphrase && strlen(service->passphrase) > 0)
 -              g_key_file_set_string(keyfile, service->identifier,
 +      if (service->user.current_user == service->user.favorite_user) {
 +              if (service->passphrase && strlen(service->passphrase) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
                                        "Passphrase", service->passphrase);
 -      else
 -              g_key_file_remove_key(keyfile, service->identifier,
 -                                                      "Passphrase", NULL);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "Passphrase", NULL);
 +      }
  
        if (service->ipconfig_ipv4)
                __connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
        g_key_file_remove_key(keyfile, service->identifier,
                                                        "Nameservers", NULL);
  
 +#if defined TIZEN_EXT
 +      if(service->dns_config_method_ipv4 != 0) {
 +              const char *method;
 +              method = __connman_dnsconfig_method2string(
 +                              service->dns_config_method_ipv4);
 +              g_key_file_set_string(keyfile, service->identifier,
 +                              "Nameservers.IPv4method", method);
 +      } else
 +      g_key_file_remove_key(keyfile, service->identifier,
 +                                              "Nameservers.IPv4method", NULL);
 +
 +      if(service->dns_config_method_ipv6 != 0) {
 +              const char *method;
 +              method = __connman_dnsconfig_method2string(
 +                              service->dns_config_method_ipv6);
 +              g_key_file_set_string(keyfile, service->identifier,
 +                              "Nameservers.IPv6method", method);
 +      } else
 +      g_key_file_remove_key(keyfile, service->identifier,
 +                                                      "Nameservers.IPv6method", NULL);
 +#endif
 +
        if (service->timeservers_config) {
                guint len = g_strv_length(service->timeservers_config);
  
                g_key_file_set_string(keyfile, service->identifier,
                                "Config.ident", service->config_entry);
  
 +#if defined TIZEN_EXT
 +      if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
 +                      service->security == CONNMAN_SERVICE_SECURITY_8021X) {
 +              if (service->eap != NULL && strlen(service->eap) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
 +                                      "EAP", service->eap);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "EAP", NULL);
 +
 +              if (service->phase2 != NULL && strlen(service->phase2) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
 +                                      "Phase2", service->phase2);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "Phase2", NULL);
 +
 +              if (service->identity != NULL && strlen(service->identity) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
 +                                      "Identity", service->identity);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "Identity", NULL);
 +
 +              if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
 +                                      "CACertFile", service->ca_cert_file);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "CACertFile", NULL);
 +
 +              if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
 +                                      "ClientCertFile", service->client_cert_file);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "ClientCertFile", NULL);
 +
 +              if (service->private_key_file != NULL && strlen(service->private_key_file) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
 +                                      "PrivateKeyFile", service->private_key_file);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "PrivateKeyFile", NULL);
 +
 +              if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0)
 +                      g_key_file_set_string(keyfile, service->identifier,
 +                                      "PrivateKeyPassphrase", service->private_key_passphrase);
 +              else
 +                      g_key_file_remove_key(keyfile, service->identifier,
 +                                      "PrivateKeyPassphrase", NULL);
 +      }
 +#endif
 +
  done:
        __connman_storage_save_service(keyfile, service->identifier);
  
@@@ -1246,15 -890,12 +1269,12 @@@ done
        return result;
  }
  
- static bool is_connecting_state(struct connman_service *service,
-                                       enum connman_service_state state)
+ static bool is_connecting(enum connman_service_state state)
  {
        switch (state) {
        case CONNMAN_SERVICE_STATE_UNKNOWN:
        case CONNMAN_SERVICE_STATE_IDLE:
        case CONNMAN_SERVICE_STATE_FAILURE:
-               if (service->network)
-                       return connman_network_get_connecting(service->network);
        case CONNMAN_SERVICE_STATE_DISCONNECT:
        case CONNMAN_SERVICE_STATE_READY:
        case CONNMAN_SERVICE_STATE_ONLINE:
        return false;
  }
  
- static bool is_connected_state(const struct connman_service *service,
-                                       enum connman_service_state state)
+ static bool is_connected(enum connman_service_state state)
  {
        switch (state) {
        case CONNMAN_SERVICE_STATE_UNKNOWN:
        return false;
  }
  
- static bool is_idle_state(const struct connman_service *service,
-                               enum connman_service_state state)
+ static bool is_idle(enum connman_service_state state)
  {
        switch (state) {
+       case CONNMAN_SERVICE_STATE_IDLE:
+       case CONNMAN_SERVICE_STATE_DISCONNECT:
+       case CONNMAN_SERVICE_STATE_FAILURE:
+               return true;
        case CONNMAN_SERVICE_STATE_UNKNOWN:
        case CONNMAN_SERVICE_STATE_ASSOCIATION:
        case CONNMAN_SERVICE_STATE_CONFIGURATION:
        case CONNMAN_SERVICE_STATE_READY:
        case CONNMAN_SERVICE_STATE_ONLINE:
-       case CONNMAN_SERVICE_STATE_DISCONNECT:
-       case CONNMAN_SERVICE_STATE_FAILURE:
                break;
-       case CONNMAN_SERVICE_STATE_IDLE:
-               return true;
        }
  
        return false;
  }
  
- static bool is_connecting(struct connman_service *service)
+ static int nameservers_changed_cb(void *user_data)
  {
-       return is_connecting_state(service, service->state);
+       struct connman_service *service = user_data;
+       DBG("service %p", service);
+       service->nameservers_timeout = 0;
+       if ((is_idle(service->state) && !service->nameservers) ||
+                       is_connected(service->state))
+               dns_changed(service);
+       return FALSE;
  }
  
- static bool is_connected(struct connman_service *service)
+ static void nameservers_changed(struct connman_service *service)
  {
-       return is_connected_state(service, service->state);
+       if (!service->nameservers_timeout)
+               service->nameservers_timeout = g_idle_add(nameservers_changed_cb,
+                                                       service);
  }
  
  static bool nameserver_available(struct connman_service *service,
+                               enum connman_ipconfig_type type,
                                const char *ns)
  {
        int family;
  
        family = connman_inet_check_ipaddress(ns);
  
-       if (family == AF_INET)
-               return is_connected_state(service, service->state_ipv4);
+       if (family == AF_INET) {
+               if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
+                       return false;
  
-       if (family == AF_INET6)
-               return is_connected_state(service, service->state_ipv6);
+               return is_connected(service->state_ipv4);
+       }
+       if (family == AF_INET6) {
+               if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
+                       return false;
+               return is_connected(service->state_ipv6);
+       }
  
        return false;
  }
  
+ static int searchdomain_add_all(struct connman_service *service)
+ {
+       int index, i = 0;
+       if (!is_connected(service->state))
+               return -ENOTCONN;
+       index = __connman_service_get_index(service);
+       if (index < 0)
+               return -ENXIO;
+       if (service->domains) {
+               while (service->domains[i]) {
+                       connman_resolver_append(index, service->domains[i],
+                                               NULL);
+                       i++;
+               }
+               return 0;
+       }
+       if (service->domainname)
+               connman_resolver_append(index, service->domainname, NULL);
+       return 0;
+ }
+ static int searchdomain_remove_all(struct connman_service *service)
+ {
+       int index, i = 0;
+       if (!is_connected(service->state))
+               return -ENOTCONN;
+       index = __connman_service_get_index(service);
+       if (index < 0)
+               return -ENXIO;
+       while (service->domains && service->domains[i]) {
+               connman_resolver_remove(index, service->domains[i], NULL);
+               i++;
+       }
+       if (service->domainname)
+               connman_resolver_remove(index, service->domainname, NULL);
+       return 0;
+ }
  static int nameserver_add(struct connman_service *service,
+                       enum connman_ipconfig_type type,
                        const char *nameserver)
  {
-       int index;
+       int index, ret;
  
-       if (!nameserver_available(service, nameserver))
+       if (!nameserver_available(service, type, nameserver))
                return 0;
  
        index = __connman_service_get_index(service);
        if (index < 0)
                return -ENXIO;
  
-       return connman_resolver_append(index, NULL, nameserver);
 +#if defined TIZEN_EXT
 +      DBG("Resolver append nameserver: %s", nameserver);
 +#endif
+       ret = connman_resolver_append(index, NULL, nameserver);
+       if (ret >= 0)
+               nameservers_changed(service);
+       return ret;
  }
  
- #if defined TIZEN_EXT
  static int nameserver_add_all(struct connman_service *service,
-               enum connman_ipconfig_type type)
- #else
- static int nameserver_add_all(struct connman_service *service)
- #endif
+                       enum connman_ipconfig_type type)
  {
        int i = 0;
  
        if (service->nameservers_config) {
                while (service->nameservers_config[i]) {
-                                       nameserver_add(service,
 +#if defined TIZEN_EXT
 +                      DBG("type %d add service->nameservers_config[%d]:%s",type,
 +                          i, service->nameservers_config[i]);
 +                      if(strncmp(service->nameservers_config[i], "::", 2) == 0) {
 +                              DBG("Invalid nameserver");
 +                              i++;
 +                              continue;
 +                      }
 +
 +                      switch(type) {
 +                      case CONNMAN_IPCONFIG_TYPE_IPV4:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers_config[i]) == AF_INET &&
 +                                  service->dns_config_method_ipv4 ==
 +                                  CONNMAN_DNSCONFIG_METHOD_MANUAL) {
-                                       nameserver_add(service,
++                                      nameserver_add(service, type,
 +                                                     service->nameservers_config[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_IPV6:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers_config[i]) == AF_INET6 &&
 +                                  service->dns_config_method_ipv6 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL) {
-                                       nameserver_add(service,
++                                      nameserver_add(service, type,
 +                                                     service->nameservers_config[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_ALL:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers_config[i]) == AF_INET &&
 +                                  service->dns_config_method_ipv4 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL) {
-                                       nameserver_add(service,
++                                      nameserver_add(service, type,
 +                                                     service->nameservers_config[i]);
 +                              }
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers_config[i]) == AF_INET6 &&
 +                                  service->dns_config_method_ipv6 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL) {
-                       nameserver_add(service, service->nameservers_config[i]);
++                                      nameserver_add(service, type,
 +                                                     service->nameservers_config[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
 +                              DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
 +                              break;
 +                      default:
 +                              DBG("default case do nothing");
 +                              break;
 +                      }
 +#else
+                       nameserver_add(service, type,
+                               service->nameservers_config[i]);
 +#endif
                        i++;
                }
- #if !defined TIZEN_EXT
-               return 0;
- #endif
-       }
- #if defined TIZEN_EXT
-       i = 0;
- #endif
-       if (service->nameservers) {
+       } else if (service->nameservers) {
                while (service->nameservers[i]) {
-                                       nameserver_add(service,
 +#if defined TIZEN_EXT
 +                      DBG("type %d service->nameservers[%d]: %s",type,
 +                          i, service->nameservers[i]);
 +
 +                      switch(type) {
 +                      case CONNMAN_IPCONFIG_TYPE_IPV4:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET &&
 +                                      service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
-                                       nameserver_add(service,
++                                      nameserver_add(service, type,
 +                                                     service->nameservers[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_IPV6:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET6 &&
 +                                      service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
-                                       nameserver_add(service,
++                                      nameserver_add(service, type,
 +                                                     service->nameservers[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_ALL:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET &&
 +                                      service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
-                                       nameserver_add(service,
++                                      nameserver_add(service, type,
 +                                                     service->nameservers[i]);
 +                              }
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET6 &&
 +                                      service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
-                       nameserver_add(service, service->nameservers[i]);
++                                      nameserver_add(service, type,
 +                                                     service->nameservers[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
 +                              DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
 +                              break;
 +                      default:
 +                              DBG("default case do nothing");
 +                              break;
 +                      }
 +#else
+                       nameserver_add(service, type,
+                               service->nameservers[i]);
 +#endif
                        i++;
                }
        }
  
+       if (!i)
+               __connman_resolver_append_fallback_nameservers();
+       searchdomain_add_all(service);
        return 0;
  }
  
  static int nameserver_remove(struct connman_service *service,
+                       enum connman_ipconfig_type type,
                        const char *nameserver)
  {
-       int index;
+       int index, ret;
  
-       if (!nameserver_available(service, nameserver))
+       if (!nameserver_available(service, type, nameserver))
                return 0;
  
        index = __connman_service_get_index(service);
        if (index < 0)
                return -ENXIO;
  
-       return connman_resolver_remove(index, NULL, nameserver);
 +#if defined TIZEN_EXT
 +      DBG("Resolver remove nameserver: %s", nameserver);
 +#endif
+       ret = connman_resolver_remove(index, NULL, nameserver);
+       if (ret >= 0)
+               nameservers_changed(service);
+       return ret;
  }
  
- #if defined TIZEN_EXT
  static int nameserver_remove_all(struct connman_service *service,
-               enum connman_ipconfig_type type)
- #else
- static int nameserver_remove_all(struct connman_service *service)
- #endif
+                               enum connman_ipconfig_type type)
  {
 +#if defined TIZEN_EXT
 +      /**
 +        * Skip this function if there is any connected profiles
 +        * that use same interface
 +        */
 +      if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
 +                      __connman_service_get_connected_count_of_iface(service) > 0)
 +              return 0;
 +#endif
        int index, i = 0;
  
        index = __connman_service_get_index(service);
                return -ENXIO;
  
        while (service->nameservers_config && service->nameservers_config[i]) {
 -
 +#if defined TIZEN_EXT
 +              DBG("type %d Remove service->nameservers_config[%d]: %s",
 +                    type, i, service->nameservers_config[i]);
 +              switch(type) {
 +              case CONNMAN_IPCONFIG_TYPE_IPV4:
 +                      if (connman_inet_check_ipaddress(
 +                              service->nameservers_config[i]) == AF_INET &&
 +                              (service->dns_config_method_ipv4 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_DHCP ||
 +                              service->dns_config_method_ipv4 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
-                               nameserver_remove(service,
++                              nameserver_remove(service, type,
 +                                                service->nameservers_config[i]);
 +                      }
 +                      break;
 +              case CONNMAN_IPCONFIG_TYPE_IPV6:
 +                      if (connman_inet_check_ipaddress(
 +                              service->nameservers_config[i]) == AF_INET6 &&
 +                              (service->dns_config_method_ipv6 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_DHCP ||
 +                              service->dns_config_method_ipv6 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
-                               nameserver_remove(service,
++                              nameserver_remove(service, type,
 +                                                service->nameservers_config[i]);
 +                      }
 +                      break;
 +              case CONNMAN_IPCONFIG_TYPE_ALL:
 +                      if (connman_inet_check_ipaddress(
 +                              service->nameservers_config[i]) == AF_INET &&
 +                              (service->dns_config_method_ipv4 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_DHCP ||
 +                              service->dns_config_method_ipv4 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
-                               nameserver_remove(service,
++                              nameserver_remove(service, type,
 +                                                service->nameservers_config[i]);
 +                      }
 +                      if (connman_inet_check_ipaddress(
 +                              service->nameservers_config[i]) == AF_INET6 &&
 +                              (service->dns_config_method_ipv6 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_DHCP ||
 +                              service->dns_config_method_ipv6 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
-                               nameserver_remove(service,
++                              nameserver_remove(service, type,
 +                                                service->nameservers_config[i]);
 +                      }
 +                      break;
 +              case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
 +                      DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
 +                      break;
 +              default:
 +                      DBG("default case do nothing");
 +                      break;
 +              }
 +#else
-               nameserver_remove(service, service->nameservers_config[i]);
+               nameserver_remove(service, type,
+                               service->nameservers_config[i]);
 +#endif
                i++;
        }
  
        i = 0;
        while (service->nameservers && service->nameservers[i]) {
-                                       nameserver_remove(service,
 +#if defined TIZEN_EXT
 +              DBG("type %d Remove service->nameservers[%d]: %s",type, i,
 +                    service->nameservers[i]);
 +              switch(type) {
 +                      case CONNMAN_IPCONFIG_TYPE_IPV4:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET &&
 +                                      (service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_MANUAL ||
 +                                      service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP)) {
-                                       nameserver_remove(service,
++                                      nameserver_remove(service, type,
 +                                                        service->nameservers[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_IPV6:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET6 &&
 +                                      (service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_MANUAL ||
 +                                      service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP)) {
-                                       nameserver_remove(service,
++                                      nameserver_remove(service, type,
 +                                                        service->nameservers[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_ALL:
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET &&
 +                                      (service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_MANUAL ||
 +                                      service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP)) {
-                                       nameserver_remove(service,
++                                      nameserver_remove(service, type,
 +                                                        service->nameservers[i]);
 +                              }
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET6 &&
 +                                      (service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_MANUAL ||
 +                                      service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP)) {
-               nameserver_remove(service, service->nameservers[i]);
++                                      nameserver_remove(service, type,
 +                                                        service->nameservers[i]);
 +                              }
 +                              break;
 +                      case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
 +                              DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
 +                              break;
 +                      default:
 +                              DBG("default case do nothing");
 +                              break;
 +              }
 +#else
+               nameserver_remove(service, type, service->nameservers[i]);
 +#endif
                i++;
        }
  
-       return 0;
- }
- static int searchdomain_add_all(struct connman_service *service)
- {
-       int index, i = 0;
-       if (!is_connected(service))
-               return -ENOTCONN;
-       index = __connman_service_get_index(service);
-       if (index < 0)
-               return -ENXIO;
-       if (service->domains) {
-               while (service->domains[i]) {
-                       connman_resolver_append(index, service->domains[i],
-                                               NULL);
-                       i++;
-               }
-               return 0;
-       }
-       if (service->domainname)
-               connman_resolver_append(index, service->domainname, NULL);
-       return 0;
- }
- static int searchdomain_remove_all(struct connman_service *service)
- {
-       int index, i = 0;
-       if (!is_connected(service))
-               return -ENOTCONN;
-       index = __connman_service_get_index(service);
-       if (index < 0)
-               return -ENXIO;
-       while (service->domains && service->domains[i]) {
-               connman_resolver_remove(index, service->domains[i], NULL);
-               i++;
-       }
-       if (service->domainname)
-               connman_resolver_remove(index, service->domainname, NULL);
+       searchdomain_remove_all(service);
  
        return 0;
  }
   * inserted to resolver via netlink message (see rtnl.c:rtnl_newnduseropt()
   * for details) and not through service.c
   */
 +#if defined TIZEN_EXT
 +int __connman_service_nameserver_append(struct connman_service *service,
 +                              const char *nameserver, bool is_auto,
 +                              enum connman_ipconfig_type type)
 +#else
  int __connman_service_nameserver_append(struct connman_service *service,
                                const char *nameserver, bool is_auto)
 +#endif
  {
        char **nameservers;
        int len, i;
  
 -      DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
 +      DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
  
        if (!nameserver)
                return -EINVAL;
                nameservers = service->nameservers;
  
        for (i = 0; nameservers && nameservers[i]; i++)
 +#if defined TIZEN_EXT
 +      {
 +              DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver);
 +#endif
                if (g_strcmp0(nameservers[i], nameserver) == 0)
                        return -EEXIST;
 +#if defined TIZEN_EXT
 +      }
 +#endif
  
        if (nameservers) {
                len = g_strv_length(nameservers);
        nameservers[len] = g_strdup(nameserver);
        nameservers[len + 1] = NULL;
  
-                       service->dns_config_method_ipv4 ==
-                       CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
 +#ifdef TIZEN_EXT
 +      if(type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
-                       service->dns_config_method_ipv6 ==
-                       CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
++         service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
 +              service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
 +
 +      if(type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
++         service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
 +              service->dns_config_method_ipv6 = CONNMAN_DNSCONFIG_METHOD_DHCP;
 +#endif
 +
        if (is_auto) {
                service->nameservers_auto = nameservers;
        } else {
                service->nameservers = nameservers;
- #if defined TIZEN_EXT
-               DBG("nameserver add: %s, type: %d", nameserver, type);
- #endif
-               nameserver_add(service, nameserver);
+               nameserver_add(service, CONNMAN_IPCONFIG_TYPE_ALL, nameserver);
        }
  
+       nameservers_changed(service);
+       searchdomain_add_all(service);
        return 0;
  }
  
 +#if defined TIZEN_EXT
 +int __connman_service_nameserver_remove(struct connman_service *service,
 +                              const char *nameserver, bool is_auto,
 +                              enum connman_ipconfig_type type)
 +#else
  int __connman_service_nameserver_remove(struct connman_service *service,
                                const char *nameserver, bool is_auto)
 +#endif
  {
        char **servers, **nameservers;
        bool found = false;
        if (!nameservers)
                return 0;
  
-       for (i = 0; nameservers && nameservers[i]; i++)
+       for (i = 0; nameservers[i]; i++)
                if (g_strcmp0(nameservers[i], nameserver) == 0) {
                        found = true;
                        break;
@@@ -1838,10 -1246,8 +1879,14 @@@ set_servers
                service->nameservers_auto = nameservers;
        } else {
                service->nameservers = nameservers;
-               nameserver_remove(service, nameserver);
 +#if defined TIZEN_EXT
 +              DBG("nameserver remove ip_type: %d", type);
++              nameserver_remove(service, type,
++                              nameserver);
++#else
+               nameserver_remove(service, CONNMAN_IPCONFIG_TYPE_ALL,
+                               nameserver);
 +#endif
        }
  
        return 0;
  
  void __connman_service_nameserver_clear(struct connman_service *service)
  {
- #if defined TIZEN_EXT
-       DBG("nameserver remove all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
        nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
- #else
-       nameserver_remove_all(service);
- #endif
  
        g_strfreev(service->nameservers);
        service->nameservers = NULL;
  
- #if defined TIZEN_EXT
-       DBG("nameserver add all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
        nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
- #else
-       nameserver_add_all(service);
- #endif
  }
  
  static void add_nameserver_route(int family, int index, char *nameserver,
@@@ -1978,6 -1373,18 +2012,18 @@@ void __connman_service_nameserver_del_r
                nameserver_del_routes(index, service->nameservers, type);
  }
  
+ static void address_updated(struct connman_service *service,
+                       enum connman_ipconfig_type type)
+ {
+       if (is_connected(service->state) &&
+                       service == __connman_service_get_default()) {
+               nameserver_remove_all(service, type);
+               nameserver_add_all(service, type);
+               __connman_timeserver_sync(service);
+       }
+ }
  static struct connman_stats *stats_get(struct connman_service *service)
  {
        if (service->roaming)
@@@ -2066,71 -1473,6 +2112,71 @@@ static void reset_stats(struct connman_
        g_timer_reset(service->stats_roaming.timer);
  }
  
-                               is_connected(service) == TRUE) {
 +#if defined TIZEN_EXT
 +static gboolean __connman_service_is_internet_profile(
 +              struct connman_service *cellular)
 +{
 +      const char internet_suffix[] = "_1";
 +
 +      DBG("Service path: %s", cellular->path);
 +
 +      if (g_str_has_suffix(cellular->path, internet_suffix) == TRUE)
 +              return TRUE;
 +
 +      return FALSE;
 +}
 +
 +static gboolean __connman_service_is_tethering_profile(
 +              struct connman_service *cellular)
 +{
 +      const char tethering_suffix[] = "_5";
 +
 +      DBG("Service path: %s", cellular->path);
 +
 +      if (g_str_has_suffix(cellular->path, tethering_suffix) == TRUE)
 +              return TRUE;
 +
 +      return FALSE;
 +}
 +
 +struct connman_service *connman_service_get_default_connection(void)
 +{
 +      GList *list;
 +      struct connman_service *service;
 +      struct connman_service *default_service = NULL;
 +
 +      for (list = service_list; list; list = list->next) {
 +              service = list->data;
 +
 +              DBG("service: %p %s %s %s", service, service->name,
 +                              state2string(service->state),
 +                              __connman_service_type2string(service->type));
 +
 +              if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
-                       else if (is_connected(service) == TRUE &&
-                                       is_connected(default_service) == FALSE)
++                              is_connected(service->state) == TRUE) {
 +                      return service;
 +              } else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
 +                              __connman_service_is_internet_profile(service) == TRUE) {
 +                      if (default_service == NULL)
 +                              default_service = service;
-                               is_connected(service) == TRUE) {
++                      else if (is_connected(service->state) == TRUE &&
++                                      is_connected(default_service->state) == FALSE)
 +                              default_service = service;
 +              } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET &&
-                               is_connected(service) == TRUE) {
++                              is_connected(service->state) == TRUE) {
 +                      if (default_service == NULL)
 +                              default_service = service;
 +              } else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH &&
++                              is_connected(service->state) == TRUE) {
 +                      if (default_service == NULL)
 +                              default_service = service;
 +              }
 +      }
 +
 +      return default_service;
 +}
 +#endif
 +
  struct connman_service *__connman_service_get_default(void)
  {
        struct connman_service *service;
  
        service = service_list->data;
  
-       if (!is_connected(service))
+       if (!is_connected(service->state))
                return NULL;
  
        return service;
@@@ -2169,15 -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 &&
@@@ -2201,13 -1537,9 +2247,13 @@@ static void state_changed(struct connma
        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);
@@@ -2339,7 -1671,7 +2385,7 @@@ static void append_ipv4(DBusMessageIte
  {
        struct connman_service *service = user_data;
  
-       if (!is_connected_state(service, service->state_ipv4))
+       if (!is_connected(service->state_ipv4))
                return;
  
        if (service->ipconfig_ipv4)
@@@ -2350,7 -1682,7 +2396,7 @@@ static void append_ipv6(DBusMessageIte
  {
        struct connman_service *service = user_data;
  
-       if (!is_connected_state(service, service->state_ipv6))
+       if (!is_connected(service->state_ipv6))
                return;
  
        if (service->ipconfig_ipv6)
@@@ -2384,9 -1716,9 +2430,9 @@@ static void append_nameservers(DBusMess
  
        for (i = 0; servers[i]; i++) {
                if (service)
-                       available = nameserver_available(service, servers[i]);
-               DBG("servers[%d] %s available %d", i, servers[i], available);
+                       available = nameserver_available(service,
+                                               CONNMAN_IPCONFIG_TYPE_ALL,
+                                               servers[i]);
  
                if (available)
                        dbus_message_iter_append_basic(iter,
        }
  }
  
-               available = nameserver_available(service, server);
 +#if defined TIZEN_EXT
 +static void append_nameserver_manual(DBusMessageIter *iter,
 +              struct connman_service *service, const char *server)
 +{
 +      bool available = true;
 +
 +      if (service)
-               available = nameserver_available(service, server);
++              available = nameserver_available(service,
++                              CONNMAN_IPCONFIG_TYPE_ALL, server);
 +
 +      if (available)
 +              dbus_message_iter_append_basic(iter,
 +                              DBUS_TYPE_STRING, &server);
 +}
 +
 +static void append_nameserver_dhcp(DBusMessageIter *iter,
 +              struct connman_service *service, const char *server)
 +{
 +      bool available = true;
 +
 +      if (service)
++              available = nameserver_available(service,
++                              CONNMAN_IPCONFIG_TYPE_ALL, server);
 +
 +      if (available)
 +              dbus_message_iter_append_basic(iter,
 +                              DBUS_TYPE_STRING, &server);
 +}
 +#endif
 +
  static void append_dns(DBusMessageIter *iter, void *user_data)
  {
        struct connman_service *service = user_data;
 +#if defined TIZEN_EXT
 +      int i;
 +#endif
  
-       if (!is_connected(service))
+       if (!is_connected(service->state))
                return;
  
 +#ifdef TIZEN_EXT
 +      const char *str;
 +
 +      str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
 +      if(str != NULL) {
 +              char *str1 = g_strdup_printf("ipv4.%s", str);
 +              dbus_message_iter_append_basic(iter,
 +                      DBUS_TYPE_STRING, &str1);
 +              g_free(str1);
 +      }
 +
 +      str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
 +      if(str != NULL) {
 +              char *str1 = g_strdup_printf("ipv6.%s", str);
 +              dbus_message_iter_append_basic(iter,
 +                      DBUS_TYPE_STRING, &str1);
 +              g_free(str1);
 +      }
 +#endif
 +
        if (service->nameservers_config) {
 +#if defined TIZEN_EXT
 +              i = 0;
 +              while (service->nameservers_config[i]) {
 +                      if (connman_inet_check_ipaddress(
 +                              service->nameservers_config[i]) == AF_INET &&
 +                              service->dns_config_method_ipv4 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL) {
 +                              append_nameserver_manual(iter, service,
 +                                              service->nameservers_config[i]);
 +                      }
 +
 +                      if (connman_inet_check_ipaddress(
 +                              service->nameservers_config[i]) == AF_INET6 &&
 +                              service->dns_config_method_ipv6 ==
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL) {
 +                              append_nameserver_manual(iter, service,
 +                                              service->nameservers_config[i]);
 +                      }
 +                      i++;
 +              }
 +              /* In case of mixed DNS Config Type one of IPv4/IPv6 can be
 +               * dynamic while other is static so try to append the DNS
 +               * Address which is dynamic also */
 +              if (service->nameservers != NULL) {
 +                      i = 0;
 +                      while (service->nameservers[i]) {
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET &&
 +                                      service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
 +                                      append_nameserver_dhcp(iter, service,
 +                                                      service->nameservers[i]);
 +                              }
 +
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET6 &&
 +                                      service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
 +                                      append_nameserver_dhcp(iter, service,
 +                                                      service->nameservers[i]);
 +                              }
 +                              i++;
 +                      }
 +              }
 +#else
                append_nameservers(iter, service, service->nameservers_config);
 +#endif
                return;
        } else {
                if (service->nameservers)
 +#if defined TIZEN_EXT
 +              {
 +                      i = 0;
 +                      while (service->nameservers[i]) {
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET &&
 +                                      service->dns_config_method_ipv4 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
 +                                      append_nameserver_dhcp(iter, service,
 +                                                      service->nameservers[i]);
 +                              }
 +
 +                              if (connman_inet_check_ipaddress(
 +                                      service->nameservers[i]) == AF_INET6 &&
 +                                      service->dns_config_method_ipv6 ==
 +                                              CONNMAN_DNSCONFIG_METHOD_DHCP) {
 +                                      append_nameserver_dhcp(iter, service,
 +                                                      service->nameservers[i]);
 +                              }
 +                              i++;
 +                      }
 +              }
 +#else
                        append_nameservers(iter, service,
                                        service->nameservers);
 +#endif
  
                if (service->nameservers_auto)
                        append_nameservers(iter, service,
@@@ -2550,46 -1761,10 +2598,46 @@@ static void append_dnsconfig(DBusMessag
  {
        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)
@@@ -2639,8 -1814,8 +2687,8 @@@ static void append_domain(DBusMessageIt
  {
        struct connman_service *service = user_data;
  
-       if (!is_connected(service) &&
-                               !is_connecting(service))
+       if (!is_connected(service->state) &&
+                               !is_connecting(service->state))
                return;
  
        if (service->domains)
@@@ -2684,7 -1859,7 +2732,7 @@@ static void append_proxy(DBusMessageIte
        const char *method = proxymethod2string(
                CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
  
-       if (!is_connected(service))
+       if (!is_connected(service->state))
                return;
  
        proxy = connman_service_get_proxy_method(service);
@@@ -2771,7 -1946,7 +2819,7 @@@ static void append_provider(DBusMessage
  {
        struct connman_service *service = user_data;
  
-       if (!is_connected(service))
+       if (!is_connected(service->state))
                return;
  
        if (service->provider)
@@@ -2784,11 -1959,13 +2832,13 @@@ static void settings_changed(struct con
  {
        enum connman_ipconfig_type type;
  
+       type = __connman_ipconfig_get_config_type(ipconfig);
+       __connman_notifier_ipconfig_changed(service, ipconfig);
        if (!allow_property_changed(service))
                return;
  
-       type = __connman_ipconfig_get_config_type(ipconfig);
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                connman_dbus_property_changed_dict(service->path,
                                        CONNMAN_SERVICE_INTERFACE, "IPv4",
                connman_dbus_property_changed_dict(service->path,
                                        CONNMAN_SERVICE_INTERFACE, "IPv6",
                                        append_ipv6, service);
-       __connman_notifier_ipconfig_changed(service, ipconfig);
  }
  
  static void ipv4_configuration_changed(struct connman_service *service)
                                                        service);
  }
  
+ void __connman_service_notify_ipv4_configuration(
+                                       struct connman_service *service)
+ {
+       if (!service)
+               return;
+       ipv4_configuration_changed(service);
+ }
  static void ipv6_configuration_changed(struct connman_service *service)
  {
        if (!allow_property_changed(service))
@@@ -3074,7 -2258,7 +3131,7 @@@ void __connman_service_notify(struct co
        if (!service)
                return;
  
-       if (!is_connected(service))
+       if (!is_connected(service->state))
                return;
  
        stats_update(service,
@@@ -3154,86 -2338,6 +3211,86 @@@ int __connman_service_iterate_services(
        return 0;
  }
  
 +#if defined TIZEN_EXT
 +static void append_wifi_ext_info(DBusMessageIter *dict,
 +                                      struct connman_network *network)
 +{
 +      char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
 +      char *bssid_str = bssid_buff;
 +      const void *ssid;
 +      unsigned int ssid_len;
 +      unsigned char *bssid;
 +      unsigned int maxrate;
 +      unsigned int keymgmt;
 +      uint16_t frequency;
 +      const char *enc_mode;
 +      const char *str;
 +      gboolean passpoint;
 +
 +      ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
 +      bssid = connman_network_get_bssid(network);
 +      maxrate = connman_network_get_maxrate(network);
 +      frequency = connman_network_get_frequency(network);
 +      enc_mode = connman_network_get_enc_mode(network);
 +      passpoint = connman_network_get_bool(network, "WiFi.HS20AP");
 +      keymgmt = connman_network_get_keymgmt(network);
 +
 +      snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
 +                              bssid[0], bssid[1], bssid[2],
 +                              bssid[3], bssid[4], bssid[5]);
 +
 +      connman_dbus_dict_append_fixed_array(dict, "SSID",
 +                                      DBUS_TYPE_BYTE, &ssid, ssid_len);
 +      connman_dbus_dict_append_basic(dict, "BSSID",
 +                                      DBUS_TYPE_STRING, &bssid_str);
 +      connman_dbus_dict_append_basic(dict, "MaxRate",
 +                                      DBUS_TYPE_UINT32, &maxrate);
 +      connman_dbus_dict_append_basic(dict, "Frequency",
 +                                      DBUS_TYPE_UINT16, &frequency);
 +      connman_dbus_dict_append_basic(dict, "EncryptionMode",
 +                                      DBUS_TYPE_STRING, &enc_mode);
 +      connman_dbus_dict_append_basic(dict, "Passpoint",
 +                                      DBUS_TYPE_BOOLEAN, &passpoint);
 +      connman_dbus_dict_append_basic(dict, "Keymgmt",
 +                                      DBUS_TYPE_UINT32, &keymgmt);
 +
 +      str = connman_network_get_string(network, "WiFi.Security");
 +      if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) {
 +              str = connman_network_get_string(network, "WiFi.EAP");
 +              if (str != NULL)
 +                      connman_dbus_dict_append_basic(dict, "EAP",
 +                                      DBUS_TYPE_STRING, &str);
 +
 +              str = connman_network_get_string(network, "WiFi.Phase2");
 +              if (str != NULL)
 +                      connman_dbus_dict_append_basic(dict, "Phase2",
 +                                      DBUS_TYPE_STRING, &str);
 +
 +              str = connman_network_get_string(network, "WiFi.Identity");
 +              if (str != NULL)
 +                      connman_dbus_dict_append_basic(dict, "Identity",
 +                                      DBUS_TYPE_STRING, &str);
 +
 +              str = connman_network_get_string(network, "WiFi.CACertFile");
 +              if (str != NULL)
 +                      connman_dbus_dict_append_basic(dict, "CACertFile",
 +                                      DBUS_TYPE_STRING, &str);
 +
 +              str = connman_network_get_string(network,
 +                              "WiFi.ClientCertFile");
 +              if (str != NULL)
 +                      connman_dbus_dict_append_basic(dict, "ClientCertFile",
 +                                      DBUS_TYPE_STRING, &str);
 +
 +              str = connman_network_get_string(network,
 +                              "WiFi.PrivateKeyFile");
 +              if (str != NULL)
 +                      connman_dbus_dict_append_basic(dict, "PrivateKeyFile",
 +                                      DBUS_TYPE_STRING, &str);
 +      }
 +}
 +#endif
 +
  static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
                                        struct connman_service *service)
  {
        const char *str;
        GSList *list;
  
-       unsigned char *wifi_vsie;
 +#if defined TIZEN_EXT
 +      unsigned int frequency = 0U;
 +      if (service && service->network) {
 +              frequency = connman_network_get_frequency(service->network);
 +              connman_dbus_dict_append_basic(dict, "Frequency",
 +                              DBUS_TYPE_UINT16, &frequency);
 +      }
-       GSList *vsie_list = NULL;
-       if (service->network)
-               vsie_list = (GSList *)connman_network_get_vsie_list(service->network);
-       if (vsie_list) {
-               DBG("ConnMan, service->path=%s No.of elements in list: %d", service->path, g_slist_length(vsie_list));
-               GSList *list;
-               for (list = vsie_list; list; list = list->next) {
-                       wifi_vsie = (unsigned char *)list->data;
-                       wifi_vsie_len = wifi_vsie[1] + 2;
-                       connman_dbus_dict_append_fixed_array(dict, "Vsie", DBUS_TYPE_BYTE,
-                                       &wifi_vsie, wifi_vsie_len);
-               }
++      const void *wifi_vsie;
 +      unsigned int wifi_vsie_len;
++      wifi_vsie = connman_network_get_blob(service->network, "WiFi.Vsie", &wifi_vsie_len);
++      if(wifi_vsie_len > 0) {
++              DBG("ConnMan, service->path=%s vsie length=%d", service->path, wifi_vsie_len);
 +      }
++      connman_dbus_dict_append_fixed_array(dict, "Vsie", DBUS_TYPE_BYTE,
++                      &wifi_vsie, wifi_vsie_len);
 +#endif
 +
        str = __connman_service_type2string(service->type);
        if (str)
                connman_dbus_dict_append_basic(dict, "Type",
                connman_dbus_dict_append_basic(dict, "State",
                                                DBUS_TYPE_STRING, &str);
  
 +#ifdef TIZEN_EXT
 +      str = state2string(service->state_ipv6);
 +      if (str != NULL)
 +              connman_dbus_dict_append_basic(dict, "StateIPv6",
 +                              DBUS_TYPE_STRING, &str);
 +#endif
 +
        str = error2string(service->error);
        if (str)
                connman_dbus_dict_append_basic(dict, "Error",
                                                append_ethernet, service);
                break;
        case CONNMAN_SERVICE_TYPE_WIFI:
 +#if defined TIZEN_EXT
 +              if (service->network != NULL)
 +                      append_wifi_ext_info(dict, service->network);
 +
 +              connman_dbus_dict_append_dict(dict, "Ethernet",
 +                                              append_ethernet, service);
 +
 +              connman_dbus_dict_append_basic(dict, "DisconnectReason",
 +                              DBUS_TYPE_INT32, &service->disconnect_reason);
 +
 +              connman_dbus_dict_append_basic(dict, "AssocStatusCode",
 +                              DBUS_TYPE_INT32, &service->assoc_status_code);
 +
 +              break;
 +#endif
        case CONNMAN_SERVICE_TYPE_ETHERNET:
        case CONNMAN_SERVICE_TYPE_BLUETOOTH:
        case CONNMAN_SERVICE_TYPE_GADGET:
@@@ -3581,54 -2635,6 +3627,54 @@@ char **connman_service_get_timeservers(
        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)
  {
@@@ -3716,18 -2722,6 +3762,18 @@@ const char *connman_service_get_proxy_a
        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)
  {
@@@ -3855,22 -2849,6 +3901,22 @@@ void __connman_service_set_pac(struct c
        proxy_changed(service);
  }
  
 +#if defined TIZEN_EXT
 +void __connman_service_set_proxy(struct connman_service *service,
 +                                       const char *proxies)
 +{
 +       char **proxies_array = NULL;
 +
 +       g_strfreev(service->proxies);
 +       service->proxies = NULL;
 +
 +       if (proxies != NULL)
 +               proxies_array = g_strsplit(proxies, " ", 0);
 +
 +       service->proxies = proxies_array;
 +}
 +#endif
 +
  void __connman_service_set_identity(struct connman_service *service,
                                        const char *identity)
  {
                                        service->identity);
  }
  
+ void __connman_service_set_anonymous_identity(struct connman_service *service,
+                                               const char *anonymous_identity)
+ {
+       if (service->immutable || service->hidden)
+               return;
+       g_free(service->anonymous_identity);
+       service->anonymous_identity = g_strdup(anonymous_identity);
+       if (service->network)
+               connman_network_set_string(service->network,
+                                       "WiFi.AnonymousIdentity",
+                                       service->anonymous_identity);
+ }
+ void __connman_service_set_subject_match(struct connman_service *service,
+                                               const char *subject_match)
+ {
+       if (service->immutable || service->hidden)
+               return;
+       g_free(service->subject_match);
+       service->subject_match = g_strdup(subject_match);
+       if (service->network)
+               connman_network_set_string(service->network,
+                                       "WiFi.SubjectMatch",
+                                       service->subject_match);
+ }
+ void __connman_service_set_altsubject_match(struct connman_service *service,
+                                               const char *altsubject_match)
+ {
+       if (service->immutable || service->hidden)
+               return;
+       g_free(service->altsubject_match);
+       service->altsubject_match = g_strdup(altsubject_match);
+       if (service->network)
+               connman_network_set_string(service->network,
+                                       "WiFi.AltSubjectMatch",
+                                       service->altsubject_match);
+ }
+ void __connman_service_set_domain_suffix_match(struct connman_service *service,
+                                               const char *domain_suffix_match)
+ {
+       if (service->immutable || service->hidden)
+               return;
+       g_free(service->domain_suffix_match);
+       service->domain_suffix_match = g_strdup(domain_suffix_match);
+       if (service->network)
+               connman_network_set_string(service->network,
+                                       "WiFi.DomainSuffixMatch",
+                                       service->domain_suffix_match);
+ }
+ void __connman_service_set_domain_match(struct connman_service *service,
+                                               const char *domain_match)
+ {
+       if (service->immutable || service->hidden)
+               return;
+       g_free(service->domain_match);
+       service->domain_match = g_strdup(domain_match);
+       if (service->network)
+               connman_network_set_string(service->network,
+                                       "WiFi.DomainMatch",
+                                       service->domain_match);
+ }
  void __connman_service_set_agent_identity(struct connman_service *service,
                                                const char *agent_identity)
  {
                                        service->agent_identity);
  }
  
static int check_passphrase(enum connman_service_security security,
int __connman_service_check_passphrase(enum connman_service_security security,
                const char *passphrase)
  {
        guint i;
        case CONNMAN_SERVICE_SECURITY_UNKNOWN:
        case CONNMAN_SERVICE_SECURITY_NONE:
        case CONNMAN_SERVICE_SECURITY_WPA:
 +#if !defined TIZEN_EXT
        case CONNMAN_SERVICE_SECURITY_RSN:
 +#endif
  
                DBG("service security '%s' (%d) not handled",
                                security2string(security), security);
                return -EOPNOTSUPP;
  
        case CONNMAN_SERVICE_SECURITY_PSK:
 +#if defined TIZEN_EXT
 +      case CONNMAN_SERVICE_SECURITY_RSN:
 +#endif
                /* A raw key is always 64 bytes length,
                 * its content is in hex representation.
                 * A PSK key must be between [8..63].
@@@ -3971,15 -3019,8 +4092,15 @@@ int __connman_service_set_passphrase(st
        if (service->immutable &&
                        service->security != CONNMAN_SERVICE_SECURITY_8021X)
                return -EINVAL;
 -
 +#if defined TIZEN_EXT
 +      /* The encrypted passphrase is used here
 +       * and validation is done by net-config before being encrypted.
 +       */
 +      if (service->security != CONNMAN_SERVICE_SECURITY_PSK &&
 +                      service->security != CONNMAN_SERVICE_SECURITY_RSN &&
 +                      service->security != CONNMAN_SERVICE_SECURITY_WEP)
 +#endif
-       err = check_passphrase(service->security, passphrase);
+       err = __connman_service_check_passphrase(service->security, passphrase);
  
        if (err < 0)
                return err;
@@@ -4009,8 -3050,6 +4130,6 @@@ static DBusMessage *get_properties(DBus
        DBusMessage *reply;
        DBusMessageIter array, dict;
  
-       DBG("service %p", service);
        reply = dbus_message_new_method_return(msg);
        if (!reply)
                return NULL;
        return reply;
  }
  
+ static char **remove_empty_strings(char **strv)
+ {
+       int index = 0;
+       char **iter = strv;
+       while (*iter) {
+               if (**iter)
+                       strv[index++] = *iter;
+               else
+                       g_free(*iter);
+               iter++;
+       }
+       strv[index] = NULL;
+       return strv;
+ }
  static int update_proxy_configuration(struct connman_service *service,
                                DBusMessageIter *array)
  {
                if (servers_str) {
                        g_strfreev(service->proxies);
  
-                       if (servers_str->len > 0)
-                               service->proxies = g_strsplit_set(
+                       if (servers_str->len > 0) {
+                               char **proxies = g_strsplit_set(
                                        servers_str->str, " ", 0);
-                       else
+                               proxies = remove_empty_strings(proxies);
+                               service->proxies = proxies;
+                       } else
                                service->proxies = NULL;
                }
  
                if (excludes_str) {
                        g_strfreev(service->excludes);
  
-                       if (excludes_str->len > 0)
-                               service->excludes = g_strsplit_set(
+                       if (excludes_str->len > 0) {
+                               char **excludes = g_strsplit_set(
                                        excludes_str->str, " ", 0);
-                       else
+                               excludes = remove_empty_strings(excludes);
+                               service->excludes = excludes;
+                       } else
                                service->excludes = NULL;
                }
  
                g_free(service->pac);
  
                if (url && strlen(url) > 0)
-                       service->pac = g_strdup(url);
+                       service->pac = g_strstrip(g_strdup(url));
                else
                        service->pac = NULL;
  
@@@ -4239,8 -3299,7 +4379,7 @@@ int __connman_service_reset_ipconfig(st
                new_method = __connman_ipconfig_get_method(new_ipconfig);
        }
  
-       if (is_connecting_state(service, state) ||
-                                       is_connected_state(service, state))
+       if (is_connecting(state) || is_connected(state))
                __connman_network_clear_ipconfig(service->network, ipconfig);
  
        __connman_ipconfig_unref(ipconfig);
        else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
                service->ipconfig_ipv6 = new_ipconfig;
  
-       if (is_connecting_state(service, state) ||
-                                       is_connected_state(service, state))
+       if (is_connecting(state) || is_connected(state))
                __connman_ipconfig_enable(new_ipconfig);
  
        if (new_state && new_method != old_method) {
                else
                        *new_state = service->state_ipv6;
  
+               settings_changed(service, new_ipconfig);
+               address_updated(service, new_method);
                __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
        }
  
@@@ -4286,21 -3347,6 +4427,21 @@@ static DBusMessage *set_property(DBusCo
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
                return __connman_error_invalid_arguments(msg);
  
-       if (service->type == CONNMAN_SERVICE_TYPE_WIFI && is_connected(service)) {
++      if (service->type == CONNMAN_SERVICE_TYPE_WIFI && is_connected(service->state)) {
 +              uid_t uid;
 +              if (connman_dbus_get_connection_unix_user_sync(conn,
 +                                              dbus_message_get_sender(msg),
 +                                              &uid) < 0) {
 +                      DBG("Can not get unix user id!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +
 +              if (!connman_service_is_user_allowed(service, uid)) {
 +                      DBG("Not allow this user to operate this wifi service now!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +      }
 +
        dbus_message_iter_get_basic(&iter, &name);
        dbus_message_iter_next(&iter);
  
                GString *str;
                int index;
                const char *gw;
 +#if defined TIZEN_EXT
 +              enum connman_ipconfig_type ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
 +              DBG("%s", name);
 +#endif
  
                if (__connman_provider_is_immutable(service->provider) ||
                                service->immutable)
                gw = __connman_ipconfig_get_gateway_from_index(index,
                        CONNMAN_IPCONFIG_TYPE_ALL);
  
++#if !defined TIZEN_EXT
                if (gw && strlen(gw))
                        __connman_service_nameserver_del_routes(service,
                                                CONNMAN_IPCONFIG_TYPE_ALL);
--
++#endif
                dbus_message_iter_recurse(&value, &entry);
  
 +#if defined TIZEN_EXT
 +              /* IPv4/IPv6 Last DNS config method */
 +              int last_dns_ipv4 = service->dns_config_method_ipv4;
 +              int last_dns_ipv6 = service->dns_config_method_ipv6;
 +              DBG("Last DNS Config Method IPv4: %d IPv6: %d", last_dns_ipv4, last_dns_ipv6);
 +#endif
 +
                while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
                        const char *val;
                        dbus_message_iter_get_basic(&entry, &val);
                        dbus_message_iter_next(&entry);
 +#ifdef TIZEN_EXT
 +                      /* First unpack the DNS Config Method */
 +                      DBG("DNS Config Method: %s", val);
 +                      if((g_strcmp0(val, "ipv4.manual") == 0)) {
 +                              service->dns_config_method_ipv4 =
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL;
 +
 +                              if(last_dns_ipv4 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
 +                                      if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
 +                                              ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
 +                                      else
 +                                              ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
 +                              }
 +                              continue;
 +                      } else if(g_strcmp0(val, "ipv4.dhcp") == 0) {
 +                              service->dns_config_method_ipv4 =
 +                                      CONNMAN_DNSCONFIG_METHOD_DHCP;
 +                              if(last_dns_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
 +                                      ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
  
-                       if (connman_inet_check_ipaddress(val) > 0) {
-                               if (str->len > 0)
-                                       g_string_append_printf(str, " %s", val);
-                               else
-                                       g_string_append(str, val);
-                       }
 +                              continue;
 +                      } else if(g_strcmp0(val, "ipv6.manual") == 0) {
 +                              service->dns_config_method_ipv6 =
 +                                      CONNMAN_DNSCONFIG_METHOD_MANUAL;
 +                              if(last_dns_ipv6 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
 +                                      if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
 +                                              ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
 +                                      else
 +                                              ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
 +                              }
 +                              continue;
 +                      } else if(g_strcmp0(val, "ipv6.dhcp") == 0) {
 +                              service->dns_config_method_ipv6 =
 +                                      CONNMAN_DNSCONFIG_METHOD_DHCP;
 +                              if(last_dns_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
 +                                      ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
 +
 +                              continue;
 +                      }
 +#endif
+                       if (!val[0])
+                               continue;
+                       if (str->len > 0)
+                               g_string_append_printf(str, " %s", val);
+                       else
+                               g_string_append(str, val);
                }
  
-               nameserver_remove_all(service);
 +#if defined TIZEN_EXT
 +              if (service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_DHCP &&
 +                      service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_DHCP) {
 +                                      DBG("Both IPv4 and IPv6 DNS Method DHCP");
 +                                      ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
 +              }
 +              if (gw && strlen(gw))
 +                      __connman_service_nameserver_del_routes(service,
 +                                              ip_type);
 +
 +              DBG("%s ip_type: %d nameserver remove all", name, ip_type);
 +              nameserver_remove_all(service, ip_type);
 +#else
+               nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
 +#endif
                g_strfreev(service->nameservers_config);
  
                if (str->len > 0) {
-                       service->nameservers_config =
-                               g_strsplit_set(str->str, " ", 0);
+                       char **nameservers, **iter;
+                       nameservers = g_strsplit_set(str->str, " ", 0);
+                       for (iter = nameservers; *iter; iter++)
+                               if (connman_inet_check_ipaddress(*iter) <= 0)
+                                       *iter[0] = '\0';
+                       nameservers = remove_empty_strings(nameservers);
+                       service->nameservers_config = nameservers;
                } else {
                        service->nameservers_config = NULL;
                }
                if (gw && strlen(gw))
                        __connman_service_nameserver_add_routes(service, gw);
  
-               nameserver_add_all(service);
 +#if defined TIZEN_EXT
 +              DBG("%s ip_type: %d nameserver add all", name, ip_type);
 +              nameserver_add_all(service, ip_type);
 +#else
+               nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
 +#endif
                dns_configuration_changed(service);
  
                if (__connman_service_is_connected_state(service,
                service_save(service);
        } else if (g_str_equal(name, "Timeservers.Configuration")) {
                DBusMessageIter entry;
-               GSList *list = NULL;
-               int count = 0;
+               GString *str;
  
                if (service->immutable)
                        return __connman_error_not_supported(msg);
                if (type != DBUS_TYPE_ARRAY)
                        return __connman_error_invalid_arguments(msg);
  
+               str = g_string_new(NULL);
+               if (!str)
+                       return __connman_error_invalid_arguments(msg);
                dbus_message_iter_recurse(&value, &entry);
  
                while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
                        const char *val;
-                       GSList *new_head;
                        dbus_message_iter_get_basic(&entry, &val);
+                       dbus_message_iter_next(&entry);
  
-                       new_head = __connman_timeserver_add_list(list, val);
-                       if (list != new_head) {
-                               count++;
-                               list = new_head;
-                       }
+                       if (!val[0])
+                               continue;
  
-                       dbus_message_iter_next(&entry);
+                       if (str->len > 0)
+                               g_string_append_printf(str, " %s", val);
+                       else
+                               g_string_append(str, val);
                }
  
                g_strfreev(service->timeservers_config);
                service->timeservers_config = NULL;
  
-               if (list) {
-                       service->timeservers_config = g_new0(char *, count+1);
+               if (str->len > 0) {
+                       char **timeservers = g_strsplit_set(str->str, " ", 0);
+                       timeservers = remove_empty_strings(timeservers);
+                       service->timeservers_config = timeservers;
+               } else
+                       service->timeservers = NULL;
  
-                       while (list) {
-                               count--;
-                               service->timeservers_config[count] = list->data;
-                               list = g_slist_delete_link(list, list);
-                       };
-               }
+               g_string_free(str, TRUE);
  
                service_save(service);
                timeservers_configuration_changed(service);
                        const char *val;
                        dbus_message_iter_get_basic(&entry, &val);
                        dbus_message_iter_next(&entry);
+                       if (!val[0])
+                               continue;
                        if (str->len > 0)
                                g_string_append_printf(str, " %s", val);
                        else
                searchdomain_remove_all(service);
                g_strfreev(service->domains);
  
-               if (str->len > 0)
-                       service->domains = g_strsplit_set(str->str, " ", 0);
-               else
+               if (str->len > 0) {
+                       char **domains = g_strsplit_set(str->str, " ", 0);
+                       domains = remove_empty_strings(domains);
+                       service->domains = domains;
+               } else
                        service->domains = NULL;
  
                g_string_free(str, TRUE);
                                                                &state);
  
                if (err < 0) {
-                       if (is_connected_state(service, state) ||
-                                       is_connecting_state(service, state)) {
+                       if (is_connected(state) || is_connecting(state)) {
                                if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                                        __connman_network_enable_ipconfig(service->network,
                                                        service->ipconfig_ipv4);
                else
                        ipv6_configuration_changed(service);
  
-               if (is_connecting(service) || is_connected(service)) {
+               if (is_connecting(service->state) ||
+                               is_connected(service->state)) {
                        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                                __connman_network_enable_ipconfig(service->network,
                                                                service->ipconfig_ipv4);
@@@ -4653,10 -3646,8 +4811,10 @@@ static void set_error(struct connman_se
        if (!service->path)
                return;
  
 +#if !defined TIZEN_EXT
        if (!allow_property_changed(service))
                return;
 +#endif
  
        str = error2string(service->error);
  
                                DBUS_TYPE_STRING, &str);
  }
  
+ static void remove_timeout(struct connman_service *service)
+ {
+       if (service->timeout > 0) {
+               g_source_remove(service->timeout);
+               service->timeout = 0;
+       }
+ }
+ static void reply_pending(struct connman_service *service, int error)
+ {
+       remove_timeout(service);
+       if (service->pending) {
+               connman_dbus_reply_pending(service->pending, error, NULL);
+               service->pending = NULL;
+       }
+       if (service->provider_pending) {
+               connman_dbus_reply_pending(service->provider_pending,
+                               error, service->path);
+               service->provider_pending = NULL;
+       }
+ }
+ static void service_complete(struct connman_service *service)
+ {
+       reply_pending(service, EIO);
+       if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
+               __connman_service_auto_connect(service->connect_reason);
+       g_get_current_time(&service->modified);
+       service_save(service);
+ }
 +static void set_idle(struct connman_service *service)
 +{
 +      service->state = service->state_ipv4 = service->state_ipv6 =
 +                                              CONNMAN_SERVICE_STATE_IDLE;
 +      set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
 +      state_changed(service);
 +}
 +
  static DBusMessage *clear_property(DBusConnection *conn,
                                        DBusMessage *msg, void *user_data)
  {
        if (g_str_equal(name, "Error")) {
                set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
  
-               g_get_current_time(&service->modified);
-               service_save(service);
+               __connman_service_clear_error(service);
+               service_complete(service);
        } else
                return __connman_error_invalid_property(msg);
  
@@@ -4746,6 -3764,7 +4939,7 @@@ static void disconnect_on_last_session(
  }
  
  static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
+ static int always_connect[MAX_CONNMAN_SERVICE_TYPES] = {};
  static int active_count = 0;
  
  void __connman_service_set_active_session(bool enable, GSList *list)
        else
                active_count--;
  
-       while (list != NULL) {
+       while (list) {
                enum connman_service_type type = GPOINTER_TO_INT(list->data);
  
                switch (type) {
@@@ -4830,24 -3849,13 +5024,24 @@@ static GList *preferred_tech_list_get(v
                for (list = service_list; list; list = list->next) {
                        struct connman_service *service = list->data;
  
-                       if (!is_connected(service))
+                       if (!is_connected(service->state))
                                break;
  
                        if (service->connect_reason ==
                                        CONNMAN_SERVICE_CONNECT_REASON_USER) {
                                DBG("service %p name %s is user connected",
                                                service, service->name);
 +#if defined TIZEN_EXT
 +                              /* We can connect to a favorite service like
 +                               * wifi even we have a userconnect for cellular
 +                               * because we have refount for cellular service
 +                               */
 +                              if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +                                      break;
 +
 +                              if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
 +                                      break;
 +#endif
                                return NULL;
                        }
                }
        return tech_data.preferred_list;
  }
  
+ static void set_always_connecting_technologies()
+ {
+       unsigned int *always_connected_techs =
+               connman_setting_get_uint_list("AlwaysConnectedTechnologies");
+       int i;
+       for (i = 0; always_connected_techs && always_connected_techs[i]; i++)
+               always_connect[always_connected_techs[i]] = 1;
+ }
+ static bool autoconnect_no_session_active(struct connman_service *service)
+ {
+       /*
+        * Test active_count to see if there are no sessions set up and
+        * stop autoconnecting, but continue connecting if the service
+        * belongs to a technology which should always autoconnect.
+        */
+       if (!active_count && !always_connect[service->type])
+               return true;
+       return false;
+ }
+ static bool autoconnect_already_connecting(struct connman_service *service,
+                                          bool autoconnecting)
+ {
+       /*
+        * If another service is already connecting and this service type has
+        * not been marked as always connecting, stop the connecting procedure.
+        */
+       if (autoconnecting &&
+                       !active_sessions[service->type] &&
+                       !always_connect[service->type])
+               return true;
+       return false;
+ }
  static bool auto_connect_service(GList *services,
                                enum connman_service_connect_reason reason,
                                bool preferred)
                        continue;
                }
  
-                       if (is_connecting(service) == TRUE || is_connected(service) == TRUE)
 +#if defined TIZEN_EXT
 +              DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)",
 +                              service, service->name,
 +                              state2string(service->state),
 +                              __connman_service_type2string(service->type),
 +                              service->favorite, is_ignore(service),
 +                              service->hidden, service->hidden_service);
 +
 +              /* Tizen takes Wi-Fi as the highest priority into consideration. */
 +              if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
++                      if (is_connecting(service->state) == TRUE || is_connected(service->state) == TRUE)
 +                              continue;
 +#endif
 +
                if (service->pending ||
-                               is_connecting(service) ||
-                               is_connected(service)) {
-                       if (!active_count)
-                               return true;
+                               is_connecting(service->state) ||
+                               is_connected(service->state)) {
+                       if (autoconnect_no_session_active(service))
+                                       return true;
  
                        ignore[service->type] = true;
                        autoconnecting = true;
                        if (preferred)
                               continue;
  
 +#if defined TIZEN_EXT
 +                      DBG("Service is not favorite, autoconnecting %d",
 +                                      autoconnecting);
 +#endif
                        return autoconnecting;
                }
  
 +#if defined TIZEN_EXT
 +              DBG("service %p identifier %s roaming %d ignore %d "
 +                              "ipconfig_usable %d autoconnect %d state %d",
 +                              service,
 +                              service->identifier, service->roaming,
 +                              service->ignore, is_ipconfig_usable(service),
 +                              service->autoconnect, service->state);
 +#endif
                if (is_ignore(service) || service->state !=
                                CONNMAN_SERVICE_STATE_IDLE)
                        continue;
  
-               if (autoconnecting && !active_sessions[service->type]) {
+               if (autoconnect_already_connecting(service, autoconnecting)) {
                        DBG("service %p type %s has no users", service,
                                __connman_service_type2string(service->type));
                        continue;
                }
  
 +              if (!is_service_owner_user_login(service)) {
 +                      DBG("favorite user not login, wifi auto connect denied");
 +                      continue;
 +              }
 +
                DBG("service %p %s %s", service, service->name,
                        (preferred) ? "preferred" : reason2string(reason));
  
                __connman_service_connect(service, reason);
  
-               if (!active_count)
+               if (autoconnect_no_session_active(service))
                        return true;
  
                ignore[service->type] = true;
@@@ -4985,21 -3999,6 +5216,21 @@@ static gboolean run_auto_connect(gpoint
        return FALSE;
  }
  
 +#if defined TIZEN_EXT
 +bool __connman_service_get_auto_connect_mode(void)
 +{
 +      return auto_connect_mode;
 +}
 +
 +void __connman_service_set_auto_connect_mode(bool enable)
 +{
 +      DBG("set auto_connect_mode = %d", enable);
 +
 +      if (auto_connect_mode != enable)
 +              auto_connect_mode = enable;
 +}
 +#endif
 +
  void __connman_service_auto_connect(enum connman_service_connect_reason reason)
  {
        DBG("");
        if (autoconnect_timeout != 0)
                return;
  
 +#if defined TIZEN_EXT
 +      if (auto_connect_mode == FALSE) {
 +              DBG("Currently, not auto connection mode");
 +              return;
 +      }
 +#endif
 +
        if (!__connman_session_policy_autoconnect(reason))
                return;
  
-       autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect,
 +#if defined TIZEN_EXT
 +      /* Adding Timeout of 500ms before trying to auto connect.
 +       * This is done because of below scenario
 +       * 1. Device is connected to AP1
 +       * 2. WPS Connection request is initiated for AP2
 +       * 3. Immediately WPS Connection is Cancelled
 +       * When WPS Connection Connection is initiated for AP2 then
 +       * sometimes there is a scenario where connman gets in ASSOCIATED
 +       * state with AP1 due to autoconnect and subsequently the connection
 +       * initiated by AP1 fails and connman service for AP1 comes in
 +       * FAILURE state due to this when connection with AP2 is cancelled
 +       * then autoconnect with AP1 doesn't works because its autoconnection
 +       * is ignored as its last state was FAILURE rather than IDLE */
 +      autoconnect_timeout = g_timeout_add(500, run_auto_connect,
 +#else
+       autoconnect_timeout = g_idle_add(run_auto_connect,
 +#endif
                                                GUINT_TO_POINTER(reason));
  }
  
@@@ -5050,7 -4026,8 +5281,8 @@@ static gboolean run_vpn_auto_connect(gp
                if (service->type != CONNMAN_SERVICE_TYPE_VPN)
                        continue;
  
-               if (is_connected(service) || is_connecting(service)) {
+               if (is_connected(service->state) ||
+                               is_connecting(service->state)) {
                        if (!service->do_split_routing)
                                need_split = true;
                        continue;
@@@ -5086,31 -4063,7 +5318,7 @@@ static void vpn_auto_connect(void
                return;
  
        vpn_autoconnect_timeout =
-               g_timeout_add_seconds(0, run_vpn_auto_connect, NULL);
- }
- static void remove_timeout(struct connman_service *service)
- {
-       if (service->timeout > 0) {
-               g_source_remove(service->timeout);
-               service->timeout = 0;
-       }
- }
- static void reply_pending(struct connman_service *service, int error)
- {
-       remove_timeout(service);
-       if (service->pending) {
-               connman_dbus_reply_pending(service->pending, error, NULL);
-               service->pending = NULL;
-       }
-       if (service->provider_pending) {
-               connman_dbus_reply_pending(service->provider_pending,
-                                               error, service->path);
-               service->provider_pending = NULL;
-       }
+               g_idle_add(run_vpn_auto_connect, NULL);
  }
  
  bool
@@@ -5187,9 -4140,6 +5395,6 @@@ static gboolean connect_timeout(gpointe
        else if (service->provider)
                connman_provider_disconnect(service->provider);
  
-       __connman_ipconfig_disable(service->ipconfig_ipv4);
-       __connman_ipconfig_disable(service->ipconfig_ipv6);
        __connman_stats_service_unregister(service);
  
        if (service->pending) {
@@@ -5223,68 -4173,20 +5428,68 @@@ static DBusMessage *connect_service(DBu
                                        DBusMessage *msg, void *user_data)
  {
        struct connman_service *service = user_data;
 +#if defined TIZEN_EXT
 +      int err = 0;
 +#else
        int index, err = 0;
        GList *list;
 +#endif
  
        DBG("service %p", service);
  
 +#if defined TIZEN_EXT
 +      /*
 +       * Description: TIZEN implements system global connection management.
 +       */
 +      if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +              connman_service_user_pdn_connection_ref(service);
 +
 +      /*Reset the Disconnect Reason while issue connect request*/
 +      service->disconnect_reason = 0;
 +
 +      /*Reset the association status code while issue connect request*/
 +      service->assoc_status_code = 0;
 +#endif
 +
        if (service->pending)
                return __connman_error_in_progress(msg);
  
 +      if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
 +              uid_t uid;
 +              if (connman_dbus_get_connection_unix_user_sync(conn,
 +                                              dbus_message_get_sender(msg),
 +                                              &uid) < 0) {
 +                      DBG("Can not get unix user id!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +
 +              if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
 +                      DBG("Not allow this user to connect this wifi service now!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +
 +              if (uid != USER_ROOT && uid != service->user.favorite_user)
 +                      service->request_passphrase_input = true;
 +
 +              service->user.current_user = uid;
 +
 +              if (!service->passphrase && uid == service->user.favorite_user) {
 +                      DBG("Now load this favorite user's passphrase.");
 +                      service_load_passphrase(service);
 +              }
 +      }
 +
 +#if !defined TIZEN_EXT
        index = __connman_service_get_index(service);
  
        for (list = service_list; list; list = list->next) {
                struct connman_service *temp = list->data;
  
-               if (!is_connecting(temp) && !is_connected(temp))
 +#if defined TIZEN_EXT
 +              if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +                      break;
 +#endif
+               if (!is_connecting(temp->state) && !is_connected(temp->state))
                        break;
  
                if (service == temp)
        }
        if (err == -EINPROGRESS)
                return __connman_error_operation_timeout(msg);
 +#endif
  
        service->ignore = false;
  
@@@ -5331,35 -4232,6 +5536,35 @@@ static DBusMessage *disconnect_service(
  
        DBG("service %p", service);
  
-               if (is_connected(service) == TRUE &&
 +#if defined TIZEN_EXT
 +      /*
 +       * Description: TIZEN implements system global connection management.
 +       */
 +      if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
 +              if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE)
 +                      return __connman_error_failed(msg, EISCONN);
 +
++              if (is_connected(service->state) == TRUE &&
 +                              service == connman_service_get_default_connection())
 +                      return __connman_error_failed(msg, EISCONN);
 +      }
 +#endif
 +
 +      if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
 +              uid_t uid;
 +              if (connman_dbus_get_connection_unix_user_sync(conn,
 +                                              dbus_message_get_sender(msg),
 +                                              &uid) < 0) {
 +                      DBG("Can not get unix user id!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +
 +              if (!connman_service_is_user_allowed(service, uid)) {
 +                      DBG("Not allow this user to disconnect this wifi service now!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +      }
 +
        service->ignore = true;
  
        err = __connman_service_disconnect(service);
        return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
  }
  
 +#if defined TIZEN_EXT
 +static void __connman_service_cleanup_network_8021x(struct connman_service *service)
 +{
 +      if (service == NULL)
 +              return;
 +
 +      DBG("service %p ", service);
 +
 +      connman_network_set_string(service->network, "WiFi.EAP", NULL);
 +      connman_network_set_string(service->network, "WiFi.Identity", NULL);
 +      connman_network_set_string(service->network, "WiFi.CACertFile", NULL);
 +      connman_network_set_string(service->network, "WiFi.ClientCertFile", NULL);
 +      connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL);
 +      connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL);
 +      connman_network_set_string(service->network, "WiFi.Phase2", NULL);
 +}
 +#endif
 +
  bool __connman_service_remove(struct connman_service *service)
  {
        if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
                        __connman_provider_is_immutable(service->provider))
                return false;
  
-       if (!service->favorite && service->state !=
-                                               CONNMAN_SERVICE_STATE_FAILURE)
 +#if !defined TIZEN_EXT
+       if (!service->favorite && !is_idle(service->state))
                return false;
 +#endif
  
        __connman_service_disconnect(service);
  
        g_free(service->identity);
        service->identity = NULL;
  
+       g_free(service->anonymous_identity);
+       service->anonymous_identity = NULL;
+       g_free(service->subject_match);
+       service->subject_match = NULL;
+       g_free(service->altsubject_match);
+       service->altsubject_match = NULL;
+       g_free(service->domain_suffix_match);
+       service->domain_suffix_match = NULL;
+       g_free(service->domain_match);
+       service->domain_match = NULL;
        g_free(service->agent_identity);
        service->agent_identity = NULL;
  
        g_free(service->eap);
        service->eap = NULL;
  
 +#if defined TIZEN_EXT
 +      g_free(service->ca_cert_file);
 +      service->ca_cert_file = NULL;
 +
 +      g_free(service->client_cert_file);
 +      service->client_cert_file = NULL;
 +
 +      g_free(service->private_key_file);
 +      service->private_key_file = NULL;
 +
 +      g_free(service->private_key_passphrase);
 +      service->private_key_passphrase = NULL;
 +
 +      g_free(service->phase2);
 +      service->phase2 = NULL;
 +
 +      __connman_service_cleanup_network_8021x(service);
 +
 +      __connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP);
 +      __connman_ipconfig_set_method(service->ipconfig_ipv6, CONNMAN_IPCONFIG_METHOD_AUTO);
 +      connman_service_set_proxy(service, NULL, false);
 +
 +      __connman_service_nameserver_clear(service);
 +
 +      g_strfreev(service->nameservers_config);
 +      service->nameservers_config = NULL;
 +
 +#endif
 +
 +#if defined TIZEN_EXT
 +      if (service->security != CONNMAN_SERVICE_SECURITY_8021X)
 +#endif
 +      set_idle(service);
 +
        service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
  
 +      service->user.favorite_user = USER_NONE;
 +
        __connman_service_set_favorite(service, false);
  
        __connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6);
  
 +#if defined TIZEN_EXT
 +      /* Reset IP Method and DNS Method to DHCP */
 +      __connman_ipconfig_set_method(service->ipconfig_ipv4,
 +                      CONNMAN_IPCONFIG_METHOD_DHCP);
 +      service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
 +      g_strfreev(service->nameservers_config);
 +      service->nameservers_config = NULL;
 +#endif
 +
 +#if defined TIZEN_EXT
 +      __connman_storage_remove_service(service->identifier);
 +#else
        service_save(service);
 +#endif
  
        return true;
  }
@@@ -5484,23 -4301,6 +5703,23 @@@ static DBusMessage *remove_service(DBus
  
        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);
  
@@@ -5613,11 -4413,11 +5832,11 @@@ static DBusMessage *move_service(DBusCo
                        return __connman_error_invalid_service(msg);
                }
  
-               target->do_split_routing = true;
+               set_split_routing(target, true);
        } else
-               target->do_split_routing = false;
+               set_split_routing(target, false);
  
-       service->do_split_routing = false;
+       set_split_routing(service, false);
  
        target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
        target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
@@@ -5710,30 -4510,6 +5929,30 @@@ static DBusMessage *reset_counters(DBus
        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;
@@@ -5746,23 -4522,17 +5965,23 @@@ static void service_append_added_foreac
        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);
        }
@@@ -5850,15 -4620,9 +6069,13 @@@ static void service_schedule_removed(st
  
  static bool allow_property_changed(struct connman_service *service)
  {
 +#if defined TIZEN_EXT
 +      if (service->path == NULL)
 +              return FALSE;
 +#endif
        if (g_hash_table_lookup_extended(services_notify->add, service->path,
-                                       NULL, NULL)) {
-               DBG("no property updates for service %p", service);
+                                       NULL, NULL))
                return false;
-       }
  
        return true;
  }
@@@ -5885,9 -4649,6 +6102,9 @@@ static const GDBusMethodTable service_m
                        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) },
        { },
  };
  
@@@ -5906,6 -4667,11 +6123,11 @@@ static void service_free(gpointer user_
  
        reply_pending(service, ENOENT);
  
+       if (service->nameservers_timeout) {
+               g_source_remove(service->nameservers_timeout);
+               dns_changed(service);
+       }
        __connman_notifier_service_remove(service);
        service_schedule_removed(service);
  
        g_free(service->identifier);
        g_free(service->eap);
        g_free(service->identity);
+       g_free(service->anonymous_identity);
        g_free(service->agent_identity);
        g_free(service->ca_cert_file);
+       g_free(service->subject_match);
+       g_free(service->altsubject_match);
+       g_free(service->domain_suffix_match);
+       g_free(service->domain_match);
        g_free(service->client_cert_file);
        g_free(service->private_key_file);
        g_free(service->private_key_passphrase);
@@@ -6018,11 -4789,6 +6245,11 @@@ static void service_initialize(struct c
  
        service->ignore = false;
  
 +      service->user.favorite_user = USER_NONE;
 +      service->user.current_user = USER_NONE;
 +
 +      service->request_passphrase_input = false;
 +
        service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
  
        service->order = 0;
        service->provider = NULL;
  
        service->wps = false;
 +#if defined TIZEN_EXT
 +      service->storage_reload = false;
 +      /*
 +       * Description: TIZEN implements system global connection management.
 +       */
 +      service->user_pdn_connection_refcount = 0;
 +      __sync_synchronize();
 +#endif
  }
  
  /**
@@@ -6138,8 -4896,8 +6365,8 @@@ static gint service_compare(gconstpoint
  
        state_a = service_a->state;
        state_b = service_b->state;
-       a_connected = is_connected(service_a);
-       b_connected = is_connected(service_b);
+       a_connected = is_connected(state_a);
+       b_connected = is_connected(state_b);
  
        if (a_connected && b_connected) {
                if (service_a->order > service_b->order)
                if (b_connected)
                        return 1;
  
-               if (is_connecting(service_a))
+               if (is_connecting(state_a))
                        return -1;
-               if (is_connecting(service_b))
+               if (is_connecting(state_b))
                        return 1;
        }
  
                return 1;
  
        if (service_a->type != service_b->type) {
+               unsigned int *tech_array;
+               int i;
+               tech_array = connman_setting_get_uint_list(
+                                               "PreferredTechnologies");
+               if (tech_array) {
+                       for (i = 0; tech_array[i]; i++) {
+                               if (tech_array[i] == service_a->type)
+                                       return -1;
+                               if (tech_array[i] == service_b->type)
+                                       return 1;
+                       }
+               }
  
                if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
                        return -1;
@@@ -6224,6 -4996,12 +6465,12 @@@ static void service_list_sort(void
        }
  }
  
+ int __connman_service_compare(const struct connman_service *a,
+                                       const struct connman_service *b)
+ {
+       return service_compare(a, b);
+ }
  /**
   * connman_service_get_type:
   * @service: service structure
@@@ -6257,40 -5035,6 +6504,40 @@@ char *connman_service_get_interface(str
  }
  
  /**
-               if (is_connected(service)) {
 + * __connman_service_is_user_allowed:
 + * @type: service type
 + * @uid: user id
 + *
 + * Check a user is allowed to operate a type of service
 + */
 +bool __connman_service_is_user_allowed(enum connman_service_type type,
 +                                      uid_t uid)
 +{
 +      GList *list;
 +      uid_t owner_user = USER_NONE;
 +
 +      for (list = service_list; list; list = list->next) {
 +              struct connman_service *service = list->data;
 +
 +              if (service->type != type)
 +                      continue;
 +
++              if (is_connected(service->state)) {
 +                      owner_user = service->user.favorite_user;
 +                      break;
 +              }
 +      }
 +
 +      if (uid == USER_NONE ||
 +                      (uid != USER_ROOT &&
 +                      owner_user != USER_NONE &&
 +                      owner_user != uid))
 +              return false;
 +
 +      return true;
 +}
 +
 +/**
   * connman_service_get_network:
   * @service: service structure
   *
@@@ -6345,14 -5089,12 +6592,12 @@@ bool __connman_service_is_connected_sta
        case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
                break;
        case CONNMAN_IPCONFIG_TYPE_IPV4:
-               return is_connected_state(service, service->state_ipv4);
+               return is_connected(service->state_ipv4);
        case CONNMAN_IPCONFIG_TYPE_IPV6:
-               return is_connected_state(service, service->state_ipv6);
+               return is_connected(service->state_ipv6);
        case CONNMAN_IPCONFIG_TYPE_ALL:
-               return is_connected_state(service,
-                                       CONNMAN_IPCONFIG_TYPE_IPV4) &&
-                       is_connected_state(service,
-                                       CONNMAN_IPCONFIG_TYPE_IPV6);
+               return is_connected(service->state_ipv4) &&
+                       is_connected(service->state_ipv6);
        }
  
        return false;
@@@ -6387,53 -5129,6 +6632,53 @@@ void __connman_service_mark_dirty(void
        services_dirty = true;
  }
  
-               if (is_connected(service2) && index2 > 0 && index1 == index2)
 +#if defined TIZEN_EXT
 +/**
 +  * Returns profile count if there is any connected profiles
 +  * that use same interface
 +  */
 +int __connman_service_get_connected_count_of_iface(
 +                                      struct connman_service *service)
 +{
 +      GList *list;
 +      int count = 0;
 +      int index1 = 0;
 +      int index2 = 0;
 +
 +      DBG("");
 +
 +      index1 = __connman_service_get_index(service);
 +
 +      if (index1 <= 0)
 +              return 0;
 +
 +      for (list = service_list; list; list = list->next) {
 +              struct connman_service *service2 = list->data;
 +
 +              if (service == service2)
 +                      continue;
 +
 +              index2 = __connman_service_get_index(service2);
 +
++              if (is_connected(service2->state) && index2 > 0 && index1 == index2)
 +                      count++;
 +
 +              index2 = 0;
 +      }
 +
 +      DBG("Interface index %d, count %d", index1, count);
 +
 +      return count;
 +}
 +
 +void __connman_service_set_storage_reload(struct connman_service *service,
 +                                      bool storage_reload)
 +{
 +      if (service != NULL)
 +              service->storage_reload = storage_reload;
 +}
 +#endif
 +
  /**
   * __connman_service_set_favorite_delayed:
   * @service: service structure
@@@ -6446,10 -5141,6 +6691,10 @@@ int __connman_service_set_favorite_dela
                                        bool favorite,
                                        bool delay_ordering)
  {
 +#if defined TIZEN_EXT
 +      if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +              return -EIO;
 +#endif
        if (service->hidden)
                return -EOPNOTSUPP;
  
@@@ -6535,9 -5226,24 +6780,24 @@@ void __connman_service_set_string(struc
        } else if (g_str_equal(key, "Identity")) {
                g_free(service->identity);
                service->identity = g_strdup(value);
+       } else if (g_str_equal(key, "AnonymousIdentity")) {
+               g_free(service->anonymous_identity);
+               service->anonymous_identity = g_strdup(value);
        } else if (g_str_equal(key, "CACertFile")) {
                g_free(service->ca_cert_file);
                service->ca_cert_file = g_strdup(value);
+       } else if (g_str_equal(key, "SubjectMatch")) {
+               g_free(service->subject_match);
+               service->subject_match = g_strdup(value);
+       } else if (g_str_equal(key, "AltSubjectMatch")) {
+               g_free(service->altsubject_match);
+               service->altsubject_match = g_strdup(value);
+       } else if (g_str_equal(key, "DomainSuffixMatch")) {
+               g_free(service->domain_suffix_match);
+               service->domain_suffix_match = g_strdup(value);
+       } else if (g_str_equal(key, "DomainMatch")) {
+               g_free(service->domain_match);
+               service->domain_match = g_strdup(value);
        } else if (g_str_equal(key, "ClientCertFile")) {
                g_free(service->client_cert_file);
                service->client_cert_file = g_strdup(value);
@@@ -6567,17 -5273,6 +6827,6 @@@ void __connman_service_set_search_domai
        searchdomain_add_all(service);
  }
  
- static void service_complete(struct connman_service *service)
- {
-       reply_pending(service, EIO);
-       if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
-               __connman_service_auto_connect(service->connect_reason);
-       g_get_current_time(&service->modified);
-       service_save(service);
- }
  static void report_error_cb(void *user_context, bool retry,
                                                        void *user_data)
  {
                /* It is not relevant to stay on Failure state
                 * when failing is due to wrong user input */
                __connman_service_clear_error(service);
 +#if defined TIZEN_EXT
 +              /* Reseting the state back in case of failure state */
 +              service->state_ipv4 = service->state_ipv6 =
 +                              CONNMAN_SERVICE_STATE_IDLE;
  
 +              if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED)
 +                      set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
 +#endif
                service_complete(service);
                __connman_connection_update_gateway();
        }
@@@ -6657,7 -5345,8 +6906,8 @@@ static void request_input_cb(struct con
  
                        if (service->hidden)
                                __connman_service_return_error(service,
-                                                       ECANCELED, user_data);
+                                                       ECONNABORTED,
+                                                       user_data);
                        goto done;
                } else {
                        if (service->hidden)
@@@ -6738,7 -5427,7 +6988,7 @@@ static void downgrade_connected_service
        for (list = service_list; list; list = list->next) {
                up_service = list->data;
  
-               if (!is_connected(up_service))
+               if (!is_connected(up_service->state))
                        continue;
  
                if (up_service->state == CONNMAN_SERVICE_STATE_ONLINE)
@@@ -6778,126 -5467,6 +7028,126 @@@ static int service_update_preferred_ord
        return -EALREADY;
  }
  
-       if (is_connected(service) == TRUE || is_connecting(service) == TRUE) {
 +#if defined TIZEN_EXT
 +static gboolean __connman_service_can_drop(struct connman_service *service)
 +{
-       } else if (is_connected(current) == TRUE || is_connecting(current) == TRUE)
++      if (is_connected(service->state) == TRUE || is_connecting(service->state) == TRUE) {
 +              if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
 +                      return TRUE;
 +              else if (connman_service_is_no_ref_user_pdn_connection(service) == TRUE)
 +                      return TRUE;
 +      }
 +      return FALSE;
 +}
 +
 +static struct connman_device *default_connecting_device = NULL;
 +
 +static void __connman_service_disconnect_default(struct connman_service *service)
 +{
 +      struct connman_device *default_device = NULL;
 +
 +      if (default_connecting_device == NULL)
 +              return;
 +
 +      default_device = connman_network_get_device(
 +                      __connman_service_get_network(service));
 +
 +      DBG("Disconnecting service %p %s", service, service->path);
 +      DBG("Disconnecting device %p %p %s",
 +                      default_connecting_device,
 +                      default_device,
 +                      connman_device_get_string(default_device, "Name"));
 +
 +      if (default_connecting_device == default_device)
 +              default_connecting_device = NULL;
 +}
 +
 +static void __connman_service_connect_default(struct connman_service *current)
 +{
 +      int err;
 +      GList *list;
 +      bool default_internet;
 +      struct connman_service *service;
 +      struct connman_service *default_service = NULL;
 +      struct connman_device *default_device = NULL;
 +
 +      if (current->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
 +              switch (current->state) {
 +              case CONNMAN_SERVICE_STATE_UNKNOWN:
 +              case CONNMAN_SERVICE_STATE_ASSOCIATION:
 +              case CONNMAN_SERVICE_STATE_CONFIGURATION:
 +                      return;
 +              default:
 +                      break;
 +              }
 +
 +              if (default_connecting_device &&
 +                              __connman_service_is_internet_profile(current) == TRUE) {
 +                      if (current->network == NULL)
 +                              return;
 +
 +                      default_device = connman_network_get_device(current->network);
 +                      if (default_connecting_device == default_device) {
 +                              DBG("Cellular service[%s]  %p %s",
 +                                              state2string(current->state), current, current->path);
 +                              DBG("Cellular device %p %p %s",
 +                                              default_connecting_device, default_device,
 +                                              connman_device_get_string(default_device, "Name"));
 +
 +                              default_connecting_device = NULL;
 +                      }
 +              }
 +
 +              return;
-                       if (is_connected(default_service) == TRUE ||
-                                       is_connecting(default_service) == TRUE)
++      } else if (is_connected(current->state) == TRUE || is_connecting(current->state) == TRUE)
 +              return;
 +
 +      /* Always-on: keep default cellular connection as possible */
 +      for (list = service_list; list; list = list->next) {
 +              service = list->data;
 +
 +              if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
 +                              __connman_service_is_internet_profile(service) != TRUE ||
 +                              service->network == NULL) {
 +                      continue;
 +              }
 +
 +              default_internet =
 +                              connman_network_get_bool(service->network, "DefaultInternet");
 +
 +              DBG("service: %p %s %s %s (default: %d)", service, service->name,
 +                              __connman_service_type2string(service->type),
 +                              state2string(service->state), default_internet);
 +
 +              if (default_internet) {
 +                      default_service = service;
++                      if (is_connected(default_service->state) == TRUE ||
++                                      is_connecting(default_service->state) == TRUE)
 +                              return;
 +
 +                      default_device = connman_network_get_device(default_service->network);
 +                      if (default_connecting_device == default_device) {
 +                              DBG("Device is connecting (%p)", default_connecting_device);
 +                              return;
 +                      }
 +
 +                      default_connecting_device = default_device;
 +                      default_service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
 +
 +                      err = __connman_network_connect(default_service->network);
 +                      DBG("Connecting default service %p %s [%d]",
 +                                      default_service, default_service->path, err);
 +                      DBG("Connecting device %p %s", default_connecting_device,
 +                                      connman_device_get_string(default_connecting_device, "Name"));
 +                      if (err < 0 && err != -EINPROGRESS) {
 +                              default_connecting_device = NULL;
 +                      } else
 +                              break;
 +              }
 +      }
 +}
 +#endif
 +
  static void single_connected_tech(struct connman_service *allowed)
  {
        struct connman_service *service;
  
        DBG("keeping %p %s", allowed, allowed->path);
  
 +#if defined TIZEN_EXT
 +      if (!allowed || allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +              return;
 +#endif
 +
        for (iter = service_list; iter; iter = iter->next) {
                service = iter->data;
  
-               if (!is_connected(service))
 +#if defined TIZEN_EXT
 +              if (service != allowed && service->type != allowed->type &&
 +                              __connman_service_can_drop(service) == TRUE)
 +#else
+               if (!is_connected(service->state))
                        break;
  
                if (service == allowed)
                        continue;
 -
 +#endif
                services = g_slist_prepend(services, service);
        }
  
                service = list->data;
  
                DBG("disconnecting %p %s", service, service->path);
 +#if defined TIZEN_EXT
 +              __connman_service_disconnect_default(service);
 +#endif
                __connman_service_disconnect(service);
        }
  
        g_slist_free(services);
  }
  
-               if (is_connected(service) == FALSE)
 +#if defined TIZEN_EXT
 +static void set_priority_connected_service(void)
 +{
 +      struct connman_service *service;
 +      GList *list;
 +
 +      for (list = service_list; list; list = list->next) {
 +              service = list->data;
 +
++              if (is_connected(service->state) == FALSE)
 +                      service->order = 5;
 +              else
 +                      service->order = 6;
 +      }
 +}
 +#endif
 +
  static const char *get_dbus_sender(struct connman_service *service)
  {
        if (!service->pending)
@@@ -7000,13 -5540,15 +7250,15 @@@ static int service_indicate_state(struc
        if (old_state == CONNMAN_SERVICE_STATE_ONLINE)
                __connman_notifier_leave_online(service->type);
  
-       if (is_connected_state(service, old_state) &&
-                       !is_connected_state(service, new_state))
+       if (is_connected(old_state) && !is_connected(new_state))
                searchdomain_remove_all(service);
  
        service->state = new_state;
        state_changed(service);
  
+       if (!is_connected(old_state) && is_connected(new_state))
+               searchdomain_add_all(service);
        switch(new_state) {
        case CONNMAN_SERVICE_STATE_UNKNOWN:
  
  
                reply_pending(service, 0);
  
-               g_get_current_time(&service->modified);
-               service_save(service);
-               searchdomain_add_all(service);
-               dns_changed(service);
-               domain_changed(service);
-               proxy_changed(service);
-               if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
-                       __connman_notifier_connect(service->type);
                if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
                        connman_network_get_bool(service->network,
                                                "WiFi.UseWPS")) {
                                                        "WiFi.UseWPS", false);
                }
  
+               g_get_current_time(&service->modified);
+               service_save(service);
+               domain_changed(service);
+               proxy_changed(service);
+               if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
+                       __connman_notifier_connect(service->type);
                method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
                if (method == CONNMAN_IPCONFIG_METHOD_OFF)
                        __connman_ipconfig_disable_ipv6(
                else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
                        vpn_auto_connect();
  
 +#if defined TIZEN_EXT
 +              if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
 +                      set_priority_connected_service();
 +#endif
 +
                break;
  
        case CONNMAN_SERVICE_STATE_ONLINE:
                reply_pending(service, ECONNABORTED);
  
                def_service = __connman_service_get_default();
 +              service->disconnect_reason = connman_network_get_disconnect_reason(service->network);
 +              service->assoc_status_code = connman_network_get_assoc_status_code(service->network);
  
                if (!__connman_notifier_is_connected() &&
                        def_service &&
  
                __connman_wpad_stop(service);
  
-               dns_changed(service);
 +#if defined TIZEN_EXT
 +              /**
 +                * Skip the functions if there is any connected profiles
 +                * that use same interface
 +                */
 +              if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
 +                      __connman_service_get_connected_count_of_iface(
 +                                                      service) <= 0) {
 +#endif
                domain_changed(service);
                proxy_changed(service);
 +#if defined TIZEN_EXT
 +              }
 +#endif
  
                /*
                 * Previous services which are connected and which states
                break;
  
        case CONNMAN_SERVICE_STATE_FAILURE:
 -
 +#if defined TIZEN_EXT
-               service->assoc_status_code = connman_network_get_assoc_status_code(service->network);
 +              if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
 +                      service->order = 5;
 +              __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
 +#endif
                if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
                        connman_agent_report_error(service, service->path,
                                        error2string(service->error),
  
        service_list_sort();
  
 +#if defined TIZEN_EXT
 +      __connman_service_connect_default(service);
 +#endif
 +
        __connman_connection_update_gateway();
  
        if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
                default_changed();
        }
  
 +      if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
 +              service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
 +              (new_state == CONNMAN_SERVICE_STATE_READY ||
 +              new_state == CONNMAN_SERVICE_STATE_ONLINE)) {
 +              if (service->user.favorite_user != service->user.current_user) {
 +                      DBG("Now set service favorite user id from %d to %d",
 +                      service->user.favorite_user, service->user.current_user);
 +
 +                      service->user.favorite_user = service->user.current_user;
 +
 +                      service_save(service);
 +              }
 +      }
 +
        return 0;
  }
  
@@@ -7228,23 -5723,6 +7474,23 @@@ int __connman_service_indicate_error(st
  
        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);
@@@ -7289,7 -5767,7 +7535,7 @@@ int __connman_service_indicate_default(
  {
        DBG("service %p state %s", service, state2string(service->state));
  
-       if (!is_connected(service)) {
+       if (!is_connected(service->state)) {
                /*
                 * If service is not yet fully connected, then we must not
                 * change the default yet. The default gw will be changed
@@@ -7347,15 -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
@@@ -7483,22 -5952,30 +7729,42 @@@ int __connman_service_ipconfig_indicate
        if (!ipconfig)
                return -EINVAL;
  
+       method = __connman_ipconfig_get_method(ipconfig);
+       switch (method) {
+       case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+       case CONNMAN_IPCONFIG_METHOD_OFF:
+               if (new_state != CONNMAN_SERVICE_STATE_IDLE)
+                       connman_warn("ipconfig state %d ipconfig method %d",
+                               new_state, method);
+               new_state = CONNMAN_SERVICE_STATE_IDLE;
+               break;
+       case CONNMAN_IPCONFIG_METHOD_FIXED:
+       case CONNMAN_IPCONFIG_METHOD_MANUAL:
+       case CONNMAN_IPCONFIG_METHOD_DHCP:
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
+               break;
+       }
        /* Any change? */
        if (old_state == new_state)
                return -EALREADY;
  
 +#if defined TIZEN_EXT
 +      __sync_synchronize();
 +      if (service->user_pdn_connection_refcount > 0 &&
 +                      service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +              if (new_state == CONNMAN_SERVICE_STATE_FAILURE ||
 +                              new_state == CONNMAN_SERVICE_STATE_DISCONNECT ||
 +                              new_state == CONNMAN_SERVICE_STATE_IDLE) {
 +                      service->user_pdn_connection_refcount = 0;
 +                      __sync_synchronize();
 +              }
 +#endif
 +
        DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)",
                service, service ? service->identifier : NULL,
                old_state, state2string(old_state),
  
        switch (new_state) {
        case CONNMAN_SERVICE_STATE_UNKNOWN:
-       case CONNMAN_SERVICE_STATE_IDLE:
        case CONNMAN_SERVICE_STATE_ASSOCIATION:
                break;
        case CONNMAN_SERVICE_STATE_CONFIGURATION:
-               __connman_ipconfig_enable(ipconfig);
                break;
        case CONNMAN_SERVICE_STATE_READY:
 -              if (connman_setting_get_bool("EnableOnlineCheck"))
 +#if defined TIZEN_EXT
 +              if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
 +                              __connman_service_is_internet_profile(service) != TRUE) {
 +                      if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
 +                              service_rp_filter(service, TRUE);
 +
 +                      break;
 +              }
 +#endif
-               if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
++              if (connman_setting_get_bool("EnableOnlineCheck")) {
+                       if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
 +#if !defined TIZEN_EXT
-                       check_proxy_setup(service);
+                               check_proxy_setup(service);
 +#endif
+                       } else {
+                               service->online_check_count = 1;
+                               __connman_wispr_start(service, type);
+                       }
 -              else
++              } else
+                       connman_info("Online check disabled. "
+                               "Default service remains in READY state.");
+               if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                        service_rp_filter(service, true);
-               } else {
-                       service->online_check_count = 1;
-                       __connman_wispr_start(service, type);
-               }
                break;
        case CONNMAN_SERVICE_STATE_ONLINE:
                break;
                        service_rp_filter(service, false);
  
                break;
-       case CONNMAN_SERVICE_STATE_FAILURE:
-               break;
-       }
  
-       /* Keep that state, but if the ipconfig method is OFF, then we set
-          the state to IDLE so that it will not affect the combined state
-          in the future.
-        */
-       method = __connman_ipconfig_get_method(ipconfig);
-       switch (method) {
-       case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
-       case CONNMAN_IPCONFIG_METHOD_OFF:
-               new_state = CONNMAN_SERVICE_STATE_IDLE;
-               break;
+       case CONNMAN_SERVICE_STATE_IDLE:
+       case CONNMAN_SERVICE_STATE_FAILURE:
+               __connman_ipconfig_disable(ipconfig);
  
-       case CONNMAN_IPCONFIG_METHOD_FIXED:
-       case CONNMAN_IPCONFIG_METHOD_MANUAL:
-       case CONNMAN_IPCONFIG_METHOD_DHCP:
-       case CONNMAN_IPCONFIG_METHOD_AUTO:
                break;
        }
  
-       if (is_connected_state(service, old_state) &&
-                       !is_connected_state(service, new_state))
- #if defined TIZEN_EXT
-       {
-               DBG("nameserver remove all, type: %d", type);
+       if (is_connected(old_state) && !is_connected(new_state))
                nameserver_remove_all(service, type);
- #else
-               nameserver_remove_all(service);
- #endif
- #if defined TIZEN_EXT
-       }
- #endif
  
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                service->state_ipv4 = new_state;
        else
                service->state_ipv6 = new_state;
  
-       if (!is_connected_state(service, old_state) &&
-                       is_connected_state(service, new_state))
- #if defined TIZEN_EXT
-       {
-               DBG("nameserver add all, type: %d", type);
+       if (!is_connected(old_state) && is_connected(new_state))
                nameserver_add_all(service, type);
- #else
-               nameserver_add_all(service);
- #endif
- #if defined TIZEN_EXT
-       }
- #endif
+       __connman_timeserver_sync(service);
  
 +#if defined TIZEN_EXT
 +      int ret = service_indicate_state(service);
 +      /*Sent the Ready changed signal again in case IPv4 IP set
 +        after IPv6 IP set*/
 +
 +      if(ret == -EALREADY && type == CONNMAN_IPCONFIG_TYPE_IPV4
 +                      && new_state == CONNMAN_SERVICE_STATE_READY) {
 +              DBG("Notify IPv4 state new/old %d/%d", new_state,old_state);
 +              state_changed(service);
 +      }
 +
 +      return ret;
 +#endif
        return service_indicate_state(service);
  }
  
@@@ -7654,10 -6077,31 +7890,31 @@@ static void prepare_8021x(struct connma
                connman_network_set_string(service->network, "WiFi.Identity",
                                                        service->identity);
  
+       if (service->anonymous_identity)
+               connman_network_set_string(service->network,
+                                               "WiFi.AnonymousIdentity",
+                                               service->anonymous_identity);
        if (service->ca_cert_file)
                connman_network_set_string(service->network, "WiFi.CACertFile",
                                                        service->ca_cert_file);
  
+       if (service->subject_match)
+               connman_network_set_string(service->network, "WiFi.SubjectMatch",
+                                                       service->subject_match);
+       if (service->altsubject_match)
+               connman_network_set_string(service->network, "WiFi.AltSubjectMatch",
+                                                       service->altsubject_match);
+       if (service->domain_suffix_match)
+               connman_network_set_string(service->network, "WiFi.DomainSuffixMatch",
+                                                       service->domain_suffix_match);
+       if (service->domain_match)
+               connman_network_set_string(service->network, "WiFi.DomainMatch",
+                                                       service->domain_match);
        if (service->client_cert_file)
                connman_network_set_string(service->network,
                                                "WiFi.ClientCertFile",
@@@ -7685,33 -6129,6 +7942,33 @@@ static int service_connect(struct connm
        if (service->hidden)
                return -EPERM;
  
-               if (!is_connecting(temp) && !is_connected(temp))
 +#if defined TIZEN_EXT
 +      GList *list;
 +      int index;
 +
 +      index = __connman_service_get_index(service);
 +
 +      for (list = service_list; list; list = list->next) {
 +              struct connman_service *temp = list->data;
 +
 +              if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +                      break;
 +
++              if (!is_connecting(temp->state) && !is_connected(temp->state))
 +                      break;
 +
 +              if (service == temp)
 +                      continue;
 +
 +              if (service->type != temp->type)
 +                      continue;
 +
 +              if (__connman_service_get_index(temp) == index &&
 +                              __connman_service_disconnect(temp) == -EINPROGRESS)
 +                      return -EINPROGRESS;
 +      }
 +#endif
 +
        switch (service->type) {
        case CONNMAN_SERVICE_TYPE_UNKNOWN:
        case CONNMAN_SERVICE_TYPE_SYSTEM:
                        if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
                                return -ENOKEY;
  
 -                      if (!service->passphrase) {
 +                      if (service->request_passphrase_input) {
 +                              DBG("Now try to connect other user's favorite service");
 +                              service->request_passphrase_input = false;
 +                              return -ENOKEY;
 +                      } else if (!service->passphrase) {
                                if (!service->network)
                                        return -EOPNOTSUPP;
  
                        if (!service->eap)
                                return -EINVAL;
  
 +#if defined TIZEN_EXT
 +                      /*
 +                       * never request credentials if using EAP-TLS, EAP-SIM
 +                       * or EAP-AKA (EAP-TLS, EAP-SIM and EAP-AKA networks
 +                       * need to be fully provisioned)
 +                       */
 +                      DBG("service eap: %s", service->eap);
 +                      if (g_str_equal(service->eap, "tls") ||
 +                              g_str_equal(service->eap, "sim") ||
 +                              g_str_equal(service->eap, "aka"))
 +                              break;
 +#else
                        /*
                         * never request credentials if using EAP-TLS
                         * (EAP-TLS networks need to be fully provisioned)
                         */
                        if (g_str_equal(service->eap, "tls"))
                                break;
 -
 +#endif
                        /*
                         * Return -ENOKEY if either identity or passphrase is
                         * missing. Agent provided credentials can be used as
                                                &service->stats_roaming.data);
                }
  
-               if (service->ipconfig_ipv4)
-                       __connman_ipconfig_enable(service->ipconfig_ipv4);
-               if (service->ipconfig_ipv6)
-                       __connman_ipconfig_enable(service->ipconfig_ipv6);
                err = __connman_network_connect(service->network);
        } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
                                        service->provider)
-               err = __connman_provider_connect(service->provider);
+               err = __connman_provider_connect(service->provider,
+                                               get_dbus_sender(service));
        else
                return -EOPNOTSUPP;
  
        if (err < 0) {
                if (err != -EINPROGRESS) {
-                       __connman_ipconfig_disable(service->ipconfig_ipv4);
-                       __connman_ipconfig_disable(service->ipconfig_ipv6);
+                       __connman_service_ipconfig_indicate_state(service,
+                                               CONNMAN_SERVICE_STATE_FAILURE,
+                                               CONNMAN_IPCONFIG_TYPE_IPV4);
+                       __connman_service_ipconfig_indicate_state(service,
+                                               CONNMAN_SERVICE_STATE_FAILURE,
+                                               CONNMAN_IPCONFIG_TYPE_IPV6);
                        __connman_stats_service_unregister(service);
                }
        }
@@@ -7846,10 -6247,10 +8103,10 @@@ int __connman_service_connect(struct co
                reason2string(service->connect_reason),
                reason2string(reason));
  
-       if (is_connected(service))
+       if (is_connected(service->state))
                return -EISCONN;
  
-       if (is_connecting(service))
+       if (is_connecting(service->state))
                return -EALREADY;
  
        switch (service->type) {
  
        err = service_connect(service);
  
+       DBG("service %p err %d", service, err);
        service->connect_reason = reason;
 -
        if (err >= 0)
                return 0;
  
        if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
                if (err == -ENOKEY || err == -EPERM) {
                        DBusMessage *pending = NULL;
+                       const char *dbus_sender = get_dbus_sender(service);
  
                        /*
                         * We steal the reply here. The idea is that the
  
                        err = __connman_agent_request_passphrase_input(service,
                                        request_input_cb,
-                                       get_dbus_sender(service),
+                                       dbus_sender,
                                        pending);
                        if (service->hidden && err != -EINPROGRESS)
                                service->pending = pending;
@@@ -7956,14 -6361,6 +8216,14 @@@ int __connman_service_disconnect(struc
                __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6,
                                                        NULL);
  
 +#if defined TIZEN_EXT
 +      /**
 +        * Skip the functions If there is any connected profiles
 +        * that use same interface
 +        */
 +      if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
 +              __connman_service_get_connected_count_of_iface(service) <= 0) {
 +#endif
        __connman_ipconfig_address_remove(service->ipconfig_ipv4);
        settings_changed(service, service->ipconfig_ipv4);
  
  
        __connman_ipconfig_disable(service->ipconfig_ipv4);
        __connman_ipconfig_disable(service->ipconfig_ipv6);
 +#if defined TIZEN_EXT
 +      }
 +#endif
  
        __connman_stats_service_unregister(service);
  
@@@ -7992,7 -6386,7 +8252,7 @@@ int __connman_service_disconnect_all(vo
        for (iter = service_list; iter; iter = iter->next) {
                service = iter->data;
  
-               if (!is_connected(service))
+               if (!is_connected(service->state))
                        break;
  
                services = g_slist_prepend(services, service);
@@@ -8022,6 -6416,11 +8282,11 @@@ static struct connman_service *lookup_b
        return g_hash_table_lookup(service_hash, identifier);
  }
  
+ struct connman_service *connman_service_lookup_from_identifier(const char* identifier)
+ {
+       return lookup_by_identifier(identifier);
+ }
  struct provision_user_data {
        const char *ident;
        int ret;
@@@ -8172,12 -6571,6 +8437,6 @@@ static void service_lower_down(struct c
  
        DBG("%s lower down", ifname);
  
-       if (!is_idle_state(service, service->state_ipv4))
-               __connman_ipconfig_disable(service->ipconfig_ipv4);
-       if (!is_idle_state(service, service->state_ipv6))
-               __connman_ipconfig_disable(service->ipconfig_ipv6);
        stats_stop(service);
        service_save(service);
  }
@@@ -8188,9 -6581,6 +8447,9 @@@ static void service_ip_bound(struct con
        struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
        enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
        enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
 +#if defined TIZEN_EXT
 +      int err;
 +#endif
  
        DBG("%s ip bound", ifname);
  
  
        if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
                        method == CONNMAN_IPCONFIG_METHOD_AUTO)
-               if(err == 0)
-                       __connman_connection_gateway_activate(service,
-                                       CONNMAN_IPCONFIG_TYPE_IPV6);
 +#if defined TIZEN_EXT
 +      {
 +              err = __connman_ipconfig_gateway_add(ipconfig, service);
 +
++              if(err < 0)
++                      DBG("Failed to add gateway");
 +      }
 +#else
                __connman_service_ipconfig_indicate_state(service,
                                                CONNMAN_SERVICE_STATE_READY,
                                                CONNMAN_IPCONFIG_TYPE_IPV6);
 +#endif
  
        settings_changed(service, ipconfig);
+       address_updated(service, type);
  }
  
  static void service_ip_release(struct connman_ipconfig *ipconfig,
@@@ -8454,28 -6835,6 +8713,28 @@@ unsigned int __connman_service_get_orde
        if (!service->favorite)
                return 0;
  
 +#if defined TIZEN_EXT
 +      if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
 +                      service->do_split_routing == FALSE)
 +              order = 10;
 +      else if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
 +              if (service->order < 5)
 +                      order = 5;
 +      } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
 +              order = 4;
 +      else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
 +              order = 3;
 +      else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
 +                      __connman_service_is_internet_profile(service) == TRUE)
 +              order = 1;
 +      else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
 +                      __connman_service_is_tethering_profile(service) == TRUE)
 +              order = 0;
 +      else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
 +              order = 0;
 +      else
 +              order = 2;
 +#else
        if (service == service_list->data)
                order = 1;
  
                service->order = 10;
                order = 10;
        }
 -
 +#endif
        DBG("service %p name %s order %d split %d", service, service->name,
                order, service->do_split_routing);
  
        return order;
  }
  
- void __connman_service_update_ordering(void)
- {
-       if (service_list && service_list->next)
-               service_list = g_list_sort(service_list, service_compare);
- }
  static enum connman_service_type convert_network_type(struct connman_network *network)
  {
        enum connman_network_type type = connman_network_get_type(network);
@@@ -8537,30 -6890,10 +8790,30 @@@ static enum connman_service_security co
                return CONNMAN_SERVICE_SECURITY_WPA;
        else if (g_str_equal(security, "rsn"))
                return CONNMAN_SERVICE_SECURITY_RSN;
 +#if defined TIZEN_EXT
 +      else if (g_str_equal(security, "ft_psk") == TRUE)
 +              return CONNMAN_SERVICE_SECURITY_PSK;
 +      else if (g_str_equal(security, "ft_ieee8021x") == TRUE)
 +              return CONNMAN_SERVICE_SECURITY_8021X;
 +#endif
        else
                return CONNMAN_SERVICE_SECURITY_UNKNOWN;
  }
  
-       return check_passphrase(security, passphrase);
 +#if defined TIZEN_EXT
 +int check_passphrase_ext(struct connman_network *network,
 +                                      const char *passphrase)
 +{
 +      const char *str;
 +      enum connman_service_security security;
 +
 +      str = connman_network_get_string(network, "WiFi.Security");
 +      security = convert_wifi_security(str);
 +
++      return __connman_service_check_passphrase(security, passphrase);
 +}
 +#endif
 +
  static void update_from_network(struct connman_service *service,
                                        struct connman_network *network)
  {
  
        DBG("service %p network %p", service, network);
  
-       if (is_connected(service))
+       if (is_connected(service->state))
                return;
  
-       if (is_connecting(service))
+       if (is_connecting(service->state))
                return;
  
        str = connman_network_get_string(network, "Name");
@@@ -8704,6 -7037,7 +8957,7 @@@ struct connman_service * __connman_serv
                service->ipconfig_ipv6 = create_ip6config(service, index);
  
        service_register(service);
+       service_schedule_added(service);
  
        if (service->favorite) {
                device = connman_network_get_device(service->network);
                                break;
                        }
                }
 +
 +#if defined TIZEN_EXT
 +              /* TIZEN synchronizes below information when the service creates */
 +              if (service->eap != NULL)
 +                      connman_network_set_string(service->network, "WiFi.EAP",
 +                                                              service->eap);
 +              if (service->identity != NULL)
 +                      connman_network_set_string(service->network, "WiFi.Identity",
 +                                                              service->identity);
 +              if (service->phase2 != NULL)
 +                      connman_network_set_string(service->network, "WiFi.Phase2",
 +                                                              service->phase2);
 +#endif
        }
  
        __connman_notifier_service_add(service, service->name);
-       service_schedule_added(service);
  
        return service;
  }
@@@ -8770,13 -7090,6 +9023,13 @@@ void __connman_service_update_from_netw
        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);
@@@ -9012,6 -7325,8 +9265,8 @@@ int __connman_service_init(void
                return err;
        }
  
+       set_always_connecting_technologies();
        connection = connman_dbus_get_connection();
  
        service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
@@@ -9055,9 -7370,10 +9310,10 @@@ void __connman_service_cleanup(void
        if (services_notify->id != 0) {
                g_source_remove(services_notify->id);
                service_send_changed(NULL);
-               g_hash_table_destroy(services_notify->remove);
-               g_hash_table_destroy(services_notify->add);
        }
+       g_hash_table_destroy(services_notify->remove);
+       g_hash_table_destroy(services_notify->add);
        g_free(services_notify);
  
        dbus_connection_unref(connection);
diff --combined src/session.c
index 08facc1,9e3c559..9e3c559
mode 100755,100644..100755
@@@ -37,13 -37,6 +37,6 @@@ static GHashTable *session_hash
  static GHashTable *service_hash;
  static struct connman_session *ecall_session;
  static uint32_t session_mark = 256;
- static struct firewall_context *global_firewall = NULL;
- enum connman_session_state {
-       CONNMAN_SESSION_STATE_DISCONNECTED   = 0,
-       CONNMAN_SESSION_STATE_CONNECTED      = 1,
-       CONNMAN_SESSION_STATE_ONLINE         = 2,
- };
  
  struct session_info {
        struct connman_session_config config;
@@@ -64,6 -57,7 +57,7 @@@ struct connman_session 
        struct connman_service *service_last;
        struct connman_session_config *policy_config;
        GSList *user_allowed_bearers;
+       char *user_allowed_interface;
  
        bool ecall;
  
@@@ -73,6 -67,7 +67,7 @@@
        int index;
        char *gateway;
        bool policy_routing;
+       bool snat_enabled;
  };
  
  struct connman_service_info {
        GSList *sessions;
  };
  
+ struct fw_snat {
+       GSList *sessions;
+       int id;
+       int index;
+       struct firewall_context *fw;
+ };
+ GSList *fw_snat_list;
  static struct connman_session_policy *policy;
  static void session_activate(struct connman_session *session);
  static void session_deactivate(struct connman_session *session);
@@@ -196,102 -200,109 +200,109 @@@ static char *service2bearer(enum connma
        return "";
  }
  
- static int init_firewall(void)
+ static struct fw_snat *fw_snat_lookup(int index)
  {
-       struct firewall_context *fw;
-       int err;
+       struct fw_snat *fw_snat;
+       GSList *list;
  
-       if (global_firewall)
-               return 0;
+       for (list = fw_snat_list; list; list = list->next) {
+               fw_snat = list->data;
  
-       fw = __connman_firewall_create();
+               if (fw_snat->index == index)
+                       return fw_snat;
+       }
+       return NULL;
+ }
  
-       err = __connman_firewall_add_rule(fw, "mangle", "INPUT",
-                                       "-j CONNMARK --restore-mark");
-       if (err < 0)
-               goto err;
+ static int fw_snat_create(struct connman_session *session,
+                               int index, const char *ifname, const char *addr)
+ {
+       struct fw_snat *fw_snat;
+       int err;
  
-       err = __connman_firewall_add_rule(fw, "mangle", "POSTROUTING",
-                                       "-j CONNMARK --save-mark");
-       if (err < 0)
-               goto err;
+       fw_snat = g_new0(struct fw_snat, 1);
  
-       err = __connman_firewall_enable(fw);
-       if (err < 0)
+       fw_snat->fw = __connman_firewall_create();
+       fw_snat->index = index;
+       fw_snat->id = __connman_firewall_enable_snat(fw_snat->fw,
+                                               index, ifname, addr);
+       if (fw_snat->id < 0) {
+               err = fw_snat->id;
                goto err;
+       }
  
-       global_firewall = fw;
+       fw_snat_list = g_slist_prepend(fw_snat_list, fw_snat);
+       fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
  
        return 0;
  err:
-       __connman_firewall_destroy(fw);
+       __connman_firewall_destroy(fw_snat->fw);
+       g_free(fw_snat);
        return err;
  }
  
- static void cleanup_firewall(void)
+ static void fw_snat_ref(struct connman_session *session,
+                               struct fw_snat *fw_snat)
  {
-       if (!global_firewall)
+       if (g_slist_find(fw_snat->sessions, session))
                return;
+       fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
+ }
  
-       __connman_firewall_disable(global_firewall);
-       __connman_firewall_destroy(global_firewall);
+ static void fw_snat_unref(struct connman_session *session,
+                               struct fw_snat *fw_snat)
+ {
+       fw_snat->sessions = g_slist_remove(fw_snat->sessions, session);
+       if (fw_snat->sessions)
+               return;
+       fw_snat_list = g_slist_remove(fw_snat_list, fw_snat);
+       __connman_firewall_disable_snat(fw_snat->fw);
+       __connman_firewall_destroy(fw_snat->fw);
+       g_free(fw_snat);
  }
  
  static int init_firewall_session(struct connman_session *session)
  {
        struct firewall_context *fw;
        int err;
+       struct connman_ipconfig *ipconfig = NULL;
+       const char *addr = NULL;
  
-       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN &&
+                       !session->info->config.source_ip_rule)
                return 0;
  
        DBG("");
  
-       err = init_firewall();
-       if (err < 0)
-               return err;
+       if (session->info->config.source_ip_rule) {
+               ipconfig = __connman_service_get_ip4config(session->service);
+               if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN && !ipconfig)
+                       return 0;
+       }
  
        fw = __connman_firewall_create();
        if (!fw)
                return -ENOMEM;
  
-       switch (session->policy_config->id_type) {
-       case CONNMAN_SESSION_ID_TYPE_UID:
-               err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
-                               "-m owner --uid-owner %s -j MARK --set-mark %d",
-                                               session->policy_config->id,
-                                               session->mark);
-               break;
-       case CONNMAN_SESSION_ID_TYPE_GID:
-               err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
-                               "-m owner --gid-owner %s -j MARK --set-mark %d",
-                                               session->policy_config->id,
-                                               session->mark);
-               break;
-       case CONNMAN_SESSION_ID_TYPE_LSM:
-       default:
-               err = -EINVAL;
+       if (session->info->config.source_ip_rule && ipconfig) {
+               addr = __connman_ipconfig_get_local(ipconfig);
        }
  
-       if (err < 0)
-               goto err;
+       err =__connman_firewall_enable_marking(fw,
+                                       session->policy_config->id_type,
+                                       session->policy_config->id,
+                                       addr, session->mark);
+       if (err < 0) {
+               __connman_firewall_destroy(fw);
+               return err;
+       }
        session->id_type = session->policy_config->id_type;
-       err = __connman_firewall_enable(fw);
-       if (err)
-               goto err;
        session->fw = fw;
  
        return 0;
- err:
-       __connman_firewall_destroy(fw);
-       return err;
  }
  
  static void cleanup_firewall_session(struct connman_session *session)
        if (!session->fw)
                return;
  
-       __connman_firewall_disable(session->fw);
+       __connman_firewall_disable_marking(session->fw);
+       __connman_firewall_disable_snat(session->fw);
        __connman_firewall_destroy(session->fw);
  
        session->fw = NULL;
@@@ -309,7 -321,11 +321,11 @@@ static int init_routing_table(struct co
  {
        int err;
  
-       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN &&
+                       !session->info->config.source_ip_rule)
+               return 0;
+       if (!session->service)
                return 0;
  
        DBG("");
@@@ -348,6 -364,7 +364,7 @@@ static void add_default_route(struct co
  {
        struct connman_ipconfig *ipconfig;
        int err;
+       struct in_addr addr = { INADDR_ANY };
  
        if (!session->service)
                return;
        session->index = __connman_ipconfig_get_index(ipconfig);
        session->gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig));
  
+       if (!session->gateway)
+               session->gateway = g_strdup(inet_ntoa(addr));
        DBG("index %d routing table %d default gateway %s",
                session->index, session->mark, session->gateway);
  
                DBG("session %p %s", session, strerror(-err));
  }
  
+ static void del_nat_rules(struct connman_session *session)
+ {
+       struct fw_snat *fw_snat;
+       if (!session->snat_enabled)
+               return;
+       session->snat_enabled = false;
+       fw_snat = fw_snat_lookup(session->index);
+       if (!fw_snat)
+               return;
+       fw_snat_unref(session, fw_snat);
+ }
+ static void add_nat_rules(struct connman_session *session)
+ {
+       struct connman_ipconfig *ipconfig;
+       struct fw_snat *fw_snat;
+       const char *addr;
+       int index, err;
+       char *ifname;
+       if (!session->service)
+               return;
+       ipconfig = __connman_service_get_ip4config(session->service);
+       index = __connman_ipconfig_get_index(ipconfig);
+       ifname = connman_inet_ifname(index);
+       addr = __connman_ipconfig_get_local(ipconfig);
+       if (!addr)
+               return;
+       session->snat_enabled = true;
+       fw_snat = fw_snat_lookup(index);
+       if (fw_snat) {
+               fw_snat_ref(session, fw_snat);
+               return;
+       }
+       err = fw_snat_create(session, index, ifname, addr);
+       if (err < 0) {
+               DBG("failed to add SNAT rule");
+               session->snat_enabled = false;
+       }
+       g_free(ifname);
+ }
+ uint32_t connman_session_firewall_get_fwmark(struct connman_session *session)
+ {
+       return session->mark;
+ }
  static void cleanup_routing_table(struct connman_session *session)
  {
        DBG("");
        del_default_route(session);
  }
  
+ static void update_firewall(struct connman_session *session)
+ {
+       cleanup_firewall_session(session);
+       init_firewall_session(session);
+ }
  static void update_routing_table(struct connman_session *session)
  {
-       del_default_route(session);
+       cleanup_routing_table(session);
+       init_routing_table(session);
        add_default_route(session);
  }
  
+ static void cleanup_nat_rules(struct connman_session *session)
+ {
+       del_nat_rules(session);
+ }
  static void destroy_policy_config(struct connman_session *session)
  {
        if (!policy) {
@@@ -407,6 -495,7 +495,7 @@@ static void free_session(struct connman
  
        destroy_policy_config(session);
        g_slist_free(session->info->config.allowed_bearers);
+       g_free(session->info->config.allowed_interface);
        g_free(session->owner);
        g_free(session->session_path);
        g_free(session->notify_path);
@@@ -434,6 -523,7 +523,7 @@@ static void cleanup_session(gpointer us
  
        DBG("remove %s", session->session_path);
  
+       cleanup_nat_rules(session);
        cleanup_routing_table(session);
        cleanup_firewall_session(session);
  
        update_session_state(session);
  
        g_slist_free(session->user_allowed_bearers);
+       g_free(session->user_allowed_interface);
  
        free_session(session);
  }
@@@ -455,6 -546,8 +546,8 @@@ struct creation_data 
        /* user config */
        enum connman_session_type type;
        GSList *allowed_bearers;
+       char *allowed_interface;
+       bool source_ip_rule;
  };
  
  static void cleanup_creation_data(struct creation_data *creation_data)
                dbus_message_unref(creation_data->pending);
  
        g_slist_free(creation_data->allowed_bearers);
+       g_free(creation_data->allowed_interface);
        g_free(creation_data);
  }
  
@@@ -543,6 -637,7 +637,7 @@@ void connman_session_set_default_config
        config->ecall = FALSE;
  
        g_slist_free(config->allowed_bearers);
+       config->allowed_bearers = NULL;
        add_default_bearer_types(&config->allowed_bearers);
  }
  
@@@ -628,18 -723,18 +723,18 @@@ static int parse_bearers(DBusMessageIte
        return 0;
  }
  
- static void filter_bearer(GSList *policy_bearers,
-                               enum connman_service_type bearer,
+ static void filter_bearer(GSList *bearers,
+                               enum connman_service_type policy,
                                GSList **list)
  {
-       enum connman_service_type policy;
+       enum connman_service_type bearer;
        GSList *it;
  
-       if (!policy_bearers)
+       if (!bearers)
                return;
  
-       for (it = policy_bearers; it; it = it->next) {
-               policy = GPOINTER_TO_INT(it->data);
+       for (it = bearers; it; it = it->next) {
+               bearer = GPOINTER_TO_INT(it->data);
  
                if (policy != bearer)
                        continue;
  static void apply_policy_on_bearers(GSList *policy_bearers, GSList *bearers,
                                GSList **list)
  {
-       enum connman_service_type bearer;
+       enum connman_service_type policy_bearer;
        GSList *it;
  
        *list = NULL;
  
-       for (it = bearers; it; it = it->next) {
-               bearer = GPOINTER_TO_INT(it->data);
+       for (it = policy_bearers; it; it = it->next) {
+               policy_bearer = GPOINTER_TO_INT(it->data);
  
-               filter_bearer(policy_bearers, bearer, list);
+               filter_bearer(bearers, policy_bearer, list);
        }
  }
  
+ static char * apply_policy_on_interface(const char *policy_interface,
+                               const char *user_interface)
+ {
+       if (policy_interface)
+               return g_strdup(policy_interface);
+       else if (user_interface)
+               return g_strdup(user_interface);
+       else
+               return NULL;
+ }
  const char *connman_session_get_owner(struct connman_session *session)
  {
        return session->owner;
@@@ -809,6 -915,28 +915,28 @@@ static void append_notify(DBusMessageIt
                info_last->config.allowed_bearers = info->config.allowed_bearers;
        }
  
+       if (session->append_all ||
+                       info->config.allowed_interface != info_last->config.allowed_interface) {
+               char *ifname = info->config.allowed_interface;
+               if (!ifname)
+                       ifname = "*";
+               connman_dbus_dict_append_basic(dict, "AllowedInterface",
+                                               DBUS_TYPE_STRING,
+                                               &ifname);
+               info_last->config.allowed_interface = info->config.allowed_interface;
+       }
+       if (session->append_all ||
+                       info->config.source_ip_rule != info_last->config.source_ip_rule) {
+               dbus_bool_t source_ip_rule = FALSE;
+               if (info->config.source_ip_rule)
+                       source_ip_rule = TRUE;
+               connman_dbus_dict_append_basic(dict, "SourceIPRule",
+                                               DBUS_TYPE_BOOLEAN,
+                                               &source_ip_rule);
+               info_last->config.source_ip_rule = info->config.source_ip_rule;
+       }
        session->append_all = false;
  }
  
@@@ -828,7 -956,9 +956,9 @@@ static bool compute_notifiable_changes(
                return true;
  
        if (info->config.allowed_bearers != info_last->config.allowed_bearers ||
-                       info->config.type != info_last->config.type)
+                       info->config.type != info_last->config.type ||
+                       info->config.allowed_interface != info_last->config.allowed_interface ||
+                       info->config.source_ip_rule != info_last->config.source_ip_rule)
                return true;
  
        return false;
@@@ -882,6 -1012,7 +1012,7 @@@ int connman_session_config_update(struc
  {
        struct session_info *info = session->info;
        GSList *allowed_bearers;
+       char *allowed_interface;
        int err;
  
        DBG("session %p", session);
                session->user_allowed_bearers,
                &allowed_bearers);
  
+       allowed_interface = apply_policy_on_interface(
+               session->policy_config->allowed_interface,
+               session->user_allowed_interface);
        if (session->active)
                set_active_session(session, false);
  
        g_slist_free(info->config.allowed_bearers);
        info->config.allowed_bearers = allowed_bearers;
  
+       g_free(info->config.allowed_interface);
+       info->config.allowed_interface = allowed_interface;
        session_activate(session);
  
        info->config.type = apply_policy_on_type(
@@@ -1024,6 -1162,7 +1162,7 @@@ static DBusMessage *change_session(DBus
  
                        session->active = false;
                        session_deactivate(session);
+                       update_session_state(session);
  
                        g_slist_free(info->config.allowed_bearers);
                        session->user_allowed_bearers = allowed_bearers;
                        info->config.type = apply_policy_on_type(
                                session->policy_config->type,
                                connman_session_parse_connection_type(val));
+               } else if (g_str_equal(name, "AllowedInterface")) {
+                       dbus_message_iter_get_basic(&value, &val);
+                       if (session->active)
+                               set_active_session(session, false);
+                       session->active = false;
+                       session_deactivate(session);
+                       update_session_state(session);
+                       g_free(session->user_allowed_interface);
+                       /* empty string means allow any interface */
+                       if (!g_strcmp0(val, ""))
+                               session->user_allowed_interface = NULL;
+                       else
+                               session->user_allowed_interface = g_strdup(val);
+                       info->config.allowed_interface = apply_policy_on_interface(
+                               session->policy_config->allowed_interface,
+                               session->user_allowed_interface);
+                       session_activate(session);
+               } else {
+                       goto err;
+               }
+               break;
+       case DBUS_TYPE_BOOLEAN:
+               if (g_str_equal(name, "SourceIPRule")) {
+                       dbus_bool_t source_ip_rule;
+                       dbus_message_iter_get_basic(&value, &source_ip_rule);
+                       info->config.source_ip_rule = source_ip_rule;
+                       update_session_state(session);
                } else {
                        goto err;
                }
@@@ -1149,6 -1320,7 +1320,7 @@@ static int session_policy_config_cb(str
                goto err;
  
        session->policy_config = config;
+       session->info->config.source_ip_rule = creation_data->source_ip_rule;
  
        session->mark = session_mark++;
        session->index = -1;
        session->user_allowed_bearers = creation_data->allowed_bearers;
        creation_data->allowed_bearers = NULL;
  
+       session->user_allowed_interface = creation_data->allowed_interface;
+       creation_data->allowed_interface = NULL;
        apply_policy_on_bearers(
                        session->policy_config->allowed_bearers,
                        session->user_allowed_bearers,
                        &info->config.allowed_bearers);
  
+       info->config.allowed_interface = apply_policy_on_interface(
+               session->policy_config->allowed_interface,
+               session->user_allowed_interface);
        g_hash_table_replace(session_hash, session->session_path, session);
  
        DBG("add %s", session->session_path);
        info_last->config.priority = info->config.priority;
        info_last->config.roaming_policy = info->config.roaming_policy;
        info_last->config.allowed_bearers = info->config.allowed_bearers;
+       info_last->config.allowed_interface = info->config.allowed_interface;
+       info_last->config.source_ip_rule = info->config.source_ip_rule;
  
        session->append_all = true;
  
@@@ -1293,11 -1474,29 +1474,29 @@@ int __connman_session_create(DBusMessag
                                        connman_session_parse_connection_type(val);
  
                                user_connection_type = true;
+                       } else if (g_str_equal(key, "AllowedInterface")) {
+                               dbus_message_iter_get_basic(&value, &val);
+                               creation_data->allowed_interface = g_strdup(val);
                        } else {
                                err = -EINVAL;
                                goto err;
                        }
+                       break;
+               case DBUS_TYPE_BOOLEAN:
+                       if (g_str_equal(key, "SourceIPRule")) {
+                               dbus_bool_t source_ip_rule;
+                               dbus_message_iter_get_basic(&value, &source_ip_rule);
+                               creation_data->source_ip_rule = source_ip_rule;
+                       } else {
+                               err = -EINVAL;
+                               goto err;
+                       }
+                       break;
+               default:
+                       err = -EINVAL;
+                       goto err;
                }
                dbus_message_iter_next(&array);
        }
  
@@@ -1481,7 -1680,14 +1680,14 @@@ static void update_session_state(struc
  
        DBG("session %p state %s", session, state2string(state));
  
+       update_firewall(session);
+       del_nat_rules(session);
        update_routing_table(session);
+       add_nat_rules(session);
+       if (policy && policy->update_session_state)
+               policy->update_session_state(session, state);
        session_notify(session);
  }
  
@@@ -1490,17 -1696,31 +1696,31 @@@ static bool session_match_service(struc
  {
        enum connman_service_type bearer_type;
        enum connman_service_type service_type;
+       enum connman_service_type current_service_type;
        GSList *list;
+       char *ifname;
  
        if (policy && policy->allowed)
                return policy->allowed(session, service);
  
+       current_service_type = connman_service_get_type(session->service);
        for (list = session->info->config.allowed_bearers; list; list = list->next) {
                bearer_type = GPOINTER_TO_INT(list->data);
                service_type = connman_service_get_type(service);
+               ifname = connman_service_get_interface(service);
  
-               if (bearer_type == service_type)
-                       return true;
+               if (bearer_type == current_service_type)
+                       return false;
+               if (bearer_type == service_type &&
+                       (session->info->config.allowed_interface == NULL ||
+                       !g_strcmp0(session->info->config.allowed_interface, "*") ||
+                       !g_strcmp0(session->info->config.allowed_interface, ifname))) {
+                               g_free(ifname);
+                               return true;
+               }
+               g_free(ifname);
        }
  
        return false;
@@@ -1521,6 -1741,7 +1741,7 @@@ static bool is_session_connected(struc
        case CONNMAN_SERVICE_STATE_READY:
                if (session->info->config.type == CONNMAN_SESSION_TYPE_INTERNET)
                        return false;
+               /* fall through */
        case CONNMAN_SERVICE_STATE_ONLINE:
                return true;
        }
@@@ -1536,6 -1757,40 +1757,40 @@@ static void session_activate(struct con
        if (!service_hash)
                return;
  
+       if (policy && policy->get_service_for_session) {
+               struct connman_service *service;
+               struct connman_service_info *info;
+               GSList *service_list = NULL;
+               enum connman_service_state state = CONNMAN_SESSION_STATE_DISCONNECTED;
+               g_hash_table_iter_init(&iter, service_hash);
+               while (g_hash_table_iter_next(&iter, &key, &value)) {
+                       struct connman_service_info *info = value;
+                       state = __connman_service_get_state(info->service);
+                       if (is_session_connected(session, state))
+                               service_list = g_slist_prepend(service_list,
+                                                              info->service);
+               }
+               service_list = g_slist_reverse(service_list);
+               service = policy->get_service_for_session(session, service_list);
+               if (service) {
+                       info = g_hash_table_lookup(service_hash, service);
+                       DBG("session %p add service %p", session, info->service);
+                       info->sessions = g_slist_prepend(info->sessions,
+                                                       session);
+                       session->service = info->service;
+                       update_session_state(session);
+               }
+               g_slist_free(service_list);
+               return;
+       }
        g_hash_table_iter_init(&iter, service_hash);
        while (g_hash_table_iter_next(&iter, &key, &value)) {
                struct connman_service_info *info = value;
@@@ -1630,10 -1885,10 +1885,10 @@@ static void handle_service_state_offlin
  
                session->service = NULL;
                update_session_state(session);
+               session_activate(session);
        }
  }
  
  static void service_state_changed(struct connman_service *service,
                                enum connman_service_state state)
  {
@@@ -1693,7 -1948,7 +1948,7 @@@ static void ipconfig_changed(struct con
                        continue;
  
                if (session->service && session->service == service) {
-                       update_routing_table(session);
+                       update_session_state(session);
  
                        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                                ipconfig_ipv4_changed(session);
@@@ -1730,12 -1985,6 +1985,6 @@@ int __connman_session_init(void
  
        service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                                                NULL, cleanup_service);
-       if (__connman_firewall_is_up()) {
-               err = init_firewall();
-               if (err < 0)
-                       return err;
-       }
        return 0;
  }
  
@@@ -1746,8 -1995,6 +1995,6 @@@ void __connman_session_cleanup(void
        if (!connection)
                return;
  
-       cleanup_firewall();
        connman_notifier_unregister(&session_notifier);
  
        g_hash_table_foreach(session_hash, release_session, NULL);
diff --combined src/stats.c
index 26343b1,663bc38..663bc38
mode 100755,100644..100755
@@@ -227,18 -227,14 +227,14 @@@ static void stats_free(gpointer user_da
        munmap(file->addr, file->len);
        file->addr = NULL;
  
-       TFR(close(file->fd));
+       close(file->fd);
        file->fd = -1;
  
-       if (file->history_name) {
-               g_free(file->history_name);
-               file->history_name = NULL;
-       }
+       g_free(file->history_name);
+       file->history_name = NULL;
  
-       if (file->name) {
-               g_free(file->name);
-               file->name = NULL;
-       }
+       g_free(file->name);
+       file->name = NULL;
  
        g_free(file);
  }
@@@ -377,7 -373,8 +373,8 @@@ static int stats_file_setup(struct stat
                connman_error("fstat error %s for %s\n",
                        strerror(errno), file->name);
  
-               TFR(close(file->fd));
+               close(file->fd);
+               file->fd = -1;
                g_free(file->name);
                file->name = NULL;
  
  
        err = stats_file_remap(file, size);
        if (err < 0) {
-               TFR(close(file->fd));
+               close(file->fd);
+               file->fd = -1;
                g_free(file->name);
                file->name = NULL;
  
@@@ -621,7 -619,7 +619,7 @@@ static int stats_file_close_swap(struc
        stats_file_unmap(history_file);
        stats_file_unmap(temp_file);
  
-       TFR(close(temp_file->fd));
+       close(temp_file->fd);
  
        unlink(history_file->name);
  
  
        unlink(temp_file->name);
  
-       TFR(close(history_file->fd));
+       close(history_file->fd);
  
        stats_file_cleanup(history_file);
        stats_file_cleanup(temp_file);
@@@ -649,6 -647,9 +647,9 @@@ static int stats_file_history_update(st
        bzero(history_file, sizeof(struct stats_file));
        bzero(temp_file, sizeof(struct stats_file));
  
+       history_file->fd = -1;
+       temp_file->fd = -1;
        err = stats_open(history_file, data_file->history_name);
        if (err < 0)
                return err;
@@@ -676,17 -677,6 +677,6 @@@ int __connman_stats_service_register(st
  
        DBG("service %p", service);
  
-       file = g_hash_table_lookup(stats_hash, service);
-       if (!file) {
-               file = g_try_new0(struct stats_file, 1);
-               if (!file)
-                       return -ENOMEM;
-               g_hash_table_insert(stats_hash, service, file);
-       } else {
-               return -EALREADY;
-       }
        dir = g_strdup_printf("%s/%s", STORAGEDIR,
                                __connman_service_get_ident(service));
  
        }
  
        g_free(dir);
+       file = g_hash_table_lookup(stats_hash, service);
+       if (!file) {
+               file = g_try_new0(struct stats_file, 1);
+               if (!file)
+                       return -ENOMEM;
+               file->fd = -1;
+               g_hash_table_insert(stats_hash, service, file);
+       } else {
+               return -EALREADY;
+       }
  
        name = g_strdup_printf("%s/%s/data", STORAGEDIR,
                                __connman_service_get_ident(service));
diff --combined src/storage.c
index 2da54d6,5e877ef..50c8e95
mode 100755,100644..100755
@@@ -23,7 -23,6 +23,7 @@@
  #include <config.h>
  #endif
  
 +#include <stdio.h>
  #include <errno.h>
  #include <unistd.h>
  #include <sys/stat.h>
@@@ -43,8 -42,6 +43,6 @@@ static GKeyFile *storage_load(const cha
  {
        GKeyFile *keyfile = NULL;
        GError *error = NULL;
-       DBG("Loading %s", pathname);
  
        keyfile = g_key_file_new();
  
@@@ -74,19 -71,6 +72,19 @@@ static int storage_save(GKeyFile *keyfi
                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 --combined src/task.c
index 8b9e1d9,953cc40..953cc40
mode 100755,100644..100755
@@@ -401,8 -401,7 +401,7 @@@ int connman_task_stop(struct connman_ta
        if (task->pid > 0) {
                kill(task->pid, SIGTERM);
  
-               g_timeout_add_seconds(0, check_kill,
-                               GINT_TO_POINTER(task->pid));
+               g_idle_add(check_kill, GINT_TO_POINTER(task->pid));
        }
  
        return 0;
diff --combined src/technology.c
index 408c99f,d2f0ae2..5aea9f4
mode 100755,100644..100755
@@@ -43,16 -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;
@@@ -76,7 -66,6 +76,7 @@@ struct connman_technology 
                                              */
        char *tethering_ident;
        char *tethering_passphrase;
 +      bool tethering_hidden;
  
        bool enable_persistent; /* Save the tech state */
  
@@@ -191,9 -180,6 +191,9 @@@ static void technology_save(struct conn
        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",
@@@ -225,22 -211,27 +225,27 @@@ static void tethering_changed(struct co
        technology_save(technology);
  }
  
void connman_technology_tethering_notify(struct connman_technology *technology,
int connman_technology_tethering_notify(struct connman_technology *technology,
                                                        bool enabled)
  {
+       int err;
        DBG("technology %p enabled %u", technology, enabled);
  
        if (technology->tethering == enabled)
-               return;
+               return -EALREADY;
  
-       technology->tethering = enabled;
+       if (enabled) {
+               err = __connman_tethering_set_enabled();
+               if (err < 0)
+                       return err;
+       } else
+               __connman_tethering_set_disabled();
  
+       technology->tethering = enabled;
        tethering_changed(technology);
  
-       if (enabled)
-               __connman_tethering_set_enabled();
-       else
-               __connman_tethering_set_disabled();
+       return 0;
  }
  
  static int set_tethering(struct connman_technology *technology,
        int err;
        const char *ident, *passphrase, *bridge;
        GSList *tech_drivers;
-       bool hidden;
  
        ident = technology->tethering_ident;
        passphrase = technology->tethering_passphrase;
-       hidden = technology->tethering_hidden;
  
        __sync_synchronize();
        if (!technology->enabled)
        if (!bridge)
                return -EOPNOTSUPP;
  
 -      if (technology->type == CONNMAN_SERVICE_TYPE_WIFI &&
 -          (!ident || !passphrase))
 +      if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && (!ident))
                return -EINVAL;
  
        for (tech_drivers = technology->driver_list; tech_drivers;
                        continue;
  
                err = driver->set_tethering(technology, ident, passphrase,
-                               bridge, enabled, hidden);
+                               bridge, enabled);
  
                if (result == -EINPROGRESS)
                        continue;
  
-               if (err == -EINPROGRESS || err == 0) {
+               if (err == -EINPROGRESS || err == 0)
                        result = err;
-                       continue;
-               }
        }
  
        return result;
@@@ -459,15 -447,31 +460,31 @@@ bool __connman_technology_get_offlinemo
  static void connman_technology_save_offlinemode(void)
  {
        GKeyFile *keyfile;
+       GError *error = NULL;
+       bool offlinemode;
  
        keyfile = __connman_storage_load_global();
-       if (!keyfile)
+       if (!keyfile) {
                keyfile = g_key_file_new();
+               g_key_file_set_boolean(keyfile, "global",
+                                       "OfflineMode", global_offlinemode);
  
-       g_key_file_set_boolean(keyfile, "global",
+               __connman_storage_save_global(keyfile);
+       }
+       else {
+               offlinemode = g_key_file_get_boolean(keyfile, "global",
+                                               "OfflineMode", &error);
+               if (error || offlinemode != global_offlinemode) {
+                       g_key_file_set_boolean(keyfile, "global",
                                        "OfflineMode", global_offlinemode);
+                       if (error)
+                               g_clear_error(&error);
  
-       __connman_storage_save_global(keyfile);
+                       __connman_storage_save_global(keyfile);
+               }
+       }
  
        g_key_file_free(keyfile);
  
@@@ -542,11 -546,6 +559,11 @@@ static void append_properties(DBusMessa
                                        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);
  }
  
@@@ -683,10 -682,6 +700,10 @@@ static void powered_changed(struct conn
  
        __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);
@@@ -865,7 -860,7 +882,7 @@@ static DBusMessage *set_property(DBusCo
        struct connman_technology *technology = data;
        DBusMessageIter iter, value;
        const char *name;
-       int type;
+       int type, err;
  
        DBG("conn %p", conn);
  
  
        DBG("property %s", name);
  
 +      if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && technology->connected) {
 +              uid_t uid;
 +              if (connman_dbus_get_connection_unix_user_sync(conn,
 +                                              dbus_message_get_sender(msg),
 +                                              &uid) < 0) {
 +                      DBG("Can not get unix user id!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +
 +              if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
 +                      DBG("Not allow this user to operate wifi technology now!");
 +                      return __connman_error_permission_denied(msg);
 +              }
 +      }
 +
        if (g_str_equal(name, "Tethering")) {
                dbus_bool_t tethering;
                int err;
                if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
                        return __connman_error_not_supported(msg);
  
-               if (strlen(str) < 8 || strlen(str) > 63) {
-                       if (g_str_equal(str, "")) {
-                               technology->tethering_passphrase = NULL;
+               err = __connman_service_check_passphrase(CONNMAN_SERVICE_SECURITY_PSK,
+                                                       str);
+               if (err < 0)
+                       return __connman_error_passphrase_required(msg);
  
-                               connman_dbus_property_changed_basic(technology->path,
-                                               CONNMAN_TECHNOLOGY_INTERFACE,
-                                               "TetheringPassphrase",
-                                               DBUS_TYPE_STRING,
-                                               &str);
-                       }
-                       else
-                               return __connman_error_passphrase_required(msg);
-               } else {
-                       if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
-                               g_free(technology->tethering_passphrase);
-                               technology->tethering_passphrase = g_strdup(str);
-                               technology_save(technology);
-                               connman_dbus_property_changed_basic(technology->path,
-                                               CONNMAN_TECHNOLOGY_INTERFACE,
-                                               "TetheringPassphrase",
-                                               DBUS_TYPE_STRING,
-                                               &technology->tethering_passphrase);
-                       }
+               if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
+                       g_free(technology->tethering_passphrase);
+                       technology->tethering_passphrase = g_strdup(str);
+                       technology_save(technology);
+                       connman_dbus_property_changed_basic(technology->path,
+                                       CONNMAN_TECHNOLOGY_INTERFACE,
+                                       "TetheringPassphrase",
+                                       DBUS_TYPE_STRING,
+                                       &technology->tethering_passphrase);
                }
 +      } else if (g_str_equal(name, "Hidden")) {
 +              dbus_bool_t hidden;
 +
 +              if (type != DBUS_TYPE_BOOLEAN)
 +                      return __connman_error_invalid_arguments(msg);
 +
 +              dbus_message_iter_get_basic(&value, &hidden);
 +
 +              if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
 +                      return __connman_error_not_supported(msg);
 +
 +              technology->tethering_hidden = hidden;
 +              technology_save(technology);
 +
 +              connman_dbus_property_changed_basic(technology->path,
 +                                      CONNMAN_TECHNOLOGY_INTERFACE,
 +                                      "Hidden",
 +                                      DBUS_TYPE_BOOLEAN,
 +                                      &hidden);
        } else if (g_str_equal(name, "Powered")) {
                dbus_bool_t enable;
  
@@@ -1045,38 -997,9 +1053,38 @@@ static void reply_scan_pending(struct c
        }
  }
  
 +#if defined TIZEN_EXT
 +dbus_bool_t __connman_technology_notify_scan_changed(const char *key, void *val)
 +{
 +      DBG("key %s", key);
 +      DBusMessage *signal;
 +      DBusMessageIter iter;
 +      dbus_bool_t result = FALSE;
 +
 +      signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
 +                      CONNMAN_MANAGER_INTERFACE, "ScanChanged");
 +      if (!signal)
 +              return result;
 +
 +      dbus_message_iter_init_append(signal, &iter);
 +      connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_BOOLEAN, val);
 +
 +      result = dbus_connection_send(connection, signal, NULL);
 +      dbus_message_unref(signal);
 +
 +      DBG("Successfuly sent signal");
 +
 +      return result;
 +}
 +#endif
 +
  void __connman_technology_scan_started(struct connman_device *device)
  {
        DBG("device %p", device);
 +#if defined TIZEN_EXT
 +      dbus_bool_t status = 1;
 +      __connman_technology_notify_scan_changed("scan_started", &status);
 +#endif
  }
  
  void __connman_technology_scan_stopped(struct connman_device *device,
                        count += 1;
        }
  
 +#if defined TIZEN_EXT
 +      if (count == 0) {
 +              DBusMessage *signal;
 +              DBusMessageIter iter;
 +              dbus_bool_t status = 0;
 +              __connman_technology_notify_scan_changed("scan_done", &status);
 +
 +              signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
 +                              CONNMAN_MANAGER_INTERFACE, "ScanDone");
 +              if (!signal)
 +                      return;
 +
 +              dbus_message_iter_init_append(signal, &iter);
 +              connman_dbus_property_append_basic(&iter, "Scantype",
 +                              DBUS_TYPE_INT32, &g_scan_type);
 +
 +              dbus_connection_send(connection, signal, NULL);
 +              dbus_message_unref(signal);
 +              reply_scan_pending(technology, 0);
 +
 +              DBG("Successfuly sent ScanDone signal");
 +      }
 +#else
        if (count == 0)
                reply_scan_pending(technology, 0);
 +#endif
  }
  
  void __connman_technology_notify_regdom_by_device(struct connman_device *device,
@@@ -1178,157 -1077,21 +1186,161 @@@ static DBusMessage *scan(DBusConnectio
        DBG("technology %p request from %s", technology,
                        dbus_message_get_sender(msg));
  
+       if (technology->type == CONNMAN_SERVICE_TYPE_P2P &&
+                               !technology->enabled)
+               return __connman_error_permission_denied(msg);
        dbus_message_ref(msg);
 +#if !defined TIZEN_EXT
        technology->scan_pending =
                g_slist_prepend(technology->scan_pending, msg);
 +#endif
  
        err = __connman_device_request_scan(technology->type);
 +#if defined TIZEN_EXT
 +      if (err < 0)
 +              return __connman_error_failed(msg, -err);
 +#else
        if (err < 0)
                reply_scan_pending(technology, err);
 +#endif
  
 +#if defined TIZEN_EXT
 +      if (err == 0) {
 +              g_scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL;
 +              DBG("g_scan_type %d", g_scan_type);
 +      }
 +      technology->scan_pending =
 +              g_slist_prepend(technology->scan_pending, msg);
 +#endif
        return NULL;
  }
  
 +#if defined TIZEN_EXT
 +static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data)
 +{
 +      struct connman_technology *technology = data;
 +      GSList *specific_scan_list = NULL;
 +      int scan_type = 0;
 +      const char *name = NULL;
 +      unsigned int freq = 0;
 +      DBusMessageIter iter, dict;
 +      int err;
 +
 +      DBG("technology %p request from %s", technology,
 +                      dbus_message_get_sender(msg));
 +
 +      if (!dbus_message_iter_init(msg, &iter))
 +              return __connman_error_invalid_arguments(msg);
 +
 +      if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
 +              return __connman_error_invalid_arguments(msg);
 +
 +      dbus_message_iter_recurse(&iter, &dict);
 +      while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
 +              DBusMessageIter entry, value2;
 +              const char *key;
 +              int type;
 +
 +              dbus_message_iter_recurse(&dict, &entry);
 +              if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
 +                      g_slist_free_full(specific_scan_list, g_free);
 +                      return __connman_error_invalid_arguments(msg);
 +              }
 +
 +              dbus_message_iter_get_basic(&entry, &key);
 +              dbus_message_iter_next(&entry);
 +
 +              if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) {
 +                      g_slist_free_full(specific_scan_list, g_free);
 +                      return __connman_error_invalid_arguments(msg);
 +              }
 +
 +              dbus_message_iter_recurse(&entry, &value2);
 +              type = dbus_message_iter_get_arg_type(&value2);
 +              if (g_str_equal(key, "SSID")) {
 +                      if (type != DBUS_TYPE_STRING) {
 +                              g_slist_free_full(specific_scan_list, g_free);
 +                              return __connman_error_invalid_arguments(msg);
 +                      }
 +
 +                      scan_type = 1; /* SSID based scan */
 +                      dbus_message_iter_get_basic(&value2, &name);
 +                      DBG("name %s", name);
 +                      specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name));
 +              } else if (g_str_equal(key, "Frequency")) {
 +                      if (type != DBUS_TYPE_UINT16) {
 +                              g_slist_free_full(specific_scan_list, g_free);
 +                              return __connman_error_invalid_arguments(msg);
 +                      }
 +
 +                      scan_type = 2; /* Frequency based scan */
 +                      dbus_message_iter_get_basic(&value2, &freq);
 +                      DBG("freq %d", freq);
 +                      specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(freq));
 +              }
 +              dbus_message_iter_next(&dict);
 +      }
 +
 +      dbus_message_ref(msg);
 +
 +      err = __connman_device_request_specific_scan(technology->type, scan_type, specific_scan_list);
 +      if (err < 0)
 +              return __connman_error_failed(msg, -err);
 +
 +      if (err == 0) {
 +              guint list_size = g_slist_length(specific_scan_list);
 +              if (list_size == 1)
 +                      g_scan_type = CONNMAN_SCAN_TYPE_SPECIFIC_AP;
 +              else
 +                      g_scan_type = CONNMAN_SCAN_TYPE_MULTI_AP;
 +              DBG("list_size %u g_scan_type %d", list_size, g_scan_type);
 +      }
 +      technology->scan_pending =
 +              g_slist_prepend(technology->scan_pending, msg);
 +
 +      if (scan_type == 1) {
 +              g_slist_free_full(specific_scan_list, g_free);
 +              scan_type = 0;
 +      }
 +      return NULL;
 +}
 +
 +static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
 +{
 +      DBusMessage *reply;
 +      DBusMessageIter iter, dict;
 +      GSList *list;
 +      struct connman_technology *technology = data;
 +      dbus_bool_t scanning = false;
 +
 +      DBG("technology %p", technology);
 +
 +      for (list = technology->device_list; list; list = list->next) {
 +              struct connman_device *device = list->data;
 +              scanning = connman_device_get_scanning(device);
 +              if(scanning)
 +                      break;
 +      }
 +
 +      DBG("scanning : %d", scanning);
 +      reply = dbus_message_new_method_return(msg);
 +      if (!reply)
 +              return NULL;
 +
 +      dbus_message_iter_init_append(reply, &iter);
 +
 +      connman_dbus_dict_open(&iter, &dict);
 +      connman_dbus_dict_append_basic(&dict, "Scanstate",
 +                                      DBUS_TYPE_BOOLEAN,
 +                                      &scanning);
 +
 +      connman_dbus_dict_close(&iter, &dict);
 +
 +      return reply;
 +}
 +#endif
 +
  static const GDBusMethodTable technology_methods[] = {
        { GDBUS_DEPRECATED_METHOD("GetProperties",
                        NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
                        NULL, set_property) },
        { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
 +#if defined TIZEN_EXT
 +      { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }),
 +                      NULL, specific_scan) },
 +      { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
 +                      get_scan_state) },
 +#endif
        { },
  };
  
  static const GDBusSignalTable technology_signals[] = {
        { GDBUS_SIGNAL("PropertyChanged",
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
 +      { GDBUS_SIGNAL("DhcpConnected",
 +                      GDBUS_ARGS({ "aptype", "s" },
 +                              { "ipaddr", "s" },
 +                              { "macaddr", "s" },
 +                              { "hostname", "s" })) },
 +      { GDBUS_SIGNAL("DhcpLeaseDeleted",
 +                      GDBUS_ARGS({ "aptype", "s" },
 +                              { "ipaddr", "s" },
 +                              { "macaddr", "s" },
 +                              { "hostname", "s" })) },
        { },
  };
  
@@@ -1423,6 -1170,13 +1435,13 @@@ static void technology_put(struct connm
  
        g_slist_free(technology->device_list);
  
+     if (technology->pending_reply) {
+         dbus_message_unref(technology->pending_reply);
+         technology->pending_reply = NULL;
+         g_source_remove(technology->pending_timeout);
+         technology->pending_timeout = 0;
+     }
        g_free(technology->path);
        g_free(technology->regdom);
        g_free(technology->tethering_ident);
@@@ -1473,7 -1227,6 +1492,7 @@@ static struct connman_technology *techn
  
        technology->refcount = 1;
        technology->type = type;
 +      technology->tethering_hidden = FALSE;
        technology->path = g_strdup_printf("%s/technology/%s",
                                                        CONNMAN_PATH, str);
  
@@@ -1779,13 -1532,12 +1798,13 @@@ int __connman_technology_enabled(enum c
        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);
  }
@@@ -1798,10 -1550,10 +1817,10 @@@ int __connman_technology_disabled(enum 
        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;
  
@@@ -1980,10 -1732,6 +1999,10 @@@ int __connman_technology_add_rfkill(uns
        g_hash_table_insert(rfkill_list, GINT_TO_POINTER(index), rfkill);
  
  done:
 +#if defined TIZEN_EXT
 +      /* Fix Svace Issue [WGID: 1348]. */
 +      g_free(rfkill);
 +#endif
        technology = technology_get(type);
        /* If there is no driver for this type, ignore it. */
        if (!technology)
  
        technology->rfkill_driven = true;
  
 +#if !defined TIZEN_EXT
        /* If hardblocked, there is no need to handle softblocked state */
        if (technology_apply_rfkill_change(technology,
                                softblock, hardblock, true))
                return 0;
 -
 +#endif
        if (global_offlinemode)
                return 0;
  
diff --combined src/tethering.c
index c0c9743,c929ba7..891ee51
mode 100755,100644..100755
@@@ -52,9 -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;
  
@@@ -63,7 -60,6 +63,7 @@@ static GDHCPServer *tethering_dhcp_serv
  static struct connman_ippool *dhcp_ippool = NULL;
  static DBusConnection *connection;
  static GHashTable *pn_hash;
 +static GHashTable *sta_hash;
  
  struct connman_private_network {
        char *owner;
        char *secondary_dns;
  };
  
 +struct connman_station_info {
 +      bool is_connected;
 +      char *path;
 +      char *type;
 +      char ip[CONNMAN_STATION_STR_INFO_LEN];
 +      char mac[CONNMAN_STATION_MAC_INFO_LEN];
 +      char hostname[CONNMAN_STATION_STR_INFO_LEN];
 +};
 +
 +static void emit_station_signal(char *action_str,
 +                      const struct connman_station_info *station_info)
 +{
 +      char *ip, *mac, *hostname;
 +
 +      if (station_info->path == NULL || station_info->type == NULL
 +              || station_info->ip == NULL || station_info->mac == NULL
 +                      || station_info->hostname == NULL)
 +              return;
 +
 +      ip = g_strdup(station_info->ip);
 +      mac = g_strdup(station_info->mac);
 +      hostname = g_strdup(station_info->hostname);
 +
 +      g_dbus_emit_signal(connection, station_info->path,
 +                      CONNMAN_TECHNOLOGY_INTERFACE, action_str,
 +                      DBUS_TYPE_STRING, &station_info->type,
 +                      DBUS_TYPE_STRING, &ip,
 +                      DBUS_TYPE_STRING, &mac,
 +                      DBUS_TYPE_STRING, &hostname,
 +                      DBUS_TYPE_INVALID);
 +
 +      g_free(ip);
 +      g_free(mac);
 +      g_free(hostname);
 +}
 +static void destroy_station(gpointer key, gpointer value, gpointer user_data)
 +{
 +      struct connman_station_info *station_info;
 +
 +      __sync_synchronize();
 +
 +      station_info = value;
 +
 +      if (station_info->is_connected) {
 +              station_info->is_connected = FALSE;
 +              emit_station_signal("DhcpLeaseDeleted", station_info);
 +      }
 +
 +      g_free(station_info->path);
 +      g_free(station_info->type);
 +      g_free(station_info);
 +}
 +
 +static void save_dhcp_ack_lease_info(char *hostname,
 +                                   unsigned char *mac, unsigned int nip)
 +{
 +      char *lower_mac;
 +      const char *ip;
 +      char sta_mac[CONNMAN_STATION_MAC_INFO_LEN];
 +      struct connman_station_info *info_found;
 +      struct in_addr addr;
 +      int str_len;
 +
 +      __sync_synchronize();
 +
 +      snprintf(sta_mac, CONNMAN_STATION_MAC_INFO_LEN,
 +               "%02x:%02x:%02x:%02x:%02x:%02x",
 +               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 +      lower_mac = g_ascii_strdown(sta_mac, -1);
 +
 +      info_found = g_hash_table_lookup(sta_hash, lower_mac);
 +      if (info_found == NULL) {
 +              g_free(lower_mac);
 +              return;
 +      }
 +
 +      /* get the ip */
 +      addr.s_addr = nip;
 +      ip = inet_ntoa(addr);
 +      str_len = strlen(ip) + 1;
 +      if (str_len > CONNMAN_STATION_STR_INFO_LEN)
 +              str_len = CONNMAN_STATION_STR_INFO_LEN - 1;
 +      memcpy(info_found->ip, ip, str_len);
 +
 +      /* get hostname */
 +      str_len = strlen(hostname) + 1;
 +      if (str_len > CONNMAN_STATION_STR_INFO_LEN)
 +              str_len = CONNMAN_STATION_STR_INFO_LEN - 1;
 +      memcpy(info_found->hostname, hostname, str_len);
 +
 +      /* emit a signal */
 +      info_found->is_connected = TRUE;
 +      emit_station_signal("DhcpConnected", info_found);
 +      g_free(lower_mac);
 +}
 +
 +int connman_technology_tethering_add_station(enum connman_service_type type,
 +                                                      const char *mac)
 +{
 +      const char *str_type;
 +      char *lower_mac;
 +      char *path;
 +      struct connman_station_info *station_info;
 +
 +      __sync_synchronize();
 +
 +      DBG("type %d", type);
 +
 +      str_type = __connman_service_type2string(type);
 +      if (str_type == NULL)
 +              return 0;
 +
 +      path = g_strdup_printf("%s/technology/%s", CONNMAN_PATH, str_type);
 +
 +      station_info = g_try_new0(struct connman_station_info, 1);
 +      if (station_info == NULL)
 +              return -ENOMEM;
 +
 +      lower_mac = g_ascii_strdown(mac, -1);
 +
 +      memcpy(station_info->mac, lower_mac, strlen(lower_mac) + 1);
 +      station_info->path = path;
 +      station_info->type = g_strdup(str_type);
 +
 +      g_hash_table_insert(sta_hash, station_info->mac, station_info);
 +
 +      g_free(lower_mac);
 +      return 0;
 +}
 +
 +int connman_technology_tethering_remove_station(const char *mac)
 +{
 +      char *lower_mac;
 +      struct connman_station_info *info_found;
 +
 +      __sync_synchronize();
 +
 +      lower_mac = g_ascii_strdown(mac, -1);
 +
 +      info_found = g_hash_table_lookup(sta_hash, lower_mac);
 +      if (info_found == NULL) {
 +              g_free(lower_mac);
 +              return -EACCES;
 +      }
 +
 +      if (info_found->is_connected) {
 +              info_found->is_connected = FALSE;
 +              emit_station_signal("DhcpLeaseDeleted", info_found);
 +      }
 +      g_free(lower_mac);
 +      g_hash_table_remove(sta_hash, info_found->mac);
 +      g_free(info_found->path);
 +      g_free(info_found->type);
 +      g_free(info_found);
 +
 +      return 0;
 +}
 +
  const char *__connman_tethering_get_bridge(void)
  {
        int sk, err;
@@@ -323,9 -161,6 +323,9 @@@ static GDHCPServer *dhcp_server_start(c
        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;
@@@ -346,7 -181,7 +346,7 @@@ static void tethering_restart(struct co
        __connman_tethering_set_enabled();
  }
  
void __connman_tethering_set_enabled(void)
int __connman_tethering_set_enabled(void)
  {
        int index;
        int err;
        DBG("enabled %d", tethering_enabled + 1);
  
        if (__sync_fetch_and_add(&tethering_enabled, 1) != 0)
-               return;
+               return 0;
  
        err = __connman_bridge_create(BRIDGE_NAME);
        if (err < 0) {
                __sync_fetch_and_sub(&tethering_enabled, 1);
-               return;
+               return -EOPNOTSUPP;
        }
  
        index = connman_inet_ifindex(BRIDGE_NAME);
                connman_error("Fail to create IP pool");
                __connman_bridge_remove(BRIDGE_NAME);
                __sync_fetch_and_sub(&tethering_enabled, 1);
-               return;
+               return -EADDRNOTAVAIL;
        }
  
        gateway = __connman_ippool_get_gateway(dhcp_ippool);
                __connman_ippool_unref(dhcp_ippool);
                __connman_bridge_remove(BRIDGE_NAME);
                __sync_fetch_and_sub(&tethering_enabled, 1);
-               return;
+               return -EADDRNOTAVAIL;
        }
  
        ns = connman_setting_get_string_list("FallbackNameservers");
                __connman_ippool_unref(dhcp_ippool);
                __connman_bridge_remove(BRIDGE_NAME);
                __sync_fetch_and_sub(&tethering_enabled, 1);
-               return;
+               return -EOPNOTSUPP;
        }
  
        prefixlen = connman_ipaddress_calc_netmask_len(subnet_mask);
                __connman_ippool_unref(dhcp_ippool);
                __connman_bridge_remove(BRIDGE_NAME);
                __sync_fetch_and_sub(&tethering_enabled, 1);
-               return;
+               return -EOPNOTSUPP;
        }
  
        err = __connman_ipv6pd_setup(BRIDGE_NAME);
                        strerror(-err));
  
        DBG("tethering started");
+       return 0;
  }
  
  void __connman_tethering_set_disabled(void)
@@@ -670,6 -507,8 +672,8 @@@ error
        close(fd);
        g_free(iface);
        g_free(path);
+       if (pn)
+               g_free(pn->owner);
        g_free(pn);
        return err;
  }
@@@ -699,9 -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;
  }
  
@@@ -722,7 -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 --combined src/timeserver.c
index fc83f9a,0e555a7..6325ece
mode 100755,100644..100755
@@@ -88,15 -88,6 +88,15 @@@ static void resolv_result(GResolvResult
  {
        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) {
@@@ -157,13 -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;
  }
@@@ -305,6 -291,8 +305,8 @@@ static void ts_recheck_enable(void
  int __connman_timeserver_sync(struct connman_service *default_service)
  {
        struct connman_service *service;
+       char **nameservers;
+       int i;
  
        if (default_service)
                service = default_service;
        if (resolv_id > 0)
                g_resolv_cancel_lookup(resolv, resolv_id);
  
+       g_resolv_flush_nameservers(resolv);
+       nameservers = connman_service_get_nameservers(service);
+       if (!nameservers)
+               return -EINVAL;
+       for (i = 0; nameservers[i]; i++)
+               g_resolv_add_nameserver(resolv, nameservers[i], 53, 0);
+       g_strfreev(nameservers);
        g_slist_free_full(ts_list, g_free);
  
        ts_list = __connman_timeserver_get_all(service);
diff --combined src/util.c
index da32cc5,732d451..732d451
mode 100755,100644..100755
  
  #define URANDOM "/dev/urandom"
  
- int f = -1;
static int f = -1;
  
  int __connman_util_get_random(uint64_t *val)
  {
-       int r = 0;
+       int r;
  
        if (!val)
                return -EINVAL;
  
-       if (read(f, val, sizeof(uint64_t)) < 0) {
+       r = read(f, val, sizeof(uint64_t));
+       if (r < 0) {
                r = -errno;
                connman_warn_once("Could not read from "URANDOM);
                *val = random();
+       } else if (r != sizeof(uint64_t)) {
+               r = -EIO;
+               connman_warn_once("Short read from "URANDOM);
+               *val = random();
        }
  
        return r;
@@@ -58,7 -63,7 +63,7 @@@ int __connman_util_init(void
  {
        int r = 0;
  
-       if (f > 0)
+       if (f >= 0)
                return 0;
  
        f = open(URANDOM, O_RDONLY);
@@@ -81,7 -86,7 +86,7 @@@
  
  void __connman_util_cleanup(void)
  {
-       if (f > 0)
+       if (f >= 0)
                close(f);
  
        f = -1;
diff --combined src/wispr.c
index c3b0c9c,03b38bb..adf6230
mode 100755,100644..100755
@@@ -832,8 -832,8 +832,8 @@@ static int wispr_portal_detect(struct c
        int err = 0;
        int i;
  
-       DBG("wispr/portal context %p", wp_context);
-       DBG("service %p", wp_context->service);
+       DBG("wispr/portal context %p service %p", wp_context,
+               wp_context->service);
  
        service_type = connman_service_get_type(wp_context->service);
  
                goto done;
        }
  
 +#if !defined TIZEN_EXT
        if (getenv("CONNMAN_WEB_DEBUG"))
 +#endif
                g_web_set_debug(wp_context->web, web_debug, "WEB");
  
        if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
                        free_connman_wispr_portal_context(wp_context);
                }
        } else if (wp_context->timeout == 0) {
-               wp_context->timeout =
-                       g_timeout_add_seconds(0, no_proxy_callback, wp_context);
+               wp_context->timeout = g_idle_add(no_proxy_callback, wp_context);
        }
  
  done:
@@@ -928,11 -925,6 +927,11 @@@ int __connman_wispr_start(struct connma
  
        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 --combined src/wpad.c
index 109e9d7,f066fee..b7f1f1e
mode 100755,100644..100755
@@@ -49,6 -49,8 +49,8 @@@ static void free_wpad(gpointer data
  {
          struct connman_wpad *wpad = data;
  
+       connman_service_unref(wpad->service);
        g_resolv_unref(wpad->resolv);
  
        g_strfreev(wpad->addrlist);
@@@ -152,7 -154,6 +154,6 @@@ int __connman_wpad_start(struct connman
                return -ENOMEM;
        }
  
-       wpad->service = service;
        wpad->resolv = g_resolv_new(index);
        if (!wpad->resolv) {
                g_strfreev(nameservers);
                return -ENOMEM;
        }
  
 +#if !defined TIZEN_EXT
        if (getenv("CONNMAN_RESOLV_DEBUG"))
 +#endif
                g_resolv_set_debug(wpad->resolv, resolv_debug, "RESOLV");
  
        for (i = 0; nameservers[i]; i++)
  
        DBG("hostname %s", wpad->hostname);
  
+       wpad->service = connman_service_ref(service);
        g_resolv_lookup_hostname(wpad->resolv, wpad->hostname,
                                                        wpad_result, wpad);
  
-       connman_service_ref(service);
        g_hash_table_replace(wpad_list, GINT_TO_POINTER(index), wpad);
  
        return 0;
@@@ -196,8 -196,7 +198,7 @@@ void __connman_wpad_stop(struct connman
        if (index < 0)
                return;
  
-       if (g_hash_table_remove(wpad_list, GINT_TO_POINTER(index)))
-               connman_service_unref(service);
+       g_hash_table_remove(wpad_list, GINT_TO_POINTER(index));
  }
  
  int __connman_wpad_init(void)
diff --combined tools/iptables-unit.c
index 7e427e2,426631a..426631a
mode 100755,100644..100755
@@@ -24,6 -24,7 +24,7 @@@
  #endif
  
  #include <glib.h>
+ #include <errno.h>
  
  #include "../src/connman.h"
  
@@@ -32,6 -33,7 +33,7 @@@ static bool assert_rule(const char *tab
        char *cmd, *output, **lines;
        GError **error = NULL;
        int i;
+       bool ret = true;
  
        cmd = g_strdup_printf(IPTABLES_SAVE " -t %s", table_name);
        g_spawn_command_line_sync(cmd, &output, NULL, NULL, error);
  
        lines = g_strsplit(output, "\n", 0);
        g_free(output);
+       if (!lines)
+               return false;
  
        for (i = 0; lines[i]; i++) {
                DBG("lines[%02d]: %s\n", i, lines[i]);
                if (g_strcmp0(lines[i], rule) == 0)
                        break;
        }
-       g_strfreev(lines);
  
        if (!lines[i])
-               return false;
+               ret = false;
  
-       return true;
+       g_strfreev(lines);
+       return ret;
  }
  
  static void assert_rule_exists(const char *table_name, const char *rule)
@@@ -402,85 -406,6 +406,6 @@@ static void test_nat_basic1(void
        g_free(service);
  }
  
- static void test_firewall_basic0(void)
- {
-       struct firewall_context *ctx;
-       int err;
-       ctx = __connman_firewall_create();
-       g_assert(ctx);
-       err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
-                                       "-m mark --mark 999 -j LOG");
-       g_assert(err == 0);
-       err = __connman_firewall_enable(ctx);
-       g_assert(err == 0);
-       assert_rule_exists("filter", ":connman-INPUT - [0:0]");
-       assert_rule_exists("filter", "-A INPUT -j connman-INPUT");
-       assert_rule_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
-       err = __connman_firewall_disable(ctx);
-       g_assert(err == 0);
-       assert_rule_not_exists("filter", ":connman-INPUT - [0:0]");
-       assert_rule_not_exists("filter", "-A INPUT -j connman-INPUT");
-       assert_rule_not_exists("filter", "-A connman-INPUT -m mark --mark 0x3e7 -j LOG");
-       __connman_firewall_destroy(ctx);
- }
- static void test_firewall_basic1(void)
- {
-       struct firewall_context *ctx;
-       int err;
-       ctx = __connman_firewall_create();
-       g_assert(ctx);
-       err = __connman_firewall_add_rule(ctx, "filter", "INPUT",
-                                       "-m mark --mark 999 -j LOG");
-       g_assert(err == 0);
-       err = __connman_firewall_add_rule(ctx, "filter", "OUTPUT",
-                                       "-m mark --mark 999 -j LOG");
-       g_assert(err == 0);
-       err = __connman_firewall_enable(ctx);
-       g_assert(err == 0);
-       err = __connman_firewall_disable(ctx);
-       g_assert(err == 0);
-       __connman_firewall_destroy(ctx);
- }
- static void test_firewall_basic2(void)
- {
-       struct firewall_context *ctx;
-       int err;
-       ctx = __connman_firewall_create();
-       g_assert(ctx);
-       err = __connman_firewall_add_rule(ctx, "mangle", "INPUT",
-                                       "-j CONNMARK --restore-mark");
-       g_assert(err == 0);
-       err = __connman_firewall_add_rule(ctx, "mangle", "POSTROUTING",
-                                       "-j CONNMARK --save-mark");
-       g_assert(err == 0);
-       err = __connman_firewall_enable(ctx);
-       g_assert(err == 0);
-       err = __connman_firewall_disable(ctx);
-       g_assert(err == 0);
-       __connman_firewall_destroy(ctx);
- }
  static gchar *option_debug = NULL;
  
  static bool parse_debug(const char *key, const char *value,
@@@ -527,7 -452,6 +452,6 @@@ int main(int argc, char *argv[]
                        "Unit Tests Connection Manager", VERSION);
  
        __connman_iptables_init();
-       __connman_firewall_init();
        __connman_nat_init();
  
        g_test_add_func("/iptables/chain0", test_iptables_chain0);
        g_test_add_func("/iptables/target0", test_iptables_target0);
        g_test_add_func("/nat/basic0", test_nat_basic0);
        g_test_add_func("/nat/basic1", test_nat_basic1);
-       g_test_add_func("/firewall/basic0", test_firewall_basic0);
-       g_test_add_func("/firewall/basic1", test_firewall_basic1);
-       g_test_add_func("/firewall/basic2", test_firewall_basic2);
  
        err = g_test_run();
  
        __connman_nat_cleanup();
-       __connman_firewall_cleanup();
        __connman_iptables_cleanup();
  
        g_free(option_debug);
diff --combined tools/session-test.h
index 5e6d196,8512933..8512933
mode 100755,100644..100755
@@@ -68,12 -68,6 +68,6 @@@ void util_session_cleanup(struct test_s
  
  typedef void (* notify_func_t) (struct test_session *session);
  
- enum connman_session_state {
-       CONNMAN_SESSION_STATE_DISCONNECTED   = 0,
-       CONNMAN_SESSION_STATE_CONNECTED      = 1,
-       CONNMAN_SESSION_STATE_ONLINE         = 2,
- };
  struct test_session_info {
        enum connman_session_state state;
        char *name;
diff --combined tools/stats-tool.c
index 7d117fd,efa39de..efa39de
mode 100755,100644..100755
@@@ -794,7 -794,7 +794,7 @@@ static void swap_and_close_files(struc
        munmap(history_file->addr, history_file->len);
        munmap(temp_file->addr, temp_file->len);
  
-       TFR(close(temp_file->fd));
+       close(temp_file->fd);
  
        unlink(history_file->name);
  
                return;
  
        unlink(temp_file->name);
-       TFR(close(history_file->fd));
+       close(history_file->fd);
  }
  
  static void history_file_update(struct stats_file *data_file,
@@@ -885,6 -885,11 +885,11 @@@ int main(int argc, char *argv[]
        else
                start_ts = option_start_ts;
  
+       if (option_interval == 0) {
+               printf("interval cannot be zero, using the default value\n");
+               option_interval = 3;
+       }
        if (option_create > 0)
                stats_create(data_file, option_create, option_interval,
                                start_ts, rec);
diff --combined unit/test-ippool.c
index e8d077a,17fac9d..17fac9d
mode 100755,100644..100755
@@@ -253,7 -253,7 +253,7 @@@ static void test_case_4(void
  
  static void test_case_5(void)
  {
-       struct connman_ippool *pool;
+       struct connman_ippool *pool1, *pool2;
        const char *gateway;
        const char *broadcast;
        const char *subnet_mask;
        g_assert(flag == 0);
  
        /* pool should return 192.168.0.1 now */
-       pool = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
-       g_assert(pool);
+       pool1 = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
+       g_assert(pool1);
  
-       gateway = __connman_ippool_get_gateway(pool);
-       broadcast = __connman_ippool_get_broadcast(pool);
-       subnet_mask = __connman_ippool_get_subnet_mask(pool);
-       start_ip = __connman_ippool_get_start_ip(pool);
-       end_ip = __connman_ippool_get_end_ip(pool);
+       gateway = __connman_ippool_get_gateway(pool1);
+       broadcast = __connman_ippool_get_broadcast(pool1);
+       subnet_mask = __connman_ippool_get_subnet_mask(pool1);
+       start_ip = __connman_ippool_get_start_ip(pool1);
+       end_ip = __connman_ippool_get_end_ip(pool1);
  
        g_assert(gateway);
        g_assert(broadcast);
                "\tgateway %s broadcast %s mask %s", start_ip, end_ip,
                gateway, broadcast, subnet_mask);
  
-       __connman_ippool_unref(pool);
        /*
         * Now create the pool again, we should not get collision
         * with existing allocated address.
  
        /* pool should return 192.168.2.1 now */
        flag = 0;
-       pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
-       g_assert(pool);
+       pool2 = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+       g_assert(pool2);
  
-       gateway = __connman_ippool_get_gateway(pool);
-       broadcast = __connman_ippool_get_broadcast(pool);
-       subnet_mask = __connman_ippool_get_subnet_mask(pool);
-       start_ip = __connman_ippool_get_start_ip(pool);
-       end_ip = __connman_ippool_get_end_ip(pool);
+       gateway = __connman_ippool_get_gateway(pool2);
+       broadcast = __connman_ippool_get_broadcast(pool2);
+       subnet_mask = __connman_ippool_get_subnet_mask(pool2);
+       start_ip = __connman_ippool_get_start_ip(pool2);
+       end_ip = __connman_ippool_get_end_ip(pool2);
  
        g_assert(gateway);
        g_assert(broadcast);
  
        g_assert(flag == 0);
  
-       __connman_ippool_unref(pool);
+       __connman_ippool_unref(pool1);
+       __connman_ippool_unref(pool2);
  
        __connman_ippool_cleanup();
  }
  
  static void test_case_6(void)
  {
-       struct connman_ippool *pool;
+       struct connman_ippool *pool1, *pool2;
        const char *gateway;
        const char *broadcast;
        const char *subnet_mask;
        g_assert(flag == 0);
  
        /* pool should return 192.168.2.1 now */
-       pool = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
-       g_assert(pool);
+       pool1 = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
+       g_assert(pool1);
  
-       gateway = __connman_ippool_get_gateway(pool);
-       broadcast = __connman_ippool_get_broadcast(pool);
-       subnet_mask = __connman_ippool_get_subnet_mask(pool);
-       start_ip = __connman_ippool_get_start_ip(pool);
-       end_ip = __connman_ippool_get_end_ip(pool);
+       gateway = __connman_ippool_get_gateway(pool1);
+       broadcast = __connman_ippool_get_broadcast(pool1);
+       subnet_mask = __connman_ippool_get_subnet_mask(pool1);
+       start_ip = __connman_ippool_get_start_ip(pool1);
+       end_ip = __connman_ippool_get_end_ip(pool1);
  
        g_assert(gateway);
        g_assert(broadcast);
                "\tgateway %s broadcast %s mask %s", start_ip, end_ip,
                gateway, broadcast, subnet_mask);
  
-       __connman_ippool_unref(pool);
        /*
         * Now create the pool again, we should not get collision
         * with existing allocated address.
  
        /* pool should return 192.168.3.1 now */
        flag = 0;
-       pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
-       g_assert(pool);
+       pool2 = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+       g_assert(pool2);
  
-       gateway = __connman_ippool_get_gateway(pool);
-       broadcast = __connman_ippool_get_broadcast(pool);
-       subnet_mask = __connman_ippool_get_subnet_mask(pool);
-       start_ip = __connman_ippool_get_start_ip(pool);
-       end_ip = __connman_ippool_get_end_ip(pool);
+       gateway = __connman_ippool_get_gateway(pool2);
+       broadcast = __connman_ippool_get_broadcast(pool2);
+       subnet_mask = __connman_ippool_get_subnet_mask(pool2);
+       start_ip = __connman_ippool_get_start_ip(pool2);
+       end_ip = __connman_ippool_get_end_ip(pool2);
  
        g_assert(gateway);
        g_assert(broadcast);
        __connman_ippool_newaddr(25, start_ip, 24);
        g_assert(flag == 1);
  
-       __connman_ippool_unref(pool);
+       __connman_ippool_unref(pool1);
+       __connman_ippool_unref(pool2);
  
        __connman_ippool_cleanup();
  }
index 03eaf22,e98fb71..a8f2948
mode 100755,100644..100755
@@@ -1,18 -1,14 +1,20 @@@
  [Unit]
  Description=ConnMan VPN service
 +Requires=dbus.socket
 +After=dbus.socket
  
  [Service]
  Type=dbus
 +User=network_fw
 +Group=network_fw
  BusName=net.connman.vpn
 -ExecStart=@sbindir@/connman-vpnd -n
 +SmackProcessLabel=System
 +ExecStart=@bindir@/connman-vpnd -n
  StandardOutput=null
- Capabilities=cap_setgid,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i
 -CapabilityBoundingSet=CAP_KILL CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
++Capabilities=cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i
 +SecureBits=keep-caps
+ ProtectHome=read-only
+ ProtectSystem=full
  
  [Install]
  WantedBy=multi-user.target
diff --combined vpn/main.c
index debb0ca,ee88aac..c18fee4
mode 100755,100644..100755
@@@ -45,7 -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;
  
@@@ -53,10 -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)
@@@ -227,21 -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.
@@@ -251,11 -233,6 +251,16 @@@ unsigned int connman_timeout_input_requ
        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 --combined vpn/plugins/l2tp.c
index 22f9dcf,a0d22c4..a0d22c4
mode 100755,100644..100755
@@@ -108,13 -108,13 +108,13 @@@ struct 
        { "PPPD.RefuseMSCHAP2", "refuse-mschapv2", OPT_PPPD, NULL, OPT_BOOL },
        { "PPPD.NoBSDComp", "nobsdcomp", OPT_PPPD, NULL, OPT_BOOL },
        { "PPPD.NoPcomp", "nopcomp", OPT_PPPD, NULL, OPT_BOOL },
-       { "PPPD.UseAccomp", "accomp", OPT_PPPD, NULL, OPT_BOOL },
+       { "PPPD.UseAccomp", "noaccomp", OPT_PPPD, NULL, OPT_BOOL },
        { "PPPD.NoDeflate", "nodeflate", OPT_PPPD, NULL, OPT_BOOL },
        { "PPPD.ReqMPPE", "require-mppe", OPT_PPPD, NULL, OPT_BOOL },
        { "PPPD.ReqMPPE40", "require-mppe-40", OPT_PPPD, NULL, OPT_BOOL },
        { "PPPD.ReqMPPE128", "require-mppe-128", OPT_PPPD, NULL, OPT_BOOL },
        { "PPPD.ReqMPPEStateful", "mppe-stateful", OPT_PPPD, NULL, OPT_BOOL },
-       { "PPPD.NoVJ", "no-vj-comp", OPT_PPPD, NULL, OPT_BOOL },
+       { "PPPD.NoVJ", "novj", OPT_PPPD, NULL, OPT_BOOL },
  };
  
  static DBusConnection *connection;
@@@ -497,8 -497,9 +497,9 @@@ static void request_input_reply(DBusMes
  
        DBG("provider %p", l2tp_reply->provider);
  
-       if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               error = dbus_message_get_error_name(reply);
+       if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+               if (reply)
+                       error = dbus_message_get_error_name(reply);
                goto done;
        }
  
index 5feaed9,87679bf..87679bf
mode 100755,100644..100755
@@@ -315,7 -315,7 +315,7 @@@ static void request_input_cookie_reply(
  
        DBG("provider %p", data->provider);
  
-       if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+       if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
                goto err;
  
        if (!vpn_agent_check_reply_has_dict(reply))
diff --combined vpn/plugins/openvpn.c
index e226afd,e339509..d115df6
mode 100755,100644..100755
@@@ -29,6 -29,7 +29,7 @@@
  #include <unistd.h>
  #include <stdio.h>
  #include <net/if.h>
+ #include <linux/if_tun.h>
  
  #include <glib.h>
  
@@@ -71,6 -72,8 +72,8 @@@ struct 
        { "OpenVPN.CompLZO", "--comp-lzo", 0 },
        { "OpenVPN.RemoteCertTls", "--remote-cert-tls", 1 },
        { "OpenVPN.ConfigFile", "--config", 1 },
+       { "OpenVPN.DeviceType", NULL, 1 },
+       { "OpenVPN.Verb", "--verb", 1 },
  };
  
  struct nameserver_entry {
@@@ -156,7 -159,7 +159,7 @@@ static int ov_notify(DBusMessage *msg, 
  {
        DBusMessageIter iter, dict;
        const char *reason, *key, *value;
-       char *address = NULL, *gateway = NULL, *peer = NULL;
+       char *address = NULL, *gateway = NULL, *peer = NULL, *netmask = NULL;
        struct connman_ipaddress *ipaddress;
        GSList *nameserver_list = NULL;
  
                if (!strcmp(key, "ifconfig_local"))
                        address = g_strdup(value);
  
+               if (!strcmp(key, "ifconfig_netmask"))
+                       netmask = g_strdup(value);
                if (!strcmp(key, "ifconfig_remote"))
                        peer = g_strdup(value);
  
                g_free(address);
                g_free(gateway);
                g_free(peer);
+               g_free(netmask);
  
                return VPN_STATE_FAILURE;
        }
  
-       connman_ipaddress_set_ipv4(ipaddress, address, NULL, gateway);
+       connman_ipaddress_set_ipv4(ipaddress, address, netmask, gateway);
        connman_ipaddress_set_peer(ipaddress, peer);
        vpn_provider_set_ipaddress(provider, ipaddress);
  
        g_free(address);
        g_free(gateway);
        g_free(peer);
+       g_free(netmask);
        connman_ipaddress_free(ipaddress);
  
        return VPN_STATE_CONNECT;
@@@ -306,13 -314,54 +314,54 @@@ static int task_append_config_data(stru
        return 0;
  }
  
+ static gboolean can_read_data(GIOChannel *chan,
+                                 GIOCondition cond, gpointer data)
+ {
+       void (*cbf)(const char *format, ...) = data;
+       gchar *str;
+       gsize size;
+       if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+               return FALSE;
+       g_io_channel_read_line(chan, &str, &size, NULL, NULL);
+       cbf(str);
+       g_free(str);
+       return TRUE;
+ }
+ static int setup_log_read(int stdout_fd, int stderr_fd)
+ {
+       GIOChannel *chan;
+       int watch;
+       chan = g_io_channel_unix_new(stdout_fd);
+       g_io_channel_set_close_on_unref(chan, TRUE);
+       watch = g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+                              can_read_data, connman_debug);
+       g_io_channel_unref(chan);
+       if (watch == 0)
+               return -EIO;
+       chan = g_io_channel_unix_new(stderr_fd);
+       g_io_channel_set_close_on_unref(chan, TRUE);
+       watch = g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+                              can_read_data, connman_error);
+       g_io_channel_unref(chan);
+       return watch == 0? -EIO : 0;
+ }
  static int ov_connect(struct vpn_provider *provider,
                        struct connman_task *task, const char *if_name,
                        vpn_provider_connect_cb_t cb, const char *dbus_sender,
                        void *user_data)
  {
        const char *option;
-       int err = 0, fd;
+       int stdout_fd, stderr_fd;
+       int err = 0;
  
        option = vpn_provider_get_string(provider, "Host");
        if (!option) {
                connman_task_add_argument(task, "--client", NULL);
        }
  
-       connman_task_add_argument(task, "--syslog", NULL);
        connman_task_add_argument(task, "--script-security", "2");
  
        connman_task_add_argument(task, "--up",
                                        connman_task_get_path(task));
  
        connman_task_add_argument(task, "--dev", if_name);
-       connman_task_add_argument(task, "--dev-type", "tun");
+       option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
+       if (option) {
+               connman_task_add_argument(task, "--dev-type", option);
+       } else {
+               /*
+                * Default to tun for backwards compatibility.
+                */
+               connman_task_add_argument(task, "--dev-type", "tun");
+       }
  
        connman_task_add_argument(task, "--persist-tun", NULL);
  
 +#if !defined TIZEN_EXT
        connman_task_add_argument(task, "--route-noexec", NULL);
        connman_task_add_argument(task, "--ifconfig-noexec", NULL);
 +#endif
  
        /*
         * Disable client restarts because we can't handle this at the
         */
        connman_task_add_argument(task, "--ping-restart", "0");
  
-       fd = fileno(stderr);
        err = connman_task_run(task, vpn_died, provider,
-                       NULL, &fd, &fd);
+                       NULL, &stdout_fd, &stderr_fd);
        if (err < 0) {
                connman_error("openvpn failed to start");
                err = -EIO;
                goto done;
        }
  
+       err = setup_log_read(stdout_fd, stderr_fd);
  done:
        if (cb)
                cb(provider, user_data, err);
        return err;
  }
  
+ static int ov_device_flags(struct vpn_provider *provider)
+ {
+       const char *option;
+       option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
+       if (!option) {
+               return IFF_TUN;
+       }
+       if (g_str_equal(option, "tap")) {
+               return IFF_TAP;
+       }
+       if (!g_str_equal(option, "tun")) {
+               connman_warn("bad OpenVPN.DeviceType value, falling back to tun");
+       }
+       return IFF_TUN;
+ }
  static struct vpn_driver vpn_driver = {
        .notify = ov_notify,
        .connect        = ov_connect,
        .save           = ov_save,
+       .device_flags = ov_device_flags,
  };
  
  static int openvpn_init(void)
diff --combined vpn/plugins/pptp.c
index 9f2a214,27b1d50..27b1d50
mode 100755,100644..100755
@@@ -77,7 -77,7 +77,7 @@@ struct 
        { "PPPD.RequirMPPE40", "require-mppe-40", NULL, OPT_BOOL },
        { "PPPD.RequirMPPE128", "require-mppe-128", NULL, OPT_BOOL },
        { "PPPD.RequirMPPEStateful", "mppe-stateful", NULL, OPT_BOOL },
-       { "PPPD.NoVJ", "no-vj-comp", NULL, OPT_BOOL },
+       { "PPPD.NoVJ", "novj", NULL, OPT_BOOL },
  };
  
  static DBusConnection *connection;
@@@ -289,8 -289,9 +289,9 @@@ static void request_input_reply(DBusMes
  
        DBG("provider %p", pptp_reply->provider);
  
-       if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               error = dbus_message_get_error_name(reply);
+       if (!reply || dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
+               if (reply)
+                       error = dbus_message_get_error_name(reply);
                goto done;
        }
  
diff --combined vpn/plugins/vpn.c
index e65daca,9a42385..f6e24c4
mode 100755,100644..100755
@@@ -56,6 -56,7 +56,7 @@@ struct vpn_data 
        unsigned int watch;
        enum vpn_state state;
        struct connman_task *task;
+       int tun_flags;
  };
  
  struct vpn_driver_data {
@@@ -89,7 -90,7 +90,7 @@@ static int stop_vpn(struct vpn_provide
                return 0;
  
        memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+       ifr.ifr_flags = data->tun_flags | IFF_NO_PI;
        sprintf(ifr.ifr_name, "%s", data->if_name);
  
        fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
@@@ -195,6 -196,34 +196,34 @@@ int vpn_set_ifname(struct vpn_provider 
        return 0;
  }
  
+ static int vpn_set_state(struct vpn_provider *provider,
+                                               enum vpn_provider_state state)
+ {
+       struct vpn_data *data = vpn_provider_get_data(provider);
+       if (!data)
+               return -EINVAL;
+       switch (state) {
+       case VPN_PROVIDER_STATE_UNKNOWN:
+               return -EINVAL;
+       case VPN_PROVIDER_STATE_IDLE:
+               data->state = VPN_STATE_IDLE;
+               break;
+       case VPN_PROVIDER_STATE_CONNECT:
+       case VPN_PROVIDER_STATE_READY:
+               data->state = VPN_STATE_CONNECT;
+               break;
+       case VPN_PROVIDER_STATE_DISCONNECT:
+               data->state = VPN_STATE_DISCONNECT;
+               break;
+       case VPN_PROVIDER_STATE_FAILURE:
+               data->state = VPN_STATE_FAILURE;
+               break;
+       }
+       return 0;
+ }
  static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
  {
        struct vpn_provider *provider = user_data;
@@@ -307,57 -336,7 +336,57 @@@ static DBusMessage *vpn_notify(struct c
        return NULL;
  }
  
- static int vpn_create_tun(struct vpn_provider *provider)
 +#if defined TIZEN_EXT
 +static void vpn_event(struct vpn_provider *provider, int state)
 +{
 +      struct vpn_driver_data *vpn_driver_data;
 +      const char *name;
 +
 +      name = vpn_provider_get_driver_name(provider);
 +      if (!name) {
 +              DBG("Cannot find VPN driver for provider %p", provider);
 +              vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
 +              return;
 +      }
 +
 +      vpn_driver_data = g_hash_table_lookup(driver_hash, name);
 +      if (!vpn_driver_data) {
 +              DBG("Cannot find VPN driver data for name %s", name);
 +              vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
 +              return;
 +      }
 +
 +      DBG("provider %p driver %s state %d", provider, name, state);
 +
 +      switch (state) {
 +      case VPN_STATE_CONNECT:
 +              vpn_provider_set_state(provider,
 +                              VPN_PROVIDER_STATE_CONNECT);
 +              break;
 +      case VPN_STATE_READY:
 +              vpn_provider_set_state(provider,
 +                              VPN_PROVIDER_STATE_READY);
 +              break;
 +
 +      case VPN_STATE_UNKNOWN:
 +      case VPN_STATE_IDLE:
 +      case VPN_STATE_DISCONNECT:
 +      case VPN_STATE_FAILURE:
 +              vpn_provider_set_state(provider,
 +                                      VPN_PROVIDER_STATE_DISCONNECT);
 +              break;
 +
 +      case VPN_STATE_AUTH_FAILURE:
 +              vpn_provider_indicate_error(provider,
 +                                      VPN_PROVIDER_ERROR_AUTH_FAILED);
 +              break;
 +      }
 +
 +      return;
 +}
 +#endif
 +
+ static int vpn_create_tun(struct vpn_provider *provider, int flags)
  {
        struct vpn_data *data = vpn_provider_get_data(provider);
        struct ifreq ifr;
        }
  
        memset(&ifr, 0, sizeof(ifr));
-       ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+       ifr.ifr_flags = flags | IFF_NO_PI;
  
        for (i = 0; i < 256; i++) {
                sprintf(ifr.ifr_name, "vpn%d", i);
                goto exist_err;
        }
  
+       data->tun_flags = flags;
        data->if_name = (char *)g_strdup(ifr.ifr_name);
        if (!data->if_name) {
                connman_error("Failed to allocate memory");
@@@ -434,7 -414,7 +464,7 @@@ static int vpn_connect(struct vpn_provi
        struct vpn_data *data = vpn_provider_get_data(provider);
        struct vpn_driver_data *vpn_driver_data;
        const char *name;
-       int ret = 0;
+       int ret = 0, tun_flags = IFF_TUN;
        enum vpn_state state = VPN_STATE_UNKNOWN;
  
        if (data)
        }
  
        if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
-               ret = vpn_create_tun(provider);
+               if (vpn_driver_data->vpn_driver->device_flags) {
+                       tun_flags = vpn_driver_data->vpn_driver->device_flags(provider);
+               }
+               ret = vpn_create_tun(provider, tun_flags);
                if (ret < 0)
                        goto exist_err;
        }
                goto exist_err;
        }
  
 +
 +#if defined TIZEN_EXT
 +      if(vpn_driver_data->vpn_driver->set_event_cb)
 +              vpn_driver_data->vpn_driver->set_event_cb(vpn_event, provider);
 +#endif
 +
        ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
                                                data->if_name, cb, dbus_sender,
                                                user_data);
@@@ -628,6 -605,7 +661,7 @@@ int vpn_register(const char *name, stru
        data->provider_driver.probe = vpn_probe;
        data->provider_driver.remove = vpn_remove;
        data->provider_driver.save = vpn_save;
+       data->provider_driver.set_state = vpn_set_state;
  
        if (!driver_hash)
                driver_hash = g_hash_table_new_full(g_str_hash,
diff --combined vpn/plugins/vpn.h
index af7e8f8,cb94bdc..1888d5f
mode 100755,100644..100755
@@@ -40,16 -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,
@@@ -57,6 -50,7 +57,7 @@@
        void (*disconnect) (struct vpn_provider *provider);
        int (*error_code) (struct vpn_provider *provider, int exit_code);
        int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
+       int (*device_flags) (struct vpn_provider *provider);
  };
  
  int vpn_register(const char *name, struct vpn_driver *driver,
diff --combined vpn/plugins/vpnc.c
index 09674bd,af9dbe7..af9dbe7
mode 100755,100644..100755
@@@ -29,6 -29,7 +29,7 @@@
  #include <unistd.h>
  #include <stdio.h>
  #include <net/if.h>
+ #include <linux/if_tun.h>
  
  #include <glib.h>
  
@@@ -72,7 -73,7 +73,7 @@@ struct 
        { "VPNC.LocalPort", "Local Port", "0", OPT_STRING, true, },
        { "VPNC.CiscoPort", "Cisco UDP Encapsulation Port", "0", OPT_STRING,
                                                                        true },
-       { "VPNC.AppVersion", "Application Version", NULL, OPT_STRING, true },
+       { "VPNC.AppVersion", "Application version", NULL, OPT_STRING, true },
        { "VPNC.NATTMode", "NAT Traversal Mode", "cisco-udp", OPT_STRING,
                                                                        true },
        { "VPNC.DPDTimeout", "DPD idle timeout (our side)", NULL, OPT_STRING,
@@@ -287,7 -288,15 +288,15 @@@ static int vc_connect(struct vpn_provid
        connman_task_add_argument(task, "--no-detach", NULL);
  
        connman_task_add_argument(task, "--ifname", if_name);
-       connman_task_add_argument(task, "--ifmode", "tun");
+       option = vpn_provider_get_string(provider, "VPNC.DeviceType");
+       if (option) {
+               connman_task_add_argument(task, "--ifmode", option);
+       } else {
+               /*
+                * Default to tun for backwards compatibility.
+                */
+               connman_task_add_argument(task, "--ifmode", "tun");
+       }
  
        connman_task_add_argument(task, "--script",
                                SCRIPTDIR "/openconnect-script");
@@@ -329,11 -338,32 +338,32 @@@ static int vc_error_code(struct vpn_pro
        }
  }
  
+ static int vc_device_flags(struct vpn_provider *provider)
+ {
+       const char *option;
+       option = vpn_provider_get_string(provider, "VPNC.DeviceType");
+       if (!option) {
+               return IFF_TUN;
+       }
+       if (g_str_equal(option, "tap")) {
+               return IFF_TAP;
+       }
+       if (!g_str_equal(option, "tun")) {
+               connman_warn("bad VPNC.DeviceType value, falling back to tun");
+       }
+       return IFF_TUN;
+ }
  static struct vpn_driver vpn_driver = {
        .notify         = vc_notify,
        .connect        = vc_connect,
        .error_code     = vc_error_code,
        .save           = vc_save,
+       .device_flags   = vc_device_flags,
  };
  
  static int vpnc_init(void)
diff --combined vpn/vpn-config.c
index a5be332,c88a99a..5f0e749
mode 100755,100644..100755
@@@ -203,11 -203,7 +203,11 @@@ static int load_provider(GKeyFile *keyf
                                struct vpn_config *config, enum what action)
  {
        struct vpn_config_provider *config_provider;
 +#if !defined TIZEN_EXT
        const char *ident, *host, *domain;
 +#else
 +      const char *ident, *host, *domain, *name;
 +#endif
        int err;
  
        /* Strip off "provider_" prefix */
  
        host = get_string(config_provider, "Host");
        domain = get_string(config_provider, "Domain");
 +#if !defined TIZEN_EXT
        if (host && domain) {
                char *id = __vpn_provider_create_identifier(host, domain);
 +#else
 +      name = get_string(config_provider, "Name");
 +      if (host && domain && name) {
 +              char *id = __vpn_provider_create_identifier(host, domain, name);
 +#endif
  
                struct vpn_provider *provider;
                provider = __vpn_provider_lookup(id);
  
                DBG("provider identifier %s", id);
        } else {
 +#if !defined TIZEN_EXT
                DBG("invalid values host %s domain %s", host, domain);
 +#else
 +              DBG("invalid values host %s domain %s name %s", host, domain, name);
 +#endif
                err = -EINVAL;
                goto err;
        }
@@@ -498,12 -484,12 +498,12 @@@ static void config_notify_handler(struc
        if (event->mask & IN_CREATE)
                return;
  
-       if (event->mask & IN_DELETE) {
+       if (event->mask & (IN_DELETE | IN_MOVED_FROM)) {
                g_hash_table_remove(config_table, ident);
                return;
        }
  
-       if (event->mask & IN_MODIFY) {
+       if (event->mask & (IN_MODIFY | IN_MOVED_TO)) {
                struct vpn_config *config;
                char *path = get_dir();
  
diff --combined vpn/vpn-provider.c
index 925f699,d2b3e3a..67239e4
mode 100755,100644..100755
@@@ -501,6 -501,12 +501,12 @@@ static DBusMessage *do_connect(DBusConn
        return NULL;
  }
  
+ static DBusMessage *do_connect2(DBusConnection *conn, DBusMessage *msg,
+                                                               void *data)
+ {
+       return do_connect(conn, msg, data);
+ }
  static DBusMessage *do_disconnect(DBusConnection *conn, DBusMessage *msg,
                                                                void *data)
  {
@@@ -527,6 -533,9 +533,9 @@@ static const GDBusMethodTable connectio
                        GDBUS_ARGS({ "name", "s" }), NULL,
                        clear_property) },
        { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, do_connect) },
+       { GDBUS_ASYNC_METHOD("Connect2",
+                       GDBUS_ARGS({ "dbus_sender", "s" }),
+                       NULL, do_connect2) },
        { GDBUS_METHOD("Disconnect", NULL, NULL, do_disconnect) },
        { },
  };
@@@ -549,6 -558,12 +558,12 @@@ static void resolv_result(GResolvResult
                provider->host_ip = g_strdupv(results);
  
        vpn_provider_unref(provider);
+       /* Remove the resolver here so that it will not be left
+        * hanging around and cause double free in unregister_provider()
+        */
+       g_resolv_unref(provider->resolv);
+       provider->resolv = NULL;
  }
  
  static void provider_resolv_host_addr(struct vpn_provider *provider)
@@@ -680,14 -695,11 +695,11 @@@ static struct vpn_route *get_route(cha
                        in_addr_t addr;
                        struct in_addr netmask_in;
                        unsigned char prefix_len = 32;
+                       char *ptr;
+                       long int value = strtol(netmask, &ptr, 10);
  
-                       if (netmask) {
-                               char *ptr;
-                               long int value = strtol(netmask, &ptr, 10);
-                               if (ptr != netmask && *ptr == '\0' &&
-                                                               value <= 32)
-                                       prefix_len = value;
-                       }
+                       if (ptr != netmask && *ptr == '\0' && value <= 32)
+                               prefix_len = value;
  
                        addr = 0xffffffff << (32 - prefix_len);
                        netmask_in.s_addr = htonl(addr);
@@@ -796,16 -808,20 +808,20 @@@ static gchar **create_network_list(GSLi
  {
        GSList *list;
        gchar **result = NULL;
+       gchar **prev_result;
        unsigned int num_elems = 0;
  
        for (list = networks; list; list = g_slist_next(list)) {
                struct vpn_route *route = list->data;
                int family;
  
+               prev_result = result;
                result = g_try_realloc(result,
                                (num_elems + 1) * sizeof(gchar *));
-               if (!result)
+               if (!result) {
+                       g_free(prev_result);
                        return NULL;
+               }
  
                switch (route->family) {
                case AF_INET:
                num_elems++;
        }
  
+       prev_result = result;
        result = g_try_realloc(result, (num_elems + 1) * sizeof(gchar *));
-       if (!result)
+       if (!result) {
+               g_free(prev_result);
                return NULL;
+       }
  
        result[num_elems] = NULL;
        *count = num_elems;
@@@ -1081,10 -1100,22 +1100,22 @@@ int __vpn_provider_connect(struct vpn_p
        DBG("provider %p", provider);
  
        if (provider->driver && provider->driver->connect) {
+               const char *dbus_sender = dbus_message_get_sender(msg);
                dbus_message_ref(msg);
+               if (dbus_message_has_signature(msg,
+                                               DBUS_TYPE_STRING_AS_STRING)) {
+                       const char *sender = NULL;
+                       dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING,
+                                       &sender, DBUS_TYPE_INVALID);
+                       if (sender && sender[0])
+                               dbus_sender = sender;
+               }
                err = provider->driver->connect(provider, connect_cb,
-                                               dbus_message_get_sender(msg),
-                                               msg);
+                                               dbus_sender, msg);
        } else
                return -EOPNOTSUPP;
  
@@@ -1560,6 -1591,9 +1591,9 @@@ int vpn_provider_indicate_error(struct 
                break;
        }
  
+       if (provider->driver && provider->driver->set_state)
+               provider->driver->set_state(provider, provider->state);
        return 0;
  }
  
@@@ -1605,6 -1639,18 +1639,18 @@@ static void unregister_provider(gpointe
  
        connection_unregister(provider);
  
+       /* If the provider has any DNS resolver queries pending,
+        * they need to be cleared here because the unref will not
+        * be able to do that (because the provider_resolv_host_addr()
+        * has increased the ref count by 1). This is quite rare as
+        * normally the resolving either returns a value or has a
+        * timeout which clears the memory. Typically resolv_result() will
+        * unref the provider but in this case that call has not yet
+        * happened.
+        */
+       if (provider->resolv)
+               vpn_provider_unref(provider);
        vpn_provider_unref(provider);
  }
  
@@@ -1757,7 -1803,6 +1803,7 @@@ static void provider_create_all_from_ty
        g_strfreev(providers);
  }
  
 +#if !defined TIZEN_EXT
  char *__vpn_provider_create_identifier(const char *host, const char *domain)
  {
        char *ident;
  
        return ident;
  }
 +#else
 +char *__vpn_provider_create_identifier(const char *host, const char *domain, const char *name)
 +{
 +      char *ident;
 +
 +      ident = g_strdup_printf("%s_%s_%s", host, domain, name);
 +      if (!ident)
 +              return NULL;
 +
 +      provider_dbus_ident(ident);
 +
 +      return ident;
 +}
 +#endif
  
  int __vpn_provider_create(DBusMessage *msg)
  {
        if (!type || !name)
                return -EOPNOTSUPP;
  
 +#if !defined TIZEN_EXT
        ident = __vpn_provider_create_identifier(host, domain);
 +#else
 +      ident = __vpn_provider_create_identifier(host, domain, name);
 +#endif
        DBG("ident %s", ident);
  
        provider = __vpn_provider_lookup(ident);
@@@ -2030,11 -2057,7 +2076,11 @@@ int __vpn_provider_create_from_config(G
                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 --combined vpn/vpn-provider.h
index 8105d7f,bdc5f5c..bdc5f5c
mode 100755,100644..100755
@@@ -132,6 -132,8 +132,8 @@@ struct vpn_provider_driver 
                        void *user_data);
        int (*disconnect) (struct vpn_provider *provider);
        int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
+       int (*set_state)(struct vpn_provider *provider,
+                                               enum vpn_provider_state state);
  };
  
  int vpn_provider_driver_register(struct vpn_provider_driver *driver);