[wifi-direct-manager]Merge Tizen 2.4 for sync 82/41982/2 submit/tizen/20150619.121623
authorYu Jiung <jiung.yu@samsung.com>
Fri, 19 Jun 2015 11:51:37 +0000 (20:51 +0900)
committerYu Jiung <jiung.yu@samsung.com>
Fri, 19 Jun 2015 11:57:33 +0000 (20:57 +0900)
Change-Id: I15c95401cb76cf8c521facc272e64564783956b8
Signed-off-by: Yu jiung <jiung.yu@samsung.com>
49 files changed:
AUTHORS
CMakeLists.txt
files/ccode.conf [new file with mode: 0644]
files/dhcpd-notify.sh [changed mode: 0755->0644]
files/dhcpd.p2p.conf
files/p2p_supp.conf
files/p2p_supp.sh [changed mode: 0755->0644]
files/p2p_supp_tv.conf [new file with mode: 0644]
files/persistent-peer [moved from files/access_list with 100% similarity]
files/udhcp_script.non-autoip
files/wifi-direct-dhcp.sh [changed mode: 0755->0644]
files/wifi-direct-server.sh [changed mode: 0755->0644]
include/wifi-direct-client.h
include/wifi-direct-group.h
include/wifi-direct-ipc.h [new file with mode: 0644]
include/wifi-direct-manager.h
include/wifi-direct-peer.h
include/wifi-direct-service.h [new file with mode: 0644]
include/wifi-direct-session.h
include/wifi-direct-util.h [changed mode: 0644->0755]
oem/wifi-direct-oem.c
oem/wifi-direct-oem.h
packaging/wifi-direct-manager.changes [deleted file]
packaging/wifi-direct-manager.spec [changed mode: 0644->0755]
packaging/wifi-direct-manager.spec~ [new file with mode: 0755]
plugin/wpasupplicant/CMakeLists.txt [deleted file]
plugin/wpasupplicant/ctrl_iface_dbus/CMakeLists.txt [new file with mode: 0755]
plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.c [new file with mode: 0755]
plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.h [new file with mode: 0644]
plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-log.h [new file with mode: 0644]
plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-wpasupplicant.h [new file with mode: 0755]
plugin/wpasupplicant/ctrl_iface_dbus/wfd-plugin-wpasupplicant.c [new file with mode: 0755]
plugin/wpasupplicant/ctrl_iface_sock/CMakeLists.txt [new file with mode: 0755]
plugin/wpasupplicant/ctrl_iface_sock/include/wfd-plugin-wpasupplicant.h [moved from plugin/wpasupplicant/wfd-plugin-wpasupplicant.h with 77% similarity, mode: 0755]
plugin/wpasupplicant/ctrl_iface_sock/wfd-plugin-wpasupplicant.c [moved from plugin/wpasupplicant/wfd-plugin-wpasupplicant.c with 61% similarity]
plugin/wpasupplicant/emul/CMakeLists.txt [new file with mode: 0755]
plugin/wpasupplicant/emul/include/wfd-plugin-wpasupplicant.h [new file with mode: 0755]
plugin/wpasupplicant/emul/wfd-plugin-wpasupplicant-emul.c [moved from plugin/wpasupplicant/wfd-plugin-wpasupplicant-emul.c with 74% similarity]
src/wifi-direct-client.c [changed mode: 0644->0755]
src/wifi-direct-event.c
src/wifi-direct-group.c
src/wifi-direct-manager.c
src/wifi-direct-peer.c
src/wifi-direct-service.c [new file with mode: 0644]
src/wifi-direct-session.c
src/wifi-direct-state.c
src/wifi-direct-util.c [changed mode: 0644->0755]
wifi-direct-manager.manifest
wifi-direct-plugin-wpasupplicant.manifest

diff --git a/AUTHORS b/AUTHORS
index 1b2f445..b4ce413 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,2 @@
-Gibyoung Kim <lastkgb.kim@samsung.com>
\ No newline at end of file
+Gibyoung Kim <lastkgb.kim@samsung.com>
+Maneesh Jain <maneesh.jain@samsung.com>
index b55e8ec..0625b9b 100755 (executable)
@@ -8,7 +8,7 @@ SET(LIBDIR "\${prefix}/lib")
 SET(INCLUDEDIR "\${prefix}/include")
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED wifi-direct glib-2.0 gobject-2.0 dlog capi-appfw-application vconf)
+pkg_check_modules(pkgs REQUIRED capi-network-wifi-direct glib-2.0 gio-2.0 gobject-2.0 dlog capi-appfw-application vconf ${MDM_REQUIRED_PKGS})
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
@@ -17,13 +17,36 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
                                        ${CMAKE_SOURCE_DIR}/oem
                                        )
 
-SET(CMAKE_C_FLAGS "${CMAKE_CFLAGS} ${EXTRA_CFLAGS} -g")
-SET(CMAKE_C_FLAGS_DEBUG "O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "O2")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Werror -fPIE")
+SET(CMAKE_C_FLAGS_DEBUG "O0 -g -fPIE")
+SET(CMAKE_C_FLAGS_RELEASE "O2 -fPIE")
+
+SET(ARCH "${ARCHITECTURE}")
 
 ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
 ADD_DEFINITIONS("-DUSE_DLOG")
 
+IF(TIZEN_TETHERING_ENABLE)
+       ADD_DEFINITIONS(-DTIZEN_TETHERING_ENABLE)
+ENDIF(TIZEN_TETHERING_ENABLE)
+
+IF(TIZEN_FEATURE_SERVICE_DISCOVERY)
+       ADD_DEFINITIONS(-DTIZEN_FEATURE_SERVICE_DISCOVERY)
+ENDIF(TIZEN_FEATURE_SERVICE_DISCOVERY)
+IF(TIZEN_FEATURE_WIFI_DISPLAY)
+       ADD_DEFINITIONS(-DTIZEN_FEATURE_WIFI_DISPLAY)
+ENDIF(TIZEN_FEATURE_WIFI_DISPLAY)
+IF(TIZEN_WLAN_CONCURRENT_ENABLE)
+       ADD_DEFINITIONS(-DTIZEN_WLAN_CONCURRENT_ENABLE)
+ENDIF(TIZEN_WLAN_CONCURRENT_ENABLE)
+
+IF(TIZEN_TV)
+       ADD_DEFINITIONS(-DTIZEN_TV)
+ENDIF(TIZEN_TV)
+IF(CTRL_IFACE_DBUS)
+       ADD_DEFINITIONS(-DCTRL_IFACE_DBUS)
+ENDIF(CTRL_IFACE_DBUS)
+
 SET(SRCS
        ${CMAKE_SOURCE_DIR}/src/wifi-direct-manager.c
        ${CMAKE_SOURCE_DIR}/src/wifi-direct-state.c
@@ -36,7 +59,12 @@ SET(SRCS
        ${CMAKE_SOURCE_DIR}/oem/wifi-direct-oem.c
        )
 
+IF(TIZEN_FEATURE_SERVICE_DISCOVERY)
+       SET(SRCS ${SRCS} ${CMAKE_SOURCE_DIR}/src/wifi-direct-service.c)
+ENDIF(TIZEN_FEATURE_SERVICE_DISCOVERY)
+
 ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl)
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
@@ -46,7 +74,24 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/dhcpd-notify.sh DESTINATION bin)
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/wifi-direct-server.sh DESTINATION bin)
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/wifi-direct-dhcp.sh DESTINATION bin)
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/p2p_supp.sh DESTINATION sbin)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/p2p_supp.conf DESTINATION etc/wifi-direct)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/access_list DESTINATION etc/wifi-direct)
+#INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/p2p_supplicant DESTINATION sbin)
+IF(TIZEN_TV)
+       INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/p2p_supp_tv.conf DESTINATION etc/wifi-direct)
+       INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/p2p_supp_tv.conf DESTINATION /opt/etc)
+ELSE(TIZEN_TV)
+       INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/p2p_supp.conf DESTINATION etc/wifi-direct)
+       INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/p2p_supp.conf DESTINATION /opt/etc)
+ENDIF(TIZEN_TV)
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/ccode.conf DESTINATION etc/wifi-direct)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/files/persistent-peer DESTINATION /opt/etc)
 
-ADD_SUBDIRECTORY(plugin/wpasupplicant)
+IF("${ARCH}" MATCHES "^arm.*|.*86.*")
+IF(CTRL_IFACE_DBUS)
+       ADD_SUBDIRECTORY(plugin/wpasupplicant/ctrl_iface_dbus)
+ELSE(CTRL_IFACE_DBUS)
+       ADD_SUBDIRECTORY(plugin/wpasupplicant/ctrl_iface_sock)
+ENDIF(CTRL_IFACE_DBUS)
+ELSE()
+       ADD_SUBDIRECTORY(plugin/wpasupplicant/emul)
+ENDIF()
diff --git a/files/ccode.conf b/files/ccode.conf
new file mode 100644 (file)
index 0000000..e958ad9
--- /dev/null
@@ -0,0 +1,237 @@
+#This group is for mcc to country code mapping.
+[ccode_map]
+
+202=gr
+204=nl
+206=be
+208=fr
+212=mc
+213=ad
+214=es
+216=hu
+218=ba
+219=hr
+220=rs
+222=it
+225=va
+226=ro
+228=ch
+230=cz
+231=sk
+232=at
+234=gb
+235=gb
+238=dk
+240=se
+242=no
+244=fi
+246=lt
+247=lv
+248=ee
+250=ru
+255=ua
+257=by
+259=md
+260=pl
+262=de
+266=gi
+268=pt
+270=lu
+272=ie
+274=is
+276=al
+278=mt
+280=cy
+282=ge
+283=am
+284=bg
+286=tr
+288=fo
+289=ge
+290=gl
+292=sm
+293=si
+294=mk
+295=li
+297=me
+302=ca
+308=pm
+310=us
+311=us
+312=us
+313=us
+314=us
+315=us
+316=us
+330=pr
+332=vi
+334=mx
+338=jm
+340=gp
+342=bb
+344=ag
+346=ky
+348=vg
+350=bm
+352=gd
+354=ms
+356=kn
+358=lc
+360=vc
+362=ai
+363=aw
+364=bs
+365=ai
+366=dm
+368=cu
+370=do
+372=ht
+374=tt
+376=tc
+400=az
+401=kz
+402=bt
+404=in
+405=in
+410=pk
+412=af
+413=lk
+414=mm
+415=lb
+416=jo
+417=sy
+418=iq
+419=kw
+420=sa
+421=ye
+422=om
+423=ps
+424=ae
+425=il
+426=bh
+427=qa
+428=mn
+429=np
+430=ae
+431=ae
+432=ir
+434=uz
+436=tj
+437=kg
+438=tm
+440=jp
+441=jp
+450=kr
+452=vn
+454=hk
+455=mo
+456=kh
+457=la
+460=cn
+461=cn
+466=tw
+467=kp
+470=bd
+472=mv
+502=my
+505=au
+510=id
+514=tl
+515=ph
+520=th
+525=sg
+528=bn
+530=nz
+534=mp
+535=gu
+536=nr
+537=pg
+539=to
+540=sb
+541=vu
+542=fj
+543=wf
+544=as
+545=ki
+546=nc
+547=pf
+548=ck
+549=ws
+550=fm
+551=mh
+552=pw
+602=eg
+603=dz
+604=ma
+605=tn
+606=ly
+607=gm
+608=sn
+609=mr
+610=ml
+611=gn
+612=ci
+613=bf
+614=ne
+615=tg
+616=bj
+617=mu
+618=lr
+619=sl
+620=gh
+621=ng
+622=td
+623=cf
+624=cm
+625=cv
+626=st
+627=gq
+628=ga
+629=cg
+630=cg
+631=ao
+632=gw
+633=sc
+634=sd
+635=rw
+636=et
+637=so
+638=dj
+639=ke
+640=tz
+641=ug
+642=bi
+643=mz
+645=zm
+646=mg
+647=re
+648=zw
+649=na
+650=mw
+651=ls
+652=bw
+653=sz
+654=km
+655=za
+657=er
+702=bz
+704=gt
+706=sv
+708=hn
+710=ni
+712=cr
+714=pa
+716=pe
+722=ar
+724=br
+730=cl
+732=co
+734=ve
+736=bo
+738=gy
+740=ec
+742=gf
+744=py
+746=sr
+748=uy
+750=fk
old mode 100755 (executable)
new mode 100644 (file)
index 9c2abfe..734fd20
@@ -1,7 +1,7 @@
 #!/bin/sh
 # Dump DHCP lease data: MAC IP Time
-dumpleases | awk '$1!="Mac" {print $1, $2, $3}' > /tmp/dhcp-client-table
+/usr/bin/dumpleases | /bin/awk '$1!="Mac" {print $1, $2, $3}' > /tmp/dhcp-client-table
 
 #Update vconf value to notify wifi-direct
-vconftool set -t int memory/private/wifi_direct_manager/dhcp_ip_lease 1 -f
+/usr/bin/vconftool set -t int memory/private/wifi_direct_manager/dhcp_ip_lease 1 -f
 #cat /tmp/dhcp-client-table
index fd3c04e..41545ac 100644 (file)
@@ -1,6 +1,7 @@
 start          192.168.49.20           #default: 192.168.0.20
 end            192.168.49.40           #default: 192.168.0.254
-interface      p2p-wlan0-0             #default: wlan0
+#interface     p2p-wlan0-0             #default: wlan0
+interface      wlan0           #default: wlan0
 max_leases     20                      #default: 254
 notify_file     /usr/bin/dhcpd-notify.sh
 
@@ -8,3 +9,4 @@ notify_file     /usr/bin/dhcpd-notify.sh
 option subnet  255.255.255.0
 option router  192.168.49.1
 option lease   864000                  # 10 days of seconds
+option broadcast       192.168.49.255
index 1456e09..bb4e500 100644 (file)
@@ -1,6 +1,5 @@
 ##### p2p_supplicant configuration file template #####
 update_config=1
-ctrl_interface=/var/run/wpa_supplicant
 eapol_version=1
 ap_scan=1
 p2p_listen_reg_class=81
@@ -10,4 +9,5 @@ p2p_oper_channel=48
 device_name=Tizen
 device_type=10-0050F204-5
 config_methods=push_button
-driver_param=use_p2p_group_interface=1
\ No newline at end of file
+persistent_reconnect=1
+p2p_no_group_iface=1
\ No newline at end of file
old mode 100755 (executable)
new mode 100644 (file)
index 8bba209..d185d28
@@ -2,42 +2,73 @@
 
 start()
 {
-       HARDWARE_MODEL=`grep Hardware /proc/cpuinfo | awk "{print \\$3}"`
+       HARDWARE_MODEL=`/bin/grep Hardware /proc/cpuinfo | /bin/awk "{print \\$3}"`
        /bin/echo "Hardware Model=${HARDWARE_MODEL}"
 
-       case $HARDWARE_MODEL in
-               "SLP_PQ")       /bin/echo "This is PQ"
-                       /usr/sbin/wpa_supplicant -t -B -ddd -g/var/run/wpa_global -f/var/log/p2p_supplicant.log
-               ;;
-               "U1SLP" | "U1HD")       /bin/echo "This is U1SLP"
-                       /usr/sbin/wpa_supplicant -t -B -ddd -Dwext -f/var/log/p2p_supplicant.log
-               ;;
-               "SLP7_C210")    /bin/echo "This is C210"
-                       /usr/sbin/wpa_supplicant -t -B -ddd -Dwext -f/var/log/p2p_supplicant.log
-               ;;
-               "SLP10_C210")
-                       /usr/sbin/wpa_supplicant -t -B -ddd -Dwext -f/var/log/p2p_supplicant.log
-               ;;
-               *)
-                       /usr/sbin/wpa_supplicant -t -B -ddd -g/var/run/wpa_global -f/var/log/p2p_supplicant.log
-               ;;
-       esac
+       if [ -e /opt/etc/p2p_supp.conf ]; then
+               echo "File exist: /opt/etc/p2p_supp.conf"
+       else
+               echo "File not exist. Reinstall: /opt/etc/p2p_supp.conf"
+                /bin/cp /usr/etc/wifi-direct/p2p_supp.conf /opt/etc/
+       fi
+       ## For Hawk-P Platform, Hardware model is Samsung
+       if [ $HARDWARE_MODEL = "Samsung" ];then
+               /usr/sbin/wpa_supplicant -t -B -ddd -Dnl80211 -ip2p0 -c/opt/etc/p2p_supp_tv.conf -g/var/run/wpa_global  -f/opt/usr/data/network/p2p_supplicant.log
+        else
+               /usr/sbin/p2p_supplicant -t -B -C/var/run/wpa_supplicant -ddd -Dnl80211 -iwlan0 -c/opt/etc/p2p_supp.conf -f/opt/usr/data/network/p2p_supplicant.log
+       fi
+ }
+
+start_p2p0()
+{
+       if [ -e /opt/etc/p2p_supp.conf ]; then
+               echo "File exist: /opt/etc/p2p_supp.conf"
+       else
+               echo "File not exist. Reinstall: /opt/etc/p2p_supp.conf"
+                /bin/cp /usr/etc/wifi-direct/p2p_supp.conf /opt/etc/
+       fi
+       /usr/sbin/p2p_supplicant -t -B -ddd -Dnl80211 -ip2p0 -c/opt/etc/p2p_supp.conf -f/opt/usr/data/network/p2p_supplicant.log
+}
+
+start_dbus()
+{
+       HARDWARE_MODEL=`/bin/grep Hardware /proc/cpuinfo | /bin/awk "{print \\$3}"`
+       /bin/echo "Hardware Model=${HARDWARE_MODEL}"
+
+       if [ -e /opt/etc/p2p_supp.conf ]; then
+               echo "File exist: /opt/etc/p2p_supp.conf"
+       else
+               echo "File not exist. Reinstall: /opt/etc/p2p_supp.conf"
+                /bin/cp /usr/etc/wifi-direct/p2p_supp.conf /opt/etc/
+       fi
+       ## For Hawk-P Platform, Hardware model is Samsung
+       if [ $HARDWARE_MODEL = "Samsung" ];then
+               /usr/sbin/wpa_supplicant -t -B -u -ddd -Dnl80211 -ip2p0 -c/opt/etc/p2p_supp_tv.conf -f/opt/usr/data/network/p2p_supplicant.log
+        else
+               /usr/sbin/p2p_supplicant -t -B -u -ddd -Dnl80211 -iwlan0 -c/opt/etc/p2p_supp.conf -f/opt/usr/data/network/p2p_supplicant.log
+       fi
 }
 
 stop()
 {
-       killall wpa_supplicant
+       /usr/bin/killall wpa_supplicant
 }
 
 case $1 in
 "start")
 start
 ;;
+"start_p2p0")
+start_p2p0
+;;
+"start_dbus")
+start_dbus
+;;
 "stop")
 stop
 ;;
 *)
-/bin/echo p2p_supp.sh [start] [stop]
+/bin/echo p2p_supp.sh [start] [start_p2p0] [start_dbus] [stop]
 exit 1
 ;;
 esac
diff --git a/files/p2p_supp_tv.conf b/files/p2p_supp_tv.conf
new file mode 100644 (file)
index 0000000..f7fee0e
--- /dev/null
@@ -0,0 +1,15 @@
+
+##### p2p_supplicant configuration file template #####
+update_config=1
+ctrl_interface=/var/run/wpa_supplicant
+eapol_version=1
+ap_scan=1
+p2p_listen_reg_class=81
+p2p_listen_channel=1
+p2p_oper_reg_class=115
+p2p_oper_channel=48
+device_name=Tizen-TV
+device_type=10-0050F204-5
+config_methods=display keypad push_button
+p2p_no_group_iface=1
+
similarity index 100%
rename from files/access_list
rename to files/persistent-peer
index bbab6e2..0163ac6 100644 (file)
@@ -7,10 +7,13 @@
 TEMP_DHCP_FILE="/tmp/udhcpc_dyn.tmp"
 UDHCPC_LOG="/tmp/udhcpc_log"
 
-env > /tmp/test_env
+BRD_ADDR="+"
+NET_ADDR="$ip/24"
 
-[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
-[ -n "$subnet" ] && NETMASK="netmask $subnet"
+/usr/bin/env > /tmp/test_env
+
+[ -n "$subnet" ] && NET_ADDR="$ip/$subnet"
+[ -n "$broadcast" ] && BRD_ADDR="$broadcast"
 
 case "$1" in
        deconfig)
@@ -22,13 +25,13 @@ case "$1" in
                echo "$interface $ip $BROADCAST $NETMASK" >> $UDHCPC_LOG
 #              if [ -n "$router" ] ; then
 #                      echo "deleting routers" >> $UDHCPC_LOG
-#                      while route del default gw 0.0.0.0 dev $interface 2>/dev/null ; do
+#                      while /sbin/route del default gw 0.0.0.0 dev $interface 2>/dev/null ; do
 #                              :
 #                      done
 #
 #                      for i in $router ; do
 #                              echo "router $i" >> $UDHCPC_LOG
-#                              route add default gw $i dev $interface
+#                              /sbin/route add default gw $i dev $interface
 #                      done
 #              fi
 
@@ -38,7 +41,7 @@ case "$1" in
                if [ -n $router ]; then
                        for i in $router ; do
 # Take the first router
-                               echo "route $i"
+                               echo "/sbin/route $i"
                                local_gateway=$i
                                break
                        done
@@ -50,12 +53,11 @@ case "$1" in
                        local_gateway="0.0.0.0"
                fi
 
-               vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname ${interface} -f
-               vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip ${ip} -f
-               vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask ${subnet} -f
-               vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway ${local_gateway} -f
-               vconftool set -t string memory/private/wifi_direct_manager/dhcpc_server_ip ${serverid} -f
-               
+               /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname ${interface} -f
+               /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask ${subnet} -f
+               /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway ${local_gateway} -f
+               /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/dhcpc_server_ip ${serverid} -f
+               /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip ${ip} -f
                echo $i >> $TEMP_DHCP_FILE
                ;;
 esac
old mode 100755 (executable)
new mode 100644 (file)
index 2cc81d3..68d6eb3
@@ -1,33 +1,40 @@
 #!/bin/sh
-INTERFACE_NAME="p2p-wlan0-0"
+#INTERFACE_NAME="p2p-wlan0-0"
+#INTERFACE_PREFIX="p2p"
+INTERFACE_NAME="wlan0"
 INTERFACE_PREFIX="p2p"
 TARGET="REDWOOD"
 DEFAULT_IP="192.168.49.1"
+DEFAULT_NET="192.168.49.1/24"
+DEFAULT_BRD="192.168.49.255"
 
-val=`uname -a | grep PQ | wc -l`
+val=`/bin/uname -a | /bin/grep PQ | /usr/bin/wc -l`
 if [ "${val}" -eq "1" ]; then
        TARGET="PQ"
 fi
 
-val=`uname -a | grep U1HD | wc -l`
+val=`/bin/uname -a | /bin/grep U1HD | /usr/bin/wc -l`
 if [ "${val}" -eq "1" ]; then
        INTERFACE_PREFIX="wl0"
        TARGET="U1HD"
 fi
 
-val=`uname -a | grep U1SLP | wc -l`
+val=`/bin/uname -a | /bin/grep U1SLP | /usr/bin/wc -l`
 if [ "${val}" -eq "1" ]; then
        INTERFACE_PREFIX="wl0"
        TARGET="U1SLP"
 fi
 
-val=`uname -a | grep i686  | wc -l`
+val=`/bin/uname -a | /bin/grep i686  | /usr/bin/wc -l`
 if [ "${val}" -eq "1" ]; then
        INTERFACE_PREFIX="eth"
        TARGET="EMUL"
 fi
 
-interface=`ifconfig|grep ^${INTERFACE_NAME}|cut -d" " -f1`
+
+#interface=`/sbin/ifconfig|/bin/grep ^${INTERFACE_NAME}|/usr/bin/cut -d" " -f1`
+interface=`/sbin/ifconfig|/bin/grep ^${INTERFACE_NAME}|/usr/bin/cut -d":" -f1`
+#interface=`/usr/sbin/ip link|/bin/grep ^${INTERFACE_NAME}|/usr/bin/cut -d":" -f2`
 echo "Target is ${TARGET} and interface ${INTERFACE_PREFIX}: ${interface}."
 
 start_dhcp_server()
@@ -37,23 +44,23 @@ start_dhcp_server()
                return 0
         fi
 
-       ifconfig ${interface} ${DEFAULT_IP} up
-       udhcpd /usr/etc/wifi-direct/dhcpd.${INTERFACE_PREFIX}.conf -f &
+       /sbin/ifconfig ${interface} ${DEFAULT_IP} up
+       /usr/bin/udhcpd /usr/etc/wifi-direct/dhcpd.${INTERFACE_PREFIX}.conf -f &
 
-       route=`cat /usr/etc/wifi-direct/dhcpd.${INTERFACE_PREFIX}.conf | grep router | awk '{print $3}'`
+       route=`/bin/cat /usr/etc/wifi-direct/dhcpd.${INTERFACE_PREFIX}.conf | /bin/grep router | /bin/awk '{print $3}'`
        if [ -z $route ]; then
                route="192.168.49.1"
        fi
-       subnet=`cat /usr/etc/wifi-direct/dhcpd.${INTERFACE_PREFIX}.conf | grep subnet | awk '{print $3}'`
+       subnet=`/bin/cat /usr/etc/wifi-direct/dhcpd.${INTERFACE_PREFIX}.conf | /bin/grep subnet | /bin/awk '{print $3}'`
 
        if [ -z $subnet ]; then
                subnet="255.255.255.0"
        fi
 
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname ${interface} -f
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip ${DEFAULT_IP} -f
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask ${subnet} -f
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway ${route} -f
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname ${interface} -f
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask ${subnet} -f
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway ${route} -f
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip ${DEFAULT_IP} -f
 }
 
 start_dhcp_client()
@@ -68,20 +75,20 @@ start_dhcp_client()
 
 stop_dhcp()
 {
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname "" -f
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip "" -f
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask "" -f
-       vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway "" -f
-
-       killall udhcpc
-       killall udhcpd
-#      ifconfig ${interface} 0.0.0.0
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname "" -f
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask "" -f
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway "" -f
+       /usr/bin/vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip "" -f
+
+       /usr/bin/killall /usr/bin/udhcpc
+       /usr/bin/killall /usr/bin/udhcpd
+       /sbin/ifconfig ${interface} 0.0.0.0
 }
 
 is_running()
 {
        program=$1
-       run=`ps -eo comm|grep ${program}`
+       run=`/bin/ps -eo comm|/bin/grep ${program}`
        if [ "X${run}" == "X" ]; then
                echo "${program} is not running"
        else
@@ -91,8 +98,8 @@ is_running()
 
 status_dhcp()
 {
-       is_running udhcpc 
-       is_running udhcpd 
+       is_running /usr/bin/udhcpc
+       is_running /usr/bin/udhcpd
 }
 
 
old mode 100755 (executable)
new mode 100644 (file)
index a993eac..78c2fd5
@@ -1,6 +1,6 @@
 #!/bin/sh
 program="wfd-manager"
-target=`ps -eo comm|grep ${program}`
+target=`/bin/ps -eo comm|/bin/grep ${program}`
 
 start_wifi_direct()
 {
@@ -8,7 +8,7 @@ start_wifi_direct()
                echo "${program} is not running"
                echo "Launching ${program}"
                /usr/bin/${program}&
-               sleep 1
+               /bin/sleep 1
        else
                echo "${program} is already running"
        fi
@@ -20,7 +20,7 @@ stop_wifi_direct()
                echo "${program} is not running"
        else
                echo "${program} is running.. Killing it"
-               killall ${program}
+               /usr/bin/killall ${program}
        fi
 }
 
index 7731a7f..fce1025 100644 (file)
@@ -31,8 +31,9 @@
 #define WFD_SERVER_SOCK_PATH "/tmp/wfd_client_socket"
 #define WFD_SERVER_SOCK_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
 #define WFD_MAX_CLIENT 16
+#define WFD_CLIENT_PENDING_SOCKET -999
 
-//#define SOCK_FD_MIN 3
+#define SOCK_FD_MIN 3
 #define WFD_POLL_TIMEOUT 2000
 
 typedef struct {
index 716a8a4..27c1271 100644 (file)
 #define IFACE_NAME_LEN 16
 
 typedef enum {
-       WFD_GROUP_ROLE_NONE,
-       WFD_GROUP_ROLE_GC,
-       WFD_GROUP_ROLE_GO,
-} wfd_group_role_e;
-
-typedef enum {
        WFD_GROUP_FLAG_NONE,
        WFD_GROUP_FLAG_PERSISTENT,
        WFD_GROUP_FLAG_AUTONOMOUS,
@@ -53,21 +47,23 @@ typedef struct {
        int freq;               // MHz
        GList *members;
        int member_count;
-       char pass[PASSPHRASE_LEN+1];
+       char passphrase[PASSPHRASE_LEN +1];
 } wfd_group_s;
 
 
-wfd_group_s *wfd_create_group(void *data, char *ifname, int role, unsigned char *go_dev_addr);
+wfd_group_s *wfd_create_group(void *data, wfd_oem_event_s *group_info);
 wfd_group_s *wfd_create_pending_group(void *data, unsigned char * bssid);
-int wfd_group_complete(void *data, char *ifname, int role, unsigned char *go_dev_addr);
+int wfd_group_complete(void *data, wfd_oem_event_s *group_info);
 int wfd_destroy_group(void * data, char *ifname);
 int wfd_group_add_member(wfd_group_s *group, unsigned char *addr);
 int wfd_group_remove_member(wfd_group_s *group, unsigned char *addr);
+#if 0
 int wfd_group_get_channel(wfd_group_s *group);
-int wfd_group_is_autonomous(wfd_group_s *group);
+int wfd_group_get_flags(wfd_group_s *group);
 int wfd_group_get_members();
 int wfd_group_make_persistent();
-int wfd_group_get_flags(wfd_group_s *group);
+#endif
+int wfd_group_is_autonomous(wfd_group_s *group);
 wfd_device_s *wfd_group_find_member_by_addr(wfd_group_s *group, unsigned char *addr);
 
 #endif /* __WIFI_DIRECT_GROUP_H__ */
diff --git a/include/wifi-direct-ipc.h b/include/wifi-direct-ipc.h
new file mode 100644 (file)
index 0000000..b9878d3
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * wifi-direct
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sungsik Jang <sungsik.jang@samsung.com>, Dongwook Lee <dwmax.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __WIFI_DIRECT_INTERNAL_H_
+#define __WIFI_DIRECT_INTERNAL_H_
+
+#define true 1
+#define false 0
+
+#define WFD_INVALID_ID -1
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK  O_NDELAY
+#endif /** O_NONBLOCK */
+
+
+#ifndef _UINT32_TYPE_H_
+#define _UINT32_TYPE_H_
+typedef unsigned int uint32;
+#endif /** _UINT32_TYPE_H_ */
+
+typedef unsigned int ipv4_addr_t;
+
+#ifndef TRUE
+#define TRUE 1
+#endif /** TRUE */
+
+#ifndef FALSE
+#define FALSE 0
+#endif /** FALSE */
+
+#define WIFI_DIRECT_MAX_SSID_LEN 32
+#define WIFI_DIRECT_MAX_DEVICE_NAME_LEN 32
+#define WIFI_DIRECT_WPS_PIN_LEN 8
+#define WIFI_DIRECT_MAC_ADDRESS_INFO_FILE "/opt/etc/.mac.info"
+#define WIFI_DIRECT_MAX_SERVICES_LEN 1024
+#define WIFI_DIRECT_MAX_SERVICE_NAME_LEN 256
+
+#define VCONFKEY_IFNAME "memory/private/wifi_direct_manager/p2p_ifname"
+#define VCONFKEY_LOCAL_IP "memory/private/wifi_direct_manager/p2p_local_ip"
+#define VCONFKEY_SUBNET_MASK "memory/private/wifi_direct_manager/p2p_subnet_mask"
+#define VCONFKEY_GATEWAY "memory/private/wifi_direct_manager/p2p_gateway"
+
+typedef enum
+{
+       WIFI_DIRECT_CMD_INVALID,
+       WIFI_DIRECT_CMD_REGISTER,
+       WIFI_DIRECT_CMD_INIT_ASYNC_SOCKET,
+       WIFI_DIRECT_CMD_DEREGISTER,
+       WIFI_DIRECT_CMD_GET_LINK_STATUS,
+       WIFI_DIRECT_CMD_ACTIVATE,
+       WIFI_DIRECT_CMD_DEACTIVATE,
+       WIFI_DIRECT_CMD_START_DISCOVERY,
+       WIFI_DIRECT_CMD_START_DISCOVERY_SPECIFIC_CHANNEL,
+       WIFI_DIRECT_CMD_CANCEL_DISCOVERY,
+       WIFI_DIRECT_CMD_IS_LISTENING_ONLY,      // 10
+       WIFI_DIRECT_CMD_GET_DISCOVERY_RESULT,
+
+       WIFI_DIRECT_CMD_CONNECT,
+       WIFI_DIRECT_CMD_SEND_CONNECT_REQ,
+       WIFI_DIRECT_CMD_CANCEL_CONNECT, // deprecated
+       WIFI_DIRECT_CMD_CANCEL_CONNECTION,
+       WIFI_DIRECT_CMD_REJECT_CONNECTION,
+       WIFI_DIRECT_CMD_DISCONNECT,
+       WIFI_DIRECT_CMD_DISCONNECT_ALL,
+       WIFI_DIRECT_CMD_GET_CONNECTED_PEERS_INFO,
+
+       WIFI_DIRECT_CMD_CREATE_GROUP,   // 20
+       WIFI_DIRECT_CMD_DESTROY_GROUP,
+       WIFI_DIRECT_CMD_IS_GROUPOWNER,
+       WIFI_DIRECT_CMD_IS_AUTONOMOUS_GROUP,
+
+       WIFI_DIRECT_CMD_GET_SSID,
+       WIFI_DIRECT_CMD_SET_SSID,
+       WIFI_DIRECT_CMD_GET_IP_ADDR,
+       WIFI_DIRECT_CMD_GET_MAC_ADDR,
+       WIFI_DIRECT_CMD_GET_CONFIG,
+       WIFI_DIRECT_CMD_SET_CONFIG,
+
+       WIFI_DIRECT_CMD_ACTIVATE_PUSHBUTTON,    // 30
+       WIFI_DIRECT_CMD_SET_WPS_PIN,
+       WIFI_DIRECT_CMD_GET_WPS_PIN,
+       WIFI_DIRECT_CMD_GENERATE_WPS_PIN,
+       WIFI_DIRECT_CMD_SET_WPA,
+       WIFI_DIRECT_CMD_GET_SUPPORTED_WPS_MODE,
+       WIFI_DIRECT_CMD_GET_LOCAL_WPS_MODE,
+       WIFI_DIRECT_CMD_GET_REQ_WPS_MODE,
+       WIFI_DIRECT_CMD_SET_REQ_WPS_MODE,
+
+       WIFI_DIRECT_CMD_SET_GO_INTENT,
+       WIFI_DIRECT_CMD_GET_GO_INTENT,  // 40
+       WIFI_DIRECT_CMD_SET_MAX_CLIENT,
+       WIFI_DIRECT_CMD_GET_MAX_CLIENT,
+       WIFI_DIRECT_CMD_SET_AUTOCONNECTION_MODE,
+       WIFI_DIRECT_CMD_IS_AUTOCONNECTION_MODE,
+       WIFI_DIRECT_CMD_IS_DISCOVERABLE,
+
+       WIFI_DIRECT_CMD_GET_OPERATING_CHANNEL,
+       WIFI_DIRECT_CMD_ACTIVATE_PERSISTENT_GROUP,
+       WIFI_DIRECT_CMD_DEACTIVATE_PERSISTENT_GROUP,
+       WIFI_DIRECT_CMD_IS_PERSISTENT_GROUP,
+       WIFI_DIRECT_CMD_GET_PERSISTENT_GROUP_INFO,      // 50
+       WIFI_DIRECT_CMD_REMOVE_PERSISTENT_GROUP,
+       WIFI_DIRECT_CMD_GET_DEVICE_NAME,
+       WIFI_DIRECT_CMD_SET_DEVICE_NAME,
+
+       WIFI_DIRECT_CMD_SET_OEM_LOGLEVEL,
+       WIFI_DIRECT_CMD_GET_PEER_INFO,
+       WIFI_DIRECT_CMD_SET_PASSPHRASE,
+       WIFI_DIRECT_CMD_GET_PASSPHRASE,
+       WIFI_DIRECT_CMD_SET_AUTOCONNECTION_PEER,
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       WIFI_DIRECT_CMD_REGISTER_LOCAL_SERVICE,
+       WIFI_DIRECT_CMD_DEREGISTER_LOCAL_SERVICE,
+       WIFI_DIRECT_CMD_START_SERVICE_DISCOVERY,
+       WIFI_DIRECT_CMD_CANCEL_SERVICE_DISCOVERY,       //60
+
+       WIFI_DIRECT_CMD_REGISTER_SERVICE,
+       WIFI_DIRECT_CMD_DEREGISTER_SERVICE,
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       WIFI_DIRECT_CMD_INIT_MIRACAST,
+       WIFI_DIRECT_CMD_INIT_DISPLAY,
+       WIFI_DIRECT_CMD_DEINIT_DISPLAY,
+       WIFI_DIRECT_CMD_SET_DISPLAY,
+       WIFI_DIRECT_CMD_SET_DISPLAY_AVAILABILITY,
+       WIFI_DIRECT_CMD_GET_PEER_DISPLAY_TYPE,
+       WIFI_DIRECT_CMD_GET_PEER_DISPLAY_AVAILABILITY,
+       WIFI_DIRECT_CMD_GET_PEER_DISPLAY_HDCP,
+       WIFI_DIRECT_CMD_GET_PEER_DISPLAY_PORT,
+       WIFI_DIRECT_CMD_GET_PEER_DISPLAY_THROUGHPUT,
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+
+
+       WIFI_DIRECT_CMD_MAX
+} wifi_direct_cmd_e;
+
+/**
+ * Wi-Fi Direct client event for IPC
+ */
+typedef enum
+{
+       WIFI_DIRECT_CLI_EVENT_INVALID = -1,                                     /**< */
+
+       WIFI_DIRECT_CLI_EVENT_ACTIVATION,                                               /**< */
+       WIFI_DIRECT_CLI_EVENT_DEACTIVATION,                                     /**< */
+
+       WIFI_DIRECT_CLI_EVENT_DISCOVER_START,                           /**< 80211 scan*/
+       WIFI_DIRECT_CLI_EVENT_DISCOVER_START_LISTEN_ONLY,       /**< listen only mode*/
+       WIFI_DIRECT_CLI_EVENT_DISCOVER_START_SEARCH_LISTEN,     /**< search, listen*/
+       WIFI_DIRECT_CLI_EVENT_DISCOVER_END,                                     /**< */
+       WIFI_DIRECT_CLI_EVENT_DISCOVER_FOUND_PEERS,                     /**< */
+
+       WIFI_DIRECT_CLI_EVENT_CONNECTION_START,                         /**< */
+       WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ,                           /**< */
+       WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP,                           /**< */
+       WIFI_DIRECT_CLI_EVENT_CONNECTION_WPS_REQ,                       /**< */
+
+       WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP,                                /**< */
+       WIFI_DIRECT_CLI_EVENT_DISCONNECTION_IND,                                /**< */
+       WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND,                               /**< */
+
+       WIFI_DIRECT_CLI_EVENT_GROUP_CREATE_RSP,                         /**< */
+       WIFI_DIRECT_CLI_EVENT_GROUP_DESTROY_RSP,                                /**< */
+
+       WIFI_DIRECT_CLI_EVENT_IP_LEASED_IND,                            /**< */
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_STARTED,
+       WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FOUND,
+       WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FINISHED,
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+       WIFI_DIRECT_CLI_EVENT_MAX,
+} wfd_client_event_e;
+
+/**
+ * Wi-Fi Direct configuration data structure for IPC
+ */
+typedef struct
+{
+       char device_name[WIFI_DIRECT_MAX_DEVICE_NAME_LEN + 1];
+       int channel;
+       wifi_direct_wps_type_e wps_config;
+       int max_clients;
+       bool hide_SSID;
+       int group_owner_intent;
+       bool want_persistent_group;
+       bool listen_only;
+       bool auto_connection;
+       wifi_direct_primary_device_type_e primary_dev_type;
+       wifi_direct_secondary_device_type_e secondary_dev_type;
+} wfd_config_data_s;
+
+
+/**
+ * Wi-Fi Direct buffer structure to store result of peer discovery for IPC
+ */
+typedef struct
+{
+       char device_name[WIFI_DIRECT_MAX_DEVICE_NAME_LEN + 1];
+       unsigned char mac_address[6];
+       unsigned char intf_address[6];
+       int channel;
+       bool is_connected;
+       bool is_group_owner;
+       bool is_persistent_go;
+       unsigned int category;
+       unsigned int subcategory;
+
+       unsigned int services;
+
+       unsigned int wps_device_pwd_id;
+       unsigned int wps_cfg_methods;
+
+       bool is_wfd_device;
+
+} wfd_discovery_entry_s;
+
+
+/**
+ * Wi-Fi Direct buffer structure to store information of connected peer
+ */
+typedef struct
+{
+       char device_name[WIFI_DIRECT_MAX_DEVICE_NAME_LEN + 1];
+       unsigned char ip_address[4];
+       unsigned char mac_address[6];
+       unsigned char intf_address[6];
+       int channel;
+       bool is_p2p;
+       unsigned short category;
+       unsigned short subcategory;
+
+       unsigned int services;
+
+       bool is_wfd_device;
+
+} wfd_connected_peer_info_s;
+
+typedef struct
+{
+       int network_id;
+       char ssid[WIFI_DIRECT_MAX_SSID_LEN + 1];
+       unsigned char go_mac_address[6];
+} wfd_persistent_group_info_s;
+
+typedef struct
+{
+       int int1;
+       int int2;
+       int int3;
+       unsigned char mac_addr[6];
+} wifi_direct_client_request_data_s;
+
+
+typedef struct
+{
+       wifi_direct_cmd_e cmd;
+       int client_id;
+       unsigned int cmd_data_len;
+       wifi_direct_client_request_data_s data;
+} wifi_direct_client_request_s;
+
+typedef struct
+{
+       wifi_direct_cmd_e cmd;
+       wifi_direct_error_e result;
+       int client_id;
+       int param1;
+       char param2[64];
+       char param3[32];
+       int data_length;
+} wifi_direct_client_response_s;
+
+typedef struct
+{
+       wfd_client_event_e event;
+       wifi_direct_error_e error;
+       int type;
+       char param1[64];
+       char param2[256];
+} wifi_direct_client_noti_s;
+
+
+#endif /* __WIFI_DIRECT_INTERNAL_H_ */
index 8141552..2a78292 100644 (file)
 #ifndef __WIFI_DIRECT_MANAGER_H__
 #define __WIFI_DIRECT_MANAGER_H__
 
+#if 0
 #define DEFAULT_DEVICE_NAME "Tizen_Device"
 #define DEFAULT_IFNAME "p2p0"
 #define GROUP_IFNAME "p2p-wlan0-0"
+#endif
+#define DEFAULT_DEVICE_NAME "JWSCOM"
+#define DEFAULT_IFNAME "wlan0"
+#define GROUP_IFNAME "wlan0"
+
 #define WFD_MAX_CLIENT 16
 #define WFD_MAX_STATION 8
 
@@ -40,8 +46,7 @@
 #define IPADDR_LEN 4
 #define IPSTR_LEN 16
 #define PINSTR_LEN 8
-#define PASSPHRASE_LEN 8
-#define QUERY_HANDLE_LIMIT 256
+#define PASSPHRASE_LEN 64
 
 #if 0
 typedef enum {
@@ -74,40 +79,42 @@ typedef enum {
 } wfd_scan_mode_e;
 
 typedef enum {
-       WFD_DEV_DENIED,
-       WFD_DEV_ALLOWED,
-       WFD_DEV_UNKNOWN,
-}wfd_dev_connection_flag_e;
+       WFD_PEER_STATE_DISCOVERED,
+       WFD_PEER_STATE_CONNECTING,
+       WFD_PEER_STATE_CONNECTED,
+} wfd_peer_state_e;
 
-typedef struct {
-       wifi_direct_display_type_e type;
-       char dev_info[2];
-       int ctrl_port;
-       int max_tput;
-       int availability;
-       int hdcp_support;
-}wfd_display_info_s;
+typedef enum {
+       WFD_IP_TYPE_DYNAMIC,
+       WFD_IP_TYPE_STATIC,
+} wfd_ip_type_e;
 
-typedef struct {
-       wifi_direct_service_type_e service_type;
-       int ref_counter;
-       char *service_string;
-       int service_str_length;
-} wfd_service_s;
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+
+typedef enum {
+       WFD_DISPLAY_TYPE_SOURCE,
+       WFD_DISPLAY_TYPE_PRISINK,
+       WFD_DISPLAY_TYPE_SECSINK,
+       WFD_DISPLAY_TYPE_DUAL,
+} wfd_display_type_e;
 
 typedef struct {
-       int handle;
-       int ref_counter;
-       unsigned char mac_addr[6];
-       wifi_direct_service_type_e service_type;
-       char *query_string;
-}wfd_query_s;
+       int type;
+       int availablity;
+       int wsd_support;
+       int tdls_support;
+       int hdcp_support;
+       int sync_support;
+       int port;
+       int max_tput;
+} wfd_display_s;
 
-typedef enum {
-       WFD_PEER_STATE_DISCOVERED,
-       WFD_PEER_STATE_CONNECTING,
-       WFD_PEER_STATE_CONNECTED,
-} wfd_peer_state_e;
+#define WIFI_DISPLAY_DEFAULT_TYPE WFD_DISPLAY_TYPE_SOURCE
+#define WIFI_DISPLAY_DEFAULT_AVAIL 1
+#define WIFI_DISPLAY_DEFAULT_HDCP 1
+#define WIFI_DISPLAY_DEFAULT_PORT 7236
+#define WIFI_DISPLAY_DEFAULT_TPUT 54
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
 typedef struct {
        int state;
@@ -126,8 +133,16 @@ typedef struct {
        int group_flags;
        int wps_mode;
 
+       char passphrase[PASSPHRASE_LEN +1];
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       wfd_display_s display;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
        GList *services;
-       wfd_display_info_s *wifi_display;
+       unsigned int service_count;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
        unsigned char ip_addr[IPADDR_LEN];
 } wfd_device_s;
@@ -140,7 +155,7 @@ typedef struct {
        GList *clients;
        unsigned int client_count;
 
-       int state;
+       wifi_direct_state_e state;
        unsigned int exit_timer;
 
        wfd_device_s *local;
@@ -148,6 +163,8 @@ typedef struct {
        int req_wps_mode;
        int max_station;
        int autoconnection;
+       unsigned char autoconnection_peer[MACADDR_LEN];
+       char auto_pin[PINSTR_LEN+1];    // for NFC Printer
        int scan_mode;
 
        GList *peers;
@@ -157,9 +174,6 @@ typedef struct {
 
        void *group;
 
-       GList *query_handles;
-       GList *access_list;
-
        void *oem_ops;
        void *plugin_handle;
 } wfd_manager_s;
@@ -168,17 +182,15 @@ wfd_manager_s *wfd_get_manager();
 int wfd_local_reset_data(wfd_manager_s *manager);
 int wfd_local_get_dev_name(char *dev_name);
 int wfd_local_set_dev_name(char *dev_name);
-int wfd_local_get_dev_mac(unsigned char *dev_mac);
+int wfd_local_get_dev_mac(char *dev_mac);
+#if 0
 int wfd_local_get_intf_mac(unsigned char *intf_mac);
+int wfd_local_set_wps_mode(int wps_mode);
+wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr);
+#endif
 int wfd_local_get_ip_addr(char *ip_str);
 int wfd_local_get_supported_wps_mode(int *wps_mode);
-int wfd_local_set_req_wps_mode(int req_wps_mode);
 int wfd_local_get_wps_mode(int *wps_mode);
-int wfd_local_get_req_wps_mode(int *req_wps_mode);
-
-int wfd_local_get_display_port(int *port);
-int wfd_local_get_display_type(wifi_direct_display_type_e *type);
-
 int wfd_manager_get_go_intent(int *go_intent);
 int wfd_manager_set_go_intent(int go_intent);
 int wfd_manager_get_max_station(int *max_station);
@@ -188,20 +200,6 @@ int wfd_manager_set_autoconnection(int autoconnection);
 int wfd_manager_get_req_wps_mode(int *req_wps_mode);
 int wfd_manager_set_req_wps_mode(int req_wps_mode);
 
-int wfd_manager_access_control(wfd_manager_s *manager, unsigned char *dev_addr);
-int wfd_manager_add_to_access_list(wfd_manager_s *manager, wfd_device_s *peer, int allowed);
-int wfd_manager_del_from_access_list(wfd_manager_s *manager, unsigned char *mac);
-
-int wfd_manager_service_add(wfd_manager_s *manager, wifi_direct_service_type_e type, char *data);
-int wfd_manager_service_del(wfd_manager_s *manager, wifi_direct_service_type_e  type, char *data);
-int wfd_manager_serv_disc_req(wfd_manager_s *manager, unsigned char* mad_addr, wifi_direct_service_type_e  type, char *data);
-int wfd_manager_serv_disc_cancel(wfd_manager_s *manager, int handle);
-int wfd_manager_init_service(wfd_device_s *device);
-int wfd_manager_init_query(wfd_manager_s *manager);
-
-int wfd_manager_init_wifi_display(wifi_direct_display_type_e type, int port, int hdcp);
-int wfd_manager_deinit_wifi_display();
-
 int wfd_manager_local_config_set(wfd_manager_s *manager);
 int wfd_manager_activate(wfd_manager_s *manager);
 int wfd_manager_deactivate(wfd_manager_s *manager);
@@ -211,11 +209,14 @@ int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_ad
 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr);
 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr);
 int wfd_manager_disconnect_all(wfd_manager_s *manager);
-int wfd_manager_get_access_list(wfd_manager_s *manager, wfd_access_list_info_s **access_list_data);
+int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char* addr, wfd_discovery_entry_s **peer);
 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers);
 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data);
-wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr);
-wfd_device_s *wfd_manager_get_current_peer(wfd_manager_s *manager);
 int wfd_manager_get_goup_ifname(char **ifname);
+wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr);
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int wfd_manager_set_display_device(int type, int port, int hdcp);
+int wfd_manager_set_session_availability(int availability);
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
 #endif /* __WIFI_DIRECT_MANAGER_H__ */
index 6dfd78d..283e7bf 100644 (file)
@@ -35,10 +35,11 @@ int wfd_update_peer(void *data, wfd_device_s *peer);
 int wfd_update_peer_time(void*data, unsigned char *peer_addr);
 int wfd_peer_clear_all(void *data);
 wfd_device_s *wfd_peer_find_by_dev_addr(void *data, unsigned char *dev_addr);
+#if 0
 wfd_device_s *wfd_peer_find_by_intf_addr(void *data, unsigned char *intf_addr);
-wfd_device_s *wfd_peer_find_by_addr(void *data, unsigned char *addr);
 wfd_device_s *wfd_peer_find_current_peer(void *data);
-int wfd_peer_set_data(unsigned char *dev_addr, int type, int data);
 int wfd_peer_get_data(unsigned char *dev_addr, int type, int data);
-
+int wfd_peer_set_data(unsigned char *dev_addr, int type, int data);
+#endif
+wfd_device_s *wfd_peer_find_by_addr(void *data, unsigned char *addr);
 #endif /* __WIFI_DIRECT_PEER_H__ */
diff --git a/include/wifi-direct-service.h b/include/wifi-direct-service.h
new file mode 100644 (file)
index 0000000..6f84c03
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * This file declares wifi direct service functions and structures.
+ *
+ * @file               wifi-direct-service.h
+ * @author     Gibyoung Kim (lastkgb.kim@samsung.com)
+ * @version    0.7
+ */
+
+#ifndef __WIFI_DIRECT_SERVICE_H__
+#define __WIFI_DIRECT_SERVICE_H__
+
+typedef enum {
+       WFD_SERVICE_TYPE_ALL,
+       WFD_SERVICE_TYPE_BONJOUR,
+       WFD_SERVICE_TYPE_UPNP,
+       WFD_SERVICE_TYPE_WS_DISCOVERY,
+       WFD_SERVICE_TYPE_WIFI_DISPLAY,
+       WFD_SERVICE_TYPE_VENDOR = 0xff,
+} wfd_service_type_e;
+
+typedef enum {
+       WFD_BONJOUR_RDATA_PTR = 0x0c,
+       WFD_BONJOUR_RDATA_TXT = 0x10,
+}wfd_bonjour_rdata_type_e;
+
+typedef struct {
+       int version;
+       char *service;
+} wfd_service_upnp_s;
+
+typedef struct {
+       char *query;
+       wfd_bonjour_rdata_type_e rdata_type;
+       char *rdata;
+} wfd_service_bonjour_s;
+
+typedef struct {
+       int type;
+       int id;
+       int status;
+       char *str_ptr;
+       union {
+               struct {
+                       char *version;
+                       char *service;
+               } upnp;
+               struct {
+                       char *query;
+                       char *rdata;
+                       wfd_bonjour_rdata_type_e rdata_type;
+               } bonjour;
+               struct {
+                       char *info1;
+                       char *info2;
+               } vendor;
+       } data;
+} wfd_service_s;
+
+
+int wfd_service_add(GList **services, int type, char *data, int *service_id);
+int wfd_service_del(GList *services, int service_id);
+#if 0
+int wfd_service_disc_req(unsigned char *addr, int type, char *data);
+int wfd_service_disc_cancel(int handle);
+#endif
+
+
+#endif /* __WIFI_DIRECT_SERVICE_H__ */
index 2d3eea9..df0d286 100644 (file)
@@ -55,6 +55,7 @@ typedef struct {
        int state;
        int timer;
        int connecting_120;
+       unsigned int retry_gsrc;
        int direction;
        wfd_device_s *peer;
        int wps_mode;
@@ -75,8 +76,10 @@ int wfd_session_invite(wfd_session_s *session);
 int wfd_session_join(wfd_session_s *session);
 wfd_device_s *wfd_session_get_peer(wfd_session_s *session);
 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session);
+#if 0
 int wfd_session_get_state(wfd_session_s *session);
 int wfd_session_stop(wfd_session_s *session);
+#endif
 int wfd_session_complete(wfd_session_s *session);
 int wfd_session_timer(wfd_session_s *session, int start);
 
old mode 100644 (file)
new mode 100755 (executable)
index efe96bf..d8fd124
 
 #ifndef __WIFI_DIRECT_UTIL_H__
 #define __WIFI_DIRECT_UTIL_H__
-
+#if 0
+#if !defined TIZEN_TV
 #define DEFAULT_MAC_FILE_PATH "/opt/etc/.mac.info"
-#define DEFAULT_DEVICE_LIST_FILE_PATH "/usr/etc/wifi-direct/access_list"
+#else
+#define DEFAULT_MAC_FILE_PATH "/sys/class/net/p2p0/address"
+#endif
+#endif
+#define DEFAULT_MAC_FILE_PATH "/sys/class/net/wlan0/address"
 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 #define IP2STR(a) (a)[0], (a)[1], (a)[2], (a)[3]
 #define IPSTR "%d.%d.%d.%d"
+#define ZEROIP "0.0.0.0"
+#define MAC2SECSTR(a) (a)[0], (a)[4], (a)[5]
+#define MACSECSTR "%02x:%02x:%02x"
+#define IP2SECSTR(a) (a)[0], (a)[3]
+#define IPSECSTR "%d..%d"
 
 #define VCONFKEY_DHCPS_IP_LEASE "memory/private/wifi_direct_manager/dhcp_ip_lease"
 #define VCONFKEY_DHCPC_SERVER_IP "memory/private/wifi_direct_manager/dhcpc_server_ip"
+#define VCONFKEY_LOCAL_IP "memory/private/wifi_direct_manager/p2p_local_ip"
 #define DHCP_DUMP_FILE "/tmp/dhcp-client-table"
+#define COUNTRY_CODE_FILE "/usr/etc/wifi-direct/ccode.conf"
 #define MAX_DHCP_DUMP_SIZE 64    // Single lease format: [99:66:dd:00:11:aa 192.168.16.20 00:00:60]
 
-#define SOCK_FD_MIN 0
+#define SOCK_FD_MIN 3
 
 #ifdef USE_DLOG
 #include <dlog.h>
 #define WDS_LOGE(format, args...) LOGE(format, ##args)
 #define WDS_LOGF(format, args...) LOGF(format, ##args)
 
-#define __WDS_LOG_FUNC_ENTER__ LOGV("Enter")
-#define __WDS_LOG_FUNC_EXIT__ LOGV("Quit")
+#define __WDS_LOG_FUNC_ENTER__ LOGD("Enter")
+#define __WDS_LOG_FUNC_EXIT__ LOGD("Quit")
+
+#define WDS_SECLOGI(format, args...) SECURE_LOG(LOG_INFO, LOG_TAG, format, ##args)
+#define WDS_SECLOGD(format, args...) SECURE_LOG(LOG_DEBUG, LOG_TAG, format, ##args)
 
 #else /* USE_DLOG */
 
 #define __WDS_LOG_FUNC_ENTER__
 #define __WDS_LOG_FUNC_EXIT__
 
+#define WDS_SECLOGI(format, args...)
+#define WDS_SECLOGD(format, args...)
+
 #endif /* USE_DLOG */
 
-gboolean wfd_util_execute_file(const char *file_path, char *const args[], char *const envs[]);
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+int wfd_util_get_current_time(unsigned long *cur_time);
+#endif
+gboolean wfd_util_execute_file(const char *file_path,  char *const args[], char *const envs[]);
 int wfd_util_freq_to_channel(int freq);
+int wfd_util_channel_to_freq(int channel);
 int wfd_util_get_phone_name(char *phone_name);
 void wfd_util_set_dev_name_notification();
 void wfd_util_unset_dev_name_notification();
+int wfd_util_set_country();
+
 int wfd_util_check_wifi_state();
 int wfd_util_check_mobile_ap_state();
 int wfd_util_wifi_direct_activatable();
+#if 0
 int wfd_util_get_wifi_direct_state();
+unsigned int wfd_util_static_ip_convert_order(unsigned int net_ip);
+#endif
 int wfd_util_set_wifi_direct_state(int state);
 int wfd_util_get_local_dev_mac(unsigned char *dev_mac);
-
-int wfd_util_get_access_list(GList **access_list);
-int wfd_util_rewrite_device_list_to_file(GList *access_list);
-int wfd_util_add_device_to_list(wfd_device_s *peer, int allowed);
-int wfd_util_reset_access_list_file();
 int wfd_util_start_wifi_direct_popup();
 int wfd_util_dhcps_start();
 int wfd_util_dhcps_wait_ip_leased(wfd_device_s *peer);
@@ -96,5 +118,6 @@ int wfd_util_dhcpc_start(wfd_device_s *peer);
 int wfd_util_dhcpc_stop();
 int wfd_util_dhcpc_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6);
 int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr);
+int wfd_util_get_local_ip(unsigned char* ip_addr);
 
 #endif /* __WIFI_DIRECT_UTIL_H__ */
index 5c90b3f..c0dc8d0 100644 (file)
 #include <stdio.h>
 
 #include <glib.h>
-
-#include <wifi-direct-internal.h>
-
-#include "wifi-direct-manager.h"
-#include "wifi-direct-util.h"
 #include "wifi-direct-oem.h"
 
 int wfd_oem_init(wfd_oem_ops_s *ops, wfd_oem_event_cb event_callback, void *user_data)
 {
        if (!ops || !ops->init) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
        return ops->init(event_callback, user_data);
 }
 
+#if 0
 int wfd_oem_deinit(wfd_oem_ops_s *ops)
 {
        if (!ops || !ops->deinit) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
        return ops->deinit();
 }
+#endif
 
-int wfd_oem_activate(wfd_oem_ops_s *ops)
+int wfd_oem_activate(wfd_oem_ops_s *ops, int concurrent)
 {
        if (!ops || !ops->activate) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
-       return ops->activate();
+       return ops->activate(concurrent);
 }
 
-int wfd_oem_deactivate(wfd_oem_ops_s *ops)
+int wfd_oem_deactivate(wfd_oem_ops_s *ops, int concurrent)
 {
        if (!ops || !ops->deactivate) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
-       return ops->deactivate();
+       return ops->deactivate(concurrent);
 }
 
 int wfd_oem_start_scan(wfd_oem_ops_s *ops, wfd_oem_scan_param_s *param)
 {
        if (!ops || !ops->start_scan) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -88,7 +80,6 @@ int wfd_oem_start_scan(wfd_oem_ops_s *ops, wfd_oem_scan_param_s *param)
 int wfd_oem_stop_scan(wfd_oem_ops_s *ops)
 {
        if (!ops || !ops->stop_scan) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -98,7 +89,6 @@ int wfd_oem_stop_scan(wfd_oem_ops_s *ops)
 int wfd_oem_get_visibility(wfd_oem_ops_s *ops, int *visibility)
 {
        if (!ops || !ops->get_visibility) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -108,7 +98,6 @@ int wfd_oem_get_visibility(wfd_oem_ops_s *ops, int *visibility)
 int wfd_oem_set_visibility(wfd_oem_ops_s *ops, int visibility)
 {
        if (!ops || !ops->set_visibility) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -118,7 +107,6 @@ int wfd_oem_set_visibility(wfd_oem_ops_s *ops, int visibility)
 int wfd_oem_get_scan_result(wfd_oem_ops_s *ops, GList **peers, int *peer_count)
 {
        if (!ops || !ops->get_scan_result) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -128,7 +116,6 @@ int wfd_oem_get_scan_result(wfd_oem_ops_s *ops, GList **peers, int *peer_count)
 int wfd_oem_get_peer_info(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_device_s **peer)
 {
        if (!ops || !ops->get_peer_info) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -138,7 +125,6 @@ int wfd_oem_get_peer_info(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_
 int wfd_oem_prov_disc_req(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
 {
        if (!ops || !ops->prov_disc_req) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -148,7 +134,6 @@ int wfd_oem_prov_disc_req(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_
 int wfd_oem_connect(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_conn_param_s *param)
 {
        if (!ops || !ops->connect) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -158,7 +143,6 @@ int wfd_oem_connect(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_conn_p
 int wfd_oem_reject_connection(wfd_oem_ops_s *ops, unsigned char *peer_addr)
 {
        if (!ops || !ops->reject_connection) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -168,7 +152,6 @@ int wfd_oem_reject_connection(wfd_oem_ops_s *ops, unsigned char *peer_addr)
 int wfd_oem_cancel_connection(wfd_oem_ops_s *ops, unsigned char *peer_addr)
 {
        if (!ops || !ops->cancel_connection) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -178,7 +161,6 @@ int wfd_oem_cancel_connection(wfd_oem_ops_s *ops, unsigned char *peer_addr)
 int wfd_oem_disconnect(wfd_oem_ops_s *ops, unsigned char *peer_addr)
 {
        if (!ops || !ops->disconnect) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -188,7 +170,6 @@ int wfd_oem_disconnect(wfd_oem_ops_s *ops, unsigned char *peer_addr)
 int wfd_oem_get_connected_peers(wfd_oem_ops_s *ops, GList **peers, int *peer_count)
 {
        if (!ops || !ops->get_connected_peers) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -198,7 +179,6 @@ int wfd_oem_get_connected_peers(wfd_oem_ops_s *ops, GList **peers, int *peer_cou
 int wfd_oem_get_pin(wfd_oem_ops_s *ops, char *pin)
 {
        if (!ops || !ops->get_pin) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -208,7 +188,6 @@ int wfd_oem_get_pin(wfd_oem_ops_s *ops, char *pin)
 int wfd_oem_set_pin(wfd_oem_ops_s *ops, char *pin)
 {
        if (!ops || !ops->set_pin) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -218,27 +197,24 @@ int wfd_oem_set_pin(wfd_oem_ops_s *ops, char *pin)
 int wfd_oem_get_supported_wps_mode(wfd_oem_ops_s *ops, int *wps_mode)
 {
        if (!ops || !ops->get_supported_wps_mode) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
        return ops->get_supported_wps_mode(wps_mode);
 }
 
-int wfd_oem_create_group(wfd_oem_ops_s *ops, int persistent, int freq)
+int wfd_oem_create_group(wfd_oem_ops_s *ops, int persistent, int freq, const char *passphrase)
 {
        if (!ops || !ops->create_group) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
-       return ops->create_group(persistent, freq);
+       return ops->create_group(persistent, freq, passphrase);
 }
 
 int wfd_oem_destroy_group(wfd_oem_ops_s *ops, const char *ifname)
 {
        if (!ops || !ops->destroy_group) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -248,7 +224,6 @@ int wfd_oem_destroy_group(wfd_oem_ops_s *ops, const char *ifname)
 int wfd_oem_invite(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_invite_param_s *param)
 {
        if (!ops || !ops->invite) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -258,7 +233,6 @@ int wfd_oem_invite(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_invite_
 int wfd_oem_wps_start(wfd_oem_ops_s *ops, unsigned char *peer_addr, int wps_mode, const char *pin)
 {
        if (!ops || !ops->wps_start) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -268,7 +242,6 @@ int wfd_oem_wps_start(wfd_oem_ops_s *ops, unsigned char *peer_addr, int wps_mode
 int wfd_oem_enrollee_start(wfd_oem_ops_s *ops, unsigned char *peer_addr, int wps_mode, const char *pin)
 {
        if (!ops || !ops->enrollee_start) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -278,7 +251,6 @@ int wfd_oem_enrollee_start(wfd_oem_ops_s *ops, unsigned char *peer_addr, int wps
 int wfd_oem_wps_cancel(wfd_oem_ops_s *ops)
 {
        if (!ops) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -288,7 +260,6 @@ int wfd_oem_wps_cancel(wfd_oem_ops_s *ops)
 int wfd_oem_get_dev_name(wfd_oem_ops_s *ops, char *dev_name)
 {
        if (!ops || !ops->get_dev_name) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -298,7 +269,6 @@ int wfd_oem_get_dev_name(wfd_oem_ops_s *ops, char *dev_name)
 int wfd_oem_set_dev_name(wfd_oem_ops_s *ops, char *dev_name)
 {
        if (!ops || !ops->set_dev_name) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -308,7 +278,6 @@ int wfd_oem_set_dev_name(wfd_oem_ops_s *ops, char *dev_name)
 int wfd_oem_get_dev_mac(wfd_oem_ops_s *ops, char *dev_mac)
 {
        if (!ops || !ops->get_dev_mac) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -318,7 +287,6 @@ int wfd_oem_get_dev_mac(wfd_oem_ops_s *ops, char *dev_mac)
 int wfd_oem_get_dev_type(wfd_oem_ops_s *ops, int *pri_dev_type, int *sec_dev_type)
 {
        if (!ops || !ops->get_dev_type) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -328,7 +296,6 @@ int wfd_oem_get_dev_type(wfd_oem_ops_s *ops, int *pri_dev_type, int *sec_dev_typ
 int wfd_oem_set_dev_type(wfd_oem_ops_s *ops, int pri_dev_type, int sec_dev_type)
 {
        if (!ops || !ops->set_dev_type) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -338,7 +305,6 @@ int wfd_oem_set_dev_type(wfd_oem_ops_s *ops, int pri_dev_type, int sec_dev_type)
 int wfd_oem_get_go_intent(wfd_oem_ops_s *ops, int *go_intent)
 {
        if (!ops || !ops->get_go_intent) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -348,17 +314,24 @@ int wfd_oem_get_go_intent(wfd_oem_ops_s *ops, int *go_intent)
 int wfd_oem_set_go_intent(wfd_oem_ops_s *ops, int go_intent)
 {
        if (!ops || !ops->set_go_intent) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
        return ops->set_go_intent(go_intent);
 }
 
+int wfd_oem_set_country(wfd_oem_ops_s *ops, char *ccode)
+{
+       if (!ops || !ops->set_country) {
+               return -1;
+       }
+
+       return ops->set_country(ccode);
+}
+
 int wfd_oem_get_persistent_groups(wfd_oem_ops_s *ops, wfd_oem_persistent_group_s **groups, int *group_count)
 {
        if (!ops || !ops->get_persistent_groups) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -368,7 +341,6 @@ int wfd_oem_get_persistent_groups(wfd_oem_ops_s *ops, wfd_oem_persistent_group_s
 int wfd_oem_remove_persistent_group(wfd_oem_ops_s *ops, char *ssid, unsigned char *bssid)
 {
        if (!ops || !ops->remove_persistent_group) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
@@ -379,68 +351,94 @@ int wfd_oem_remove_persistent_group(wfd_oem_ops_s *ops, char *ssid, unsigned cha
 int wfd_oem_set_persistent_reconnect(wfd_oem_ops_s *ops, unsigned char *bssid, int reconnect)
 {
        if (!ops || !ops->set_persistent_reconnect) {
-               WDS_LOGE("Invalid parameter");
                return -1;
        }
 
        return ops->set_persistent_reconnect(bssid, reconnect);
 }
 
-int wfd_oem_service_add(wfd_oem_ops_s *ops, wfd_oem_service_e type, char *data)
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+int wfd_oem_start_service_discovery(wfd_oem_ops_s *ops, unsigned char *peer_addr, int service_type)
+{
+       if (!ops || !ops->start_service_discovery) {
+               return -1;
+       }
+
+       return ops->start_service_discovery(peer_addr, service_type);
+}
+
+int wfd_oem_cancel_service_discovery(wfd_oem_ops_s *ops, unsigned char *peer_addr, int service_type)
 {
-       if (!ops || !ops->service_add) {
-               WDS_LOGE("Invalid parameter");
+       if (!ops || !ops->cancel_service_discovery) {
                return -1;
        }
 
-       return ops->service_add(type, data);
+       return ops->cancel_service_discovery(peer_addr, service_type);
 }
 
-int wfd_oem_service_del(wfd_oem_ops_s *ops, wfd_oem_service_e type, char *data)
+int wfd_oem_serv_add(wfd_oem_ops_s *ops, wfd_oem_new_service_s *service)
 {
-       if (!ops || !ops->service_del) {
-               WDS_LOGE("Invalid parameter");
+       if (!ops || !ops->serv_add) {
                return -1;
        }
 
-       return ops->service_del(type, data);
+       return ops->serv_add(service);
 }
 
-int wfd_oem_serv_disc_req(wfd_oem_ops_s *ops, unsigned char* MAC, wfd_oem_service_e type, char *data)
+int wfd_oem_serv_del(wfd_oem_ops_s *ops, wfd_oem_new_service_s *service)
 {
-       if (!ops || !ops->serv_disc_req) {
-               WDS_LOGE("Invalid parameter");
+       if (!ops || !ops->serv_del) {
                return -1;
        }
 
-       return ops->serv_disc_req(MAC, type, data);
+       return ops->serv_del(service);
 }
 
-int wfd_oem_serv_disc_cancel(wfd_oem_ops_s *ops, int identifier)
+int wfd_oem_serv_disc_start(wfd_oem_ops_s *ops, wfd_oem_new_service_s *service)
 {
-       if (!ops || !ops->serv_disc_cancel) {
-               WDS_LOGE("Invalid parameter");
+       if (!ops || !ops->serv_disc_start) {
                return -1;
        }
 
-       return ops->serv_disc_cancel(identifier);
+       return ops->serv_disc_start(service);
 }
 
-int wfd_oem_init_wifi_display(wfd_oem_ops_s *ops, wfd_oem_display_e type, int port, int hdcp)
+int wfd_oem_serv_disc_stop(wfd_oem_ops_s *ops, int handle)
 {
-       if (!ops || !ops->init_wifi_display) {
-               WDS_LOGE("Invalid parameter");
+       if (!ops || !ops->serv_disc_stop) {
                return -1;
        }
 
-       return ops->init_wifi_display(type, port, hdcp);
+       return ops->serv_disc_stop(handle);
 }
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
-int wfd_oem_deinit_wifi_display(wfd_oem_ops_s *ops)
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int wfd_oem_miracast_init(wfd_oem_ops_s *ops, int enable)
 {
-       if (!ops || !ops->deinit_wifi_display) {
-               WDS_LOGE("Invalid parameter");
+       if (!ops || !ops->miracast_init) {
                return -1;
        }
-       return ops->deinit_wifi_display();
+
+       return ops->miracast_init(enable);
+}
+
+int wfd_oem_set_display(wfd_oem_ops_s *ops, wfd_oem_display_s *wifi_display)
+{
+       if (!ops || !ops->set_display) {
+               return -1;
+       }
+
+       return ops->set_display(wifi_display);
+}
+
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+int wfd_oem_refresh(wfd_oem_ops_s *ops)
+{
+       if (!ops || !ops->refresh) {
+               return -1;
+       }
+
+       return ops->refresh();
 }
index eb315e6..e924173 100644 (file)
 
 #define OEM_MACSTR_LEN 18
 #define OEM_MACADDR_LEN 6
+#define OEM_IPADDR_LEN 4
 #define OEM_PINSTR_LEN 8
-#define OEM_PASS_PHRASE_LEN 8
+#define OEM_PASS_PHRASE_LEN 64
 #define OEM_DEV_NAME_LEN 32
 #define OEM_IFACE_NAME_LEN 16
+#define OEM_SERVICE_TYPE_LEN 8
+#define OEM_QUERY_ID_LEN 15
+#define OEM_SERVICE_MAX_LEN 1024
+
+typedef enum {
+       WFD_OEM_SC_SUCCESS = 0,
+       WFD_OEM_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE = 1,
+       WFD_OEM_SC_FAIL_INCOMPATIBLE_PARAMS = 2,
+       WFD_OEM_SC_FAIL_LIMIT_REACHED = 3,
+       WFD_OEM_SC_FAIL_INVALID_PARAMS = 4,
+       WFD_OEM_SC_FAIL_UNABLE_TO_ACCOMMODATE = 5,
+       WFD_OEM_SC_FAIL_PREV_PROTOCOL_ERROR = 6,
+       WFD_OEM_SC_FAIL_NO_COMMON_CHANNELS = 7,
+       WFD_OEM_SC_FAIL_UNKNOWN_GROUP = 8,
+       WFD_OEM_SC_FAIL_BOTH_GO_INTENT_15 = 9,
+       WFD_OEM_SC_FAIL_INCOMPATIBLE_PROV_METHOD = 10,
+       WFD_OEM_SC_FAIL_REJECTED_BY_USER = 11,
+} wfd_oem_status_code_e;
+
+typedef enum {
+       WFD_OEM_WPA_STATE_DISCONNECTED,
+       WFD_OEM_WPA_STATE_INTERFACE_DISABLED,
+       WFD_OEM_WPA_STATE_INACTIVE,
+       WFD_OEM_WPA_STATE_SCANNING,
+       WFD_OEM_WPA_STATE_AUTHENTICATING,
+       WFD_OEM_WPA_STATE_ASSOCIATING,
+       WFD_OEM_WPA_STATE_ASSOCIATED,
+       WFD_OEM_WPA_STATE_4WAY_HANDSHAKE,
+       WFD_OEM_WPA_STATE_GROUP_HANDSHAKE,
+       WFD_OEM_WPA_STATE_COMPLETED,
+       WFD_OEM_WPA_STATE_MAX,
+} ws_wpa_state_type_e;
 
 typedef enum {
        WFD_OEM_EVENT_NONE,
@@ -50,13 +83,13 @@ typedef enum {
 
        WFD_OEM_EVENT_GO_NEG_REQ,
        WFD_OEM_EVENT_GO_NEG_FAIL,
-       WFD_OEM_EVENT_GO_NEG_DONE,              // 10
+       WFD_OEM_EVENT_GO_NEG_DONE,      // 10
        WFD_OEM_EVENT_WPS_FAIL,
        WFD_OEM_EVENT_WPS_DONE,
        WFD_OEM_EVENT_KEY_NEG_FAIL,
        WFD_OEM_EVENT_KEY_NEG_DONE,
 
-       WFD_OEM_EVENT_CONN_FAIL,                // 15
+       WFD_OEM_EVENT_CONN_FAIL,        // 15
        WFD_OEM_EVENT_CONN_DONE,
 
        WFD_OEM_EVENT_GROUP_CREATED,
@@ -70,29 +103,35 @@ typedef enum {
        WFD_OEM_EVENT_CONNECTED,
        WFD_OEM_EVENT_DISCONNECTED,
 
-       WFD_OEM_EVENT_SERV_DISC_RESP,   // 25
+       WFD_OEM_EVENT_TERMINATING,      // 25
 
-       WFD_OEM_EVENT_TERMINATING,
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       WFD_OEM_EVENT_SERV_DISC_RESP,
+       WFD_OEM_EVENT_SERV_DISC_STARTED,
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
        WFD_OEM_EVENT_MAX,
 } wfd_oem_event_e;
 
-typedef enum
-{
-       WFD_OEM_DISPLAY_SOURCE,
-       WFD_OEM_DISPLAY_PRIMARY_SINK,
-       WFD_OEM_DISPLAY_SECONDARY_SINK,
-       WFD_OEM_DISPLAY_DUAL_ROLE,
-}wfd_oem_display_e;
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+typedef enum {
+       WFD_OEM_DISPLAY_TYPE_SOURCE,
+       WFD_OEM_DISPLAY_TYPE_PRISINK,
+       WFD_OEM_DISPLAY_TYPE_SECSINK,
+       WFD_OEM_DISPLAY_TYPE_DUAL,
+} wfd_oem_display_type_e;
 
 typedef struct {
-       wfd_oem_display_e type;
-       char dev_info[2];
-       int ctrl_port;
-       int max_tput;
-       int availability;
+       int type;
+       int availablity;
+       int wsd_support;
+       int tdls_support;
        int hdcp_support;
-}wfd_oem_display_info_s;
+       int sync_support;
+       int port;
+       int max_tput;
+} wfd_oem_display_s;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
 typedef struct {
        int age;
@@ -108,9 +147,9 @@ typedef struct {
        int dev_flags;
        int group_flags;
        int wps_mode;
-
-       wfd_oem_display_info_s wifi_display;
-
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       wfd_oem_display_display;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 } wfd_oem_device_s;
 
 typedef struct {
@@ -123,15 +162,18 @@ typedef struct {
        int dev_flags;
        int group_flags;
        int dev_role;
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       wfd_oem_display_s display;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
        unsigned char p2p_go_addr[OEM_MACADDR_LEN];
-
-       wfd_oem_display_info_s wifi_display;
-
 } wfd_oem_dev_data_s;
 
 typedef struct {
+       char ssid[OEM_DEV_NAME_LEN+1];
+       unsigned char peer_device_addr[OEM_MACADDR_LEN];
        unsigned char peer_intf_addr[OEM_MACADDR_LEN];
-       int dev_pwd_id;
+       int persistent_group;
+       int wps_mode;
        int status;
        int error;
 } wfd_oem_conn_data_s;
@@ -150,6 +192,25 @@ typedef struct {
        unsigned char go_dev_addr[OEM_MACADDR_LEN];
 } wfd_oem_group_data_s;
 
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+typedef enum {
+       WFD_OEM_SERV_STATUS_SUCCESS,
+       WFD_OEM_SERV_STATUS_FAIL,
+} wfd_oem_serv_status_e;
+
+typedef enum {
+       WFD_OEM_SERV_TYPE_ALL,
+       WFD_OEM_SERV_TYPE_BTADDR,
+} wfd_oem_serv_type_e;
+
+typedef struct {
+       int status;
+       int type;
+       unsigned char data[OEM_MACADDR_LEN];
+       unsigned char value[20];
+} wfd_oem_service_data_s;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
 typedef struct {
        int event_id;
        unsigned char dev_addr[OEM_MACADDR_LEN];        // device address
@@ -169,6 +230,7 @@ typedef enum {
        WFD_OEM_EDATA_TYPE_INVITE,
        WFD_OEM_EDATA_TYPE_GROUP,
        WFD_OEM_EDATA_TYPE_SERVICE,
+       WFD_OEM_EDATA_TYPE_NEW_SERVICE,
 } ws_event_type_e;
 
 typedef enum {
@@ -180,6 +242,10 @@ typedef enum {
        WFD_OEM_SCAN_TYPE_FULL,
        WFD_OEM_SCAN_TYPE_SOCIAL,
        WFD_OEM_SCAN_TYPE_SPECIFIC,
+       WFD_OEM_SCAN_TYPE_CHANNEL1,
+       WFD_OEM_SCAN_TYPE_CHANNEL6,
+       WFD_OEM_SCAN_TYPE_CHANNEL11,
+       WFD_OEM_SCAN_TYPE_GO_FREQ,
 } wfd_oem_scan_type_e;
 
 typedef enum {
@@ -205,16 +271,6 @@ typedef enum {
        WFD_OEM_DEV_ROLE_GO,
 } wfd_oem_dev_role_e;
 
-typedef enum
-{
-       WFD_OEM_SERVICE_ALL,
-       WFD_OEM_SERVICE_BONJOUR,
-       WFD_OEM_SERVICE_UPNP,
-       WFD_OEM_SERVICE_WSDISCOVERY,
-       WFD_OEM_SERVICE_WIFIDISPLAY,
-       WFD_OEM_SERVICE_VENDORSPEC = 0xff,
-} wfd_oem_service_e;
-
 typedef struct {
        int scan_mode;
        int scan_time;
@@ -237,6 +293,72 @@ typedef struct {
        unsigned char go_dev_addr[OEM_MACADDR_LEN];
 } wfd_oem_invite_param_s;
 
+typedef enum {
+       WFD_OEM_CONFIG_ATTR_STR_DEVICE_NAME,
+       WFD_OEM_CONFIG_ATTR_STR_SSID_POSTFIX,
+       WFD_OEM_CONFIG_ATTR_STR_COUNTRY,
+       WFD_OEM_CONFIG_ATTR_NUM_GO_INTENT,
+       WFD_OEM_CONFIG_ATTR_NUM_LISTEN_FREQ,
+       WFD_OEM_CONFIG_ATTR_NUM_OPER_FREQ,
+       WFD_OEM_CONFIG_ATTR_NUM_PREF_FREQ,
+       WFD_OEM_CONFIG_ATTR_NUM_PERSIST_RECONN,
+       WFD_OEM_CONFIG_ATTR_NUM_WIFI_DISPLAY,
+       WFD_OEM_CONFIG_ATTR_NUM_P2P_DISABLED,
+       WFD_OEM_CONFIG_ATTR_NUM_MAX_STA,
+       WFD_OEM_CONFIG_ATTR_LIMIT = WFD_OEM_CONFIG_ATTR_NUM_MAX_STA,
+} wfd_oem_conf_attr_e;
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+typedef enum {
+       WFD_OEM_SERVICE_TYPE_ALL,
+       WFD_OEM_SERVICE_TYPE_BONJOUR,
+       WFD_OEM_SERVICE_TYPE_UPNP,
+       WFD_OEM_SERVICE_TYPE_WS_DISCOVERY,
+       WFD_OEM_SERVICE_TYPE_WIFI_DISPLAY,
+       WFD_OEM_SERVICE_TYPE_BT_ADDR,
+       WFD_OEM_SERVICE_TYPE_CONTACT_INFO,
+       WFD_OEM_SERVICE_TYPE_VENDOR = 0xff,
+} wfd_oem_service_type_e;
+
+typedef enum {
+       WFD_OEM_BONJOUR_RDATA_PTR = 0x0c,
+       WFD_OEM_BONJOUR_RDATA_TXT = 0x10,
+}wfd_oem_bonjour_rdata_type_e;
+
+typedef struct {
+       /** Device address for which service discovery is requested */
+       char dev_addr[OEM_MACSTR_LEN+1];
+
+       /** service type requested */
+       char service_type[OEM_SERVICE_TYPE_LEN+1];
+
+       /** query identifier returned by wpa_supplicant for each service discovery request */
+       char query_id[OEM_QUERY_ID_LEN+1];
+} wfd_oem_service_s;
+
+typedef struct {
+       int protocol;
+       int trans_id;
+       int status;
+       char *str_ptr;
+       union {
+               struct {
+                       char *version;
+                       char *service;
+               } upnp;
+               struct {
+                       char *query;
+                       char *rdata;
+                       wfd_oem_bonjour_rdata_type_e rdata_type;
+               } bonjour;
+               struct {
+                       char *data1;
+                       char *data2;
+               } vendor;
+       } data;
+} wfd_oem_new_service_s;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
 typedef struct
 {
        int network_id;
@@ -249,8 +371,8 @@ typedef int (*wfd_oem_event_cb) (void *user_data, void *event);
 typedef struct _wfd_oem_ops_s {
        int (*init) (wfd_oem_event_cb event_callback, void *user_data);
        int (*deinit) (void);
-       int (*activate) (void);
-       int (*deactivate) (void);
+       int (*activate) (int concurrent);
+       int (*deactivate) (int concurrent);
        int (*start_scan) (wfd_oem_scan_param_s *param);
        int (*stop_scan) (void);
        int (*get_visibility) (int *visibility);
@@ -270,7 +392,7 @@ typedef struct _wfd_oem_ops_s {
        int (*set_pin) (char *pin);
 //     int (*generate_pin) (char *pin);
        int (*get_supported_wps_mode) (int *wps_mode);
-       int (*create_group) (int persistent, int freq);
+       int (*create_group) (int persistent, int freq, const char *passphrase);
        int (*destroy_group) (const char *ifname);
        int (*invite) (unsigned char *peer_addr, wfd_oem_invite_param_s *param);
 
@@ -281,24 +403,36 @@ typedef struct _wfd_oem_ops_s {
        int (*set_dev_type) (int pri_dev_type, int sec_dev_type);
        int (*get_go_intent) (int *go_intent);
        int (*set_go_intent) (int go_intent);
+       int (*set_country) (char *ccode);
+//     int (*get_country) (char **ccode);
 
        int (*get_persistent_groups) (wfd_oem_persistent_group_s **groups, int *group_count);
        int (*remove_persistent_group) (char *ssid, unsigned char *bssid);
        int (*set_persistent_reconnect) (unsigned char *bssid, int reconnect);
 
-       int (*service_add) (wfd_oem_service_e type,char *data);
-       int (*service_del) (wfd_oem_service_e type,char *data);
-       int (*serv_disc_req) (unsigned char* MAC, wfd_oem_service_e type,char *data);
-       int (*serv_disc_cancel) (int identifier);
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       int (*start_service_discovery) (unsigned char mac_addr[6], int service_type);
+       int (*cancel_service_discovery) (unsigned char mac_addr[6], int service_type);
+
+       int (*serv_add) (wfd_oem_new_service_s *service);
+       int (*serv_del) (wfd_oem_new_service_s *service);
+       int (*serv_disc_start) (wfd_oem_new_service_s *service);
+       int (*serv_disc_stop) (int handle);
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       int (*miracast_init) (int enable);
+       int (*set_display) (wfd_oem_display_s *wifi_display);
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       int (*refresh) (void);
 
-       int (*init_wifi_display) (wfd_oem_display_e type, int port, int hdcp);
-       int (*deinit_wifi_display) (void);
 } wfd_oem_ops_s;
 
 int wfd_oem_init(wfd_oem_ops_s *ops, wfd_oem_event_cb event_callback, void *user_data);
 int wfd_oem_destroy(wfd_oem_ops_s *ops);
-int wfd_oem_activate(wfd_oem_ops_s *ops);
-int wfd_oem_deactivate(wfd_oem_ops_s *ops);
+int wfd_oem_activate(wfd_oem_ops_s *ops, int concurrent);
+int wfd_oem_deactivate(wfd_oem_ops_s *ops, int concurrent);
 int wfd_oem_start_scan(wfd_oem_ops_s *ops, wfd_oem_scan_param_s *param);
 int wfd_oem_stop_scan(wfd_oem_ops_s *ops);
 int wfd_oem_get_visibility(wfd_oem_ops_s *ops, int *visibility);
@@ -318,7 +452,7 @@ int wfd_oem_get_pin(wfd_oem_ops_s *ops, char *pin);
 int wfd_oem_set_pin(wfd_oem_ops_s *ops, char *pin);
 //int wfd_oem_generate_pin(wfd_oem_ops_s *ops, char *pin);
 int wfd_oem_get_supported_wps_mode(wfd_oem_ops_s *ops, int *wps_mode);
-int wfd_oem_create_group(wfd_oem_ops_s *ops, int persistent, int freq);
+int wfd_oem_create_group(wfd_oem_ops_s *ops, int persistent, int freq, const char *passphrase);
 int wfd_oem_destroy_group(wfd_oem_ops_s *ops, const char *ifname);
 int wfd_oem_invite(wfd_oem_ops_s *ops, unsigned char *peer_addr, wfd_oem_invite_param_s *param);
 
@@ -329,17 +463,27 @@ int wfd_oem_get_dev_type(wfd_oem_ops_s *ops, int *pri_dev_type, int *sec_dev_typ
 int wfd_oem_set_dev_type(wfd_oem_ops_s *ops, int priv_dev_type, int sec_dev_type);
 int wfd_oem_get_go_intent(wfd_oem_ops_s *ops, int *go_intent);
 int wfd_oem_set_go_intent(wfd_oem_ops_s *ops, int go_intent);
+int wfd_oem_set_country(wfd_oem_ops_s *ops, char *ccode);
 
 int wfd_oem_get_persistent_groups(wfd_oem_ops_s *ops, wfd_oem_persistent_group_s **groups, int *group_count);
 int wfd_oem_remove_persistent_group(wfd_oem_ops_s *ops, char *ssid, unsigned char *bssid);
 int wfd_oem_set_persistent_reconnect(wfd_oem_ops_s *ops, unsigned char *bssid, int reconnect);
 
-int wfd_oem_service_add(wfd_oem_ops_s *ops, wfd_oem_service_e type, char *data);
-int wfd_oem_service_del(wfd_oem_ops_s *ops, wfd_oem_service_e type, char *data);
-int wfd_oem_serv_disc_req(wfd_oem_ops_s *ops, unsigned char* MAC, wfd_oem_service_e type, char *data);
-int wfd_oem_serv_disc_cancel(wfd_oem_ops_s *ops, int identifier);
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+int wfd_oem_start_service_discovery(wfd_oem_ops_s *ops, unsigned char *peer_addr, int service_type);
+int wfd_oem_cancel_service_discovery(wfd_oem_ops_s *ops, unsigned char *peer_addr, int service_type);
+
+int wfd_oem_serv_add(wfd_oem_ops_s *ops, wfd_oem_new_service_s *service);
+int wfd_oem_serv_del(wfd_oem_ops_s *ops, wfd_oem_new_service_s *service);
+int wfd_oem_serv_disc_start(wfd_oem_ops_s *ops, wfd_oem_new_service_s *service);
+int wfd_oem_serv_disc_stop(wfd_oem_ops_s *ops, int handle);
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int wfd_oem_miracast_init(wfd_oem_ops_s *ops, int enable);
+int wfd_oem_set_display(wfd_oem_ops_s *ops, wfd_oem_display_s *wifi_display);
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
-int wfd_oem_init_wifi_display(wfd_oem_ops_s *ops, wfd_oem_display_e type, int port, int hdcp);
-int wfd_oem_deinit_wifi_display(wfd_oem_ops_s *ops);
+int wfd_oem_refresh(wfd_oem_ops_s *ops);
 
 #endif /* __WIFI_DIRECT_OEM_H__ */
diff --git a/packaging/wifi-direct-manager.changes b/packaging/wifi-direct-manager.changes
deleted file mode 100644 (file)
index d016a0d..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-Fri, 14 Mar 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.11)
-  * Modifiy Provision Discovery Request/Response Event
-  * Add automatic connection using device access list
-
-Fri, 07 Mar 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.10)
-  * Add support for managing device access list
-
-Thu, 13 Feb 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.9)
-  * Add Wifi Direct Display support 
-
-Fri, 24 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.8)
-  * Add Wifi Direct Service Discovery
-
-Tue, 15 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.7)
-  * Replace file execution method
-
-Tue, 15 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.6)
-  * Add cancel connection fuction to manager
-  * Add reject connection fuction to manager
-  * Add disconnect fuction to manager
-  * Add disconnect allfuction to manager
-
-Tue, 15 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.5)
-  * Change group function operation and parameter
-
-Tue, 15 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.4)
-  * Delete event notify function
-
-Tue, 15 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.3)
-  * Add wps_cancel operation
-  * Add session type and session management related operation
-
-Tue, 15 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.2)
-  * Add update peer by time operation
-
-Tue, 15 Jan 2014 Jiung Yu <jiung.yu@samaung.com> (1.0.1)
-  * Add interface name #define.
-  * Add new scan mode SCAN_MODE_NONE.
-  * Add channel information to peer
-  * Add initializing WPS mode and fix bugs
-  * clean the group when group formation is failed
-  * Sync some variable names with libwifi-direct
-
-Mon, 14 Oct 2013 Gibyoung Kim <lastkgb.kim@samaung.com> (1.0.0)
-  * Premitive type of some variables were changed.
-  * Some local device functions were added.
-  * New API support(get_req_wps_type, set_req_wps_type)
-  * Fix bugs
-
-Mon, 23 Sep 2013 Jiung Yu <jiung.yu@samsung.com> (0.8.7)
-  * If device is GO, manager has wpa passphrase to handle WIFI_DIRECT_CMD_GET_WPA
-
-
-Mon, 02 Sep 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.8.6)
-  * Fix bug of display PIN
-
-Mon, 02 Sep 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.8.5)
-  * Fix bug of join(Keypad)
-
-Wed, 28 Aug 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.8.4)
-  * Macro is added for interface name
-  * Multi-group support is removed
-
-Thu, 22 Aug 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.8.3)
-  * Reject connection process is modified
-
-Thu, 22 Aug 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.8.2)
-  * Check socket before send message to wpasupplicant
-
-Wed, 21 Aug 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.8.1)
-  * Invitation process is modified
-
-Wed, 21 Aug 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.8.0)
-  * GET_CONFIG, SET_CURRENT_WPS_MODE API is modified(internally)
-
-Mon, 29 Jul 2013 Jiung Yu <jiung.yu@samsung.com> (0.7.11)
-  * add feature get_persistent_group
-
-Mon, 29 Jul 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.7.10)
-  * Activation function modified
-  * Event(peer found, provision discovery) processing separated
-  * Persistent features implemented
-  * Scan function modified
-  * Fix IPC bugs
-  * Fix DHCP bugs
-  * Fix vconf bugs
-
-Thu, 11 Jul 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.7.2)
-  * Add scan parameter
-  * fix bugs of disconnection(jiung)
-  * Remove not used files
-
-Thu, 20 Jun 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.7.1)
-  * Fix bug
-  *   - Invited device fails provision discovery request
-  *   - Rejecting connection fails
-  *   - Incomming session not destroyed after 120sec
-  *   - IP leased event not occurred
-
-Fri, 14 Jun 2013 Gibyoung Kim <lastkgb.kim@samsung.com> (0.7.0)
-  * New wifi-direct-manager uploaded
-
-Changes before version 0.7.0
-  * SMACK manifest modified
-  * prevent issue fixed
-  * NOTICE file updated
-  * Boilerplate updated
-  * N_SE-36637(Incorrect popup displayed)
-  * Flora license file updated
-  * License file changed
-  * Fix prevent #38619
-  * Fix bug N_SE-34851(Keypad popup disappeared and connection stoped)
-  * Fix bug N_SE-32967(Status is not changed to 'Activated')
-  * Fix bug N_SE-30232(Retry connection during 120 secs on MT side)
-  * Fix bug N_SE-26723(Send rejection message)
-  * Fix bug N_SE-30232(Retry connection during 120 secs)
-  * Flush discovered peer data when starting new scan
-  * Flush discovered peer data when starting new scan
-  * to fix incorrect error return when no connected peer exist
-  * to fix PLM issue and prevent defect(private code sync)
-  * Remove prevent issue : Resource leak, Uninitialized pointer read
-  * Remove prevent issue : Improper use of negative value
-  * Fix resource leaks
-  * Remove unuseful code
-  * Fix bug of invitation behavior
-  * SMACK is corrected
-  * Fix bug(N_SE-23902)
-  * Fix Group Created event issue
-  * SMACK is applyed
-  * Fix bug(N_SE-23716)
-  * Fix bug(N_SE-23485)
-  * Package Update
-  * Fix bug(N_SE-22984)
-  * Fix bug(N_SE-21973)
-  * Add WPS PIN feature for GO
-  * Modify "Group create" bug when GO
-  * Fix bug(WPS PIN keypad not worked)
-  * Fix bug(WPS PIN Display not worked)
-  * DLog macro is changed
-  * Implementation of wifi_direct_get_device_name / wifi_direct_set_device_name
-  * fixed discovery problerm in case of lisen only mode.
-  * Implementation of persistent mode
-  * added timer for discovering.
old mode 100644 (file)
new mode 100755 (executable)
index 7879207..bb9367b
@@ -1,18 +1,25 @@
-Name:       wifi-direct-manager
-Summary:    Wi-Fi Direct manger
-Version:    1.0.12
-Release:    1
+Name:          wifi-direct-manager
+Summary:       Wi-Fi Direct manger
+Version:       1.2.81
+Release:       1
 Group:      Network & Connectivity/Wireless
 License:    Apache-2.0
-Source0:    %{name}-%{version}.tar.gz
-Requires(post): /usr/bin/vconftool
-BuildRequires:  pkgconfig(wifi-direct)
-BuildRequires:  pkgconfig(dbus-glib-1)
-BuildRequires:  pkgconfig(dlog)
-BuildRequires:  pkgconfig(vconf)
-BuildRequires:  pkgconfig(capi-appfw-application)
-BuildRequires:  cmake
-
+Source0:       %{name}-%{version}.tar.gz
+BuildRequires: pkgconfig(capi-network-wifi-direct)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(vconf)
+#BuildRequires:        pkgconfig(dbus-1)
+#BuildRequires:        pkgconfig(security-server)
+BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: cmake
+#BuildRequires:  model-build-features
+Requires:      net-tools
+#Requires:     sys-assert
+#Requires:     tizen-coreutils
+#Requires: toybox-symlinks-dhcpd
+#Requires: toybox-symlinks-dhcp
+Requires(post):        /usr/bin/vconftool
 
 %description
 Wi-Fi Direct manager
@@ -31,6 +38,10 @@ Wifi direct plugin for wpa supplicant
 
 %build
 
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+
 %ifarch %{arm}
 export ARCH=arm
 %else
@@ -43,19 +54,46 @@ export ARCH=i586
 
 %endif
 
-%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCHITECTURE=$ARCH
-#make %{?jobs:-j%jobs}
+cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCHITECTURE=$ARCH \
+%if 0%{?model_build_feature_wlan_concurrent_mode}
+       -DTIZEN_WLAN_CONCURRENT_ENABLE=1 \
+%endif
+%if ! 0%{?model_build_feature_network_tethering_disable}
+       -DTIZEN_TETHERING_ENABLE=0 \
+%endif
+%if "%{?tizen_profile_name}" == "wearable"
+        -DTIZEN_FEATURE_SERVICE_DISCOVERY=0 \
+        -DTIZEN_FEATURE_WIFI_DISPLAY=0 \
+%else
+%if "%{?tizen_profile_name}" == "mobile"
+        -DTIZEN_FEATURE_SERVICE_DISCOVERY=1 \
+        -DTIZEN_FEATURE_WIFI_DISPLAY=1 \
+        -DCTRL_IFACE_DBUS=1 \
+%else
+%if "%{?tizen_profile_name}" == "tv"
+       -DTIZEN_TV=1 \
+%endif
+%endif
+%endif
+-DTIZEN_FEATURE_SERVICE_DISCOVERY=1 \
+-DTIZEN_FEATURE_WIFI_DISPLAY=1 \
+-DCTRL_IFACE_DBUS=1 \
+       .
+
 make %{?_smp_mflags}
 
+
 %install
 rm -rf %{buildroot}
+
 %make_install
 #%__strip %{buildroot}%{_libdir}/wifi-direct-plugin-wpasupplicant.so
 #%__strip %{buildroot}%{_bindir}/wfd-manager
 
-mkdir -p %{buildroot}/usr/share/license
-cp %{_builddir}/%{buildsubdir}/LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
-cp %{_builddir}/%{buildsubdir}/LICENSE.APLv2 %{buildroot}/usr/share/license/wifi-direct-plugin-wpasupplicant
+#License
+mkdir -p %{buildroot}%{_datadir}/license
+cp %{_builddir}/%{buildsubdir}/LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name}
+cp %{_builddir}/%{buildsubdir}/LICENSE.APLv2 %{buildroot}%{_datadir}/license/wifi-direct-plugin-wpasupplicant
 
 %post
 chmod 644 /usr/etc/wifi-direct/dhcpd.p2p.conf
@@ -65,20 +103,39 @@ chmod 755 /usr/bin/wifi-direct-server.sh
 chmod 755 /usr/bin/wifi-direct-dhcp.sh
 chmod 755 /usr/sbin/p2p_supp.sh
 
-vconftool set -t int memory/wifi_direct/state 0 -u 5000 -i -f
-vconftool set -t int memory/private/wifi_direct_manager/dhcp_ip_lease 0 -i -f
-vconftool set -t string memory/private/wifi_direct_manager/dhcpc_server_ip 0.0.0.0 -i -f
+vconftool set -t int memory/wifi_direct/state 0 -u 5000 -i -s system::vconf_network
+vconftool set -t int memory/private/wifi_direct_manager/dhcp_ip_lease 0 -i -s wifi_direct_manager
+vconftool set -t string memory/private/wifi_direct_manager/dhcpc_server_ip 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname 0.0.0.0 -u 5000 -i
+
+if [ ! -d /var/lib/misc ]; then
+        mkdir -p /var/lib/misc
+fi
+
+touch /var/lib/misc/udhcpd.leases
+chmod 666 /var/lib/misc/udhcpd.leases
 
 %postun
 
+
 %files
-%manifest %{name}.manifest
+%manifest wifi-direct-manager.manifest
 %defattr(-,root,root,-)
 %{_bindir}/wfd-manager
 /usr/etc/wifi-direct/dhcpd.p2p.conf
 /usr/etc/wifi-direct/udhcp_script.non-autoip
+%if "%{?tizen_profile_name}" == "tv"
+/usr/etc/wifi-direct/p2p_supp_tv.conf
+/opt/etc/p2p_supp_tv.conf
+%else
 /usr/etc/wifi-direct/p2p_supp.conf
-/usr/etc/wifi-direct/access_list
+/opt/etc/p2p_supp.conf
+%endif
+/usr/etc/wifi-direct/ccode.conf
+/opt/etc/persistent-peer
 %{_bindir}/dhcpd-notify.sh
 %{_bindir}/wifi-direct-server.sh
 %{_bindir}/wifi-direct-dhcp.sh
@@ -88,11 +145,10 @@ vconftool set -t string memory/private/wifi_direct_manager/dhcpc_server_ip 0.0.0
 %attr(755,-,-) %{_bindir}/wifi-direct-dhcp.sh
 %attr(755,-,-) /usr/etc/wifi-direct/udhcp_script.non-autoip
 %attr(755,-,-) %{_sbindir}/p2p_supp.sh
-/usr/share/license/%{name}
+%attr(644,-,-) %{_datadir}/license/%{name}
 
 %files -n wifi-direct-plugin-wpasupplicant
 %manifest wifi-direct-plugin-wpasupplicant.manifest
 %defattr(-,root,root,-)
 %{_libdir}/wifi-direct-plugin-wpasupplicant.so
-/usr/share/license/wifi-direct-plugin-wpasupplicant
-
+%attr(644,-,-) %{_datadir}/license/wifi-direct-plugin-wpasupplicant
diff --git a/packaging/wifi-direct-manager.spec~ b/packaging/wifi-direct-manager.spec~
new file mode 100755 (executable)
index 0000000..7c88b15
--- /dev/null
@@ -0,0 +1,151 @@
+Name:          wifi-direct-manager
+Summary:       Wi-Fi Direct manger
+Version:       1.2.80
+Release:       1
+Group:      Network & Connectivity/Wireless
+License:    Apache-2.0
+Source0:       %{name}-%{version}.tar.gz
+BuildRequires: pkgconfig(capi-network-wifi-direct)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(vconf)
+#BuildRequires:        pkgconfig(dbus-1)
+#BuildRequires:        pkgconfig(security-server)
+BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: cmake
+#BuildRequires:  model-build-features
+Requires:      net-tools
+#Requires:     sys-assert
+#Requires:     tizen-coreutils
+#Requires: toybox-symlinks-dhcpd
+#Requires: toybox-symlinks-dhcp
+Requires(post):        /usr/bin/vconftool
+
+%description
+Wi-Fi Direct manager
+
+%package -n wifi-direct-plugin-wpasupplicant
+Summary:    Wifi direct plugin for wpa supplicant
+Group:      Network & Connectivity/Wireless
+Requires:   %{name} = %{version}-%{release}
+
+%description -n wifi-direct-plugin-wpasupplicant
+Wifi direct plugin for wpa supplicant
+
+
+%prep
+%setup -q
+
+%build
+
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+
+%ifarch %{arm}
+export ARCH=arm
+%else
+
+%if 0%{?simulator}
+export ARCH=emul
+%else
+export ARCH=i586
+%endif
+
+%endif
+
+cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCHITECTURE=$ARCH \
+%if 0%{?model_build_feature_wlan_concurrent_mode}
+       -DTIZEN_WLAN_CONCURRENT_ENABLE=1 \
+%endif
+%if ! 0%{?model_build_feature_network_tethering_disable}
+       -DTIZEN_TETHERING_ENABLE=0 \
+%endif
+%if "%{?tizen_profile_name}" == "wearable"
+        -DTIZEN_FEATURE_SERVICE_DISCOVERY=0 \
+        -DTIZEN_FEATURE_WIFI_DISPLAY=0 \
+%else
+%if "%{?tizen_profile_name}" == "mobile"
+        -DTIZEN_FEATURE_SERVICE_DISCOVERY=1 \
+        -DTIZEN_FEATURE_WIFI_DISPLAY=1 \
+        -DCTRL_IFACE_DBUS=1 \
+%else
+%if "%{?tizen_profile_name}" == "tv"
+       -DTIZEN_TV=1 \
+%endif
+%endif
+%endif
+       .
+
+make %{?_smp_mflags}
+
+
+%install
+rm -rf %{buildroot}
+
+%make_install
+#%__strip %{buildroot}%{_libdir}/wifi-direct-plugin-wpasupplicant.so
+#%__strip %{buildroot}%{_bindir}/wfd-manager
+
+#License
+mkdir -p %{buildroot}%{_datadir}/license
+cp %{_builddir}/%{buildsubdir}/LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name}
+cp %{_builddir}/%{buildsubdir}/LICENSE.APLv2 %{buildroot}%{_datadir}/license/wifi-direct-plugin-wpasupplicant
+
+%post
+chmod 644 /usr/etc/wifi-direct/dhcpd.p2p.conf
+chmod 755 /usr/bin/dhcpd-notify.sh
+chmod 755 /usr/etc/wifi-direct/udhcp_script.non-autoip
+chmod 755 /usr/bin/wifi-direct-server.sh
+chmod 755 /usr/bin/wifi-direct-dhcp.sh
+chmod 755 /usr/sbin/p2p_supp.sh
+
+vconftool set -t int memory/wifi_direct/state 0 -u 5000 -i -s system::vconf_network
+vconftool set -t int memory/private/wifi_direct_manager/dhcp_ip_lease 0 -i -s wifi_direct_manager
+vconftool set -t string memory/private/wifi_direct_manager/dhcpc_server_ip 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_local_ip 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_subnet_mask 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_gateway 0.0.0.0 -u 5000 -i
+vconftool set -t string memory/private/wifi_direct_manager/p2p_ifname 0.0.0.0 -u 5000 -i
+
+if [ ! -d /var/lib/misc ]; then
+        mkdir -p /var/lib/misc
+fi
+
+touch /var/lib/misc/dhcpd.leases
+chmod 666 /var/lib/misc/dhcpd.leases
+
+%postun
+
+
+%files
+%manifest wifi-direct-manager.manifest
+%defattr(-,root,root,-)
+%{_bindir}/wfd-manager
+/usr/etc/wifi-direct/dhcpd.p2p.conf
+/usr/etc/wifi-direct/udhcp_script.non-autoip
+%if "%{?tizen_profile_name}" == "tv"
+/usr/etc/wifi-direct/p2p_supp_tv.conf
+/opt/etc/p2p_supp_tv.conf
+%else
+/usr/etc/wifi-direct/p2p_supp.conf
+/opt/etc/p2p_supp.conf
+%endif
+/usr/etc/wifi-direct/ccode.conf
+/opt/etc/persistent-peer
+%{_bindir}/dhcpd-notify.sh
+%{_bindir}/wifi-direct-server.sh
+%{_bindir}/wifi-direct-dhcp.sh
+%{_sbindir}/p2p_supp.sh
+%attr(755,-,-) %{_bindir}/dhcpd-notify.sh
+%attr(755,-,-) %{_bindir}/wifi-direct-server.sh
+%attr(755,-,-) %{_bindir}/wifi-direct-dhcp.sh
+%attr(755,-,-) /usr/etc/wifi-direct/udhcp_script.non-autoip
+%attr(755,-,-) %{_sbindir}/p2p_supp.sh
+%attr(644,-,-) %{_datadir}/license/%{name}
+
+%files -n wifi-direct-plugin-wpasupplicant
+%manifest wifi-direct-plugin-wpasupplicant.manifest
+%defattr(-,root,root,-)
+%{_libdir}/wifi-direct-plugin-wpasupplicant.so
+%attr(644,-,-) %{_datadir}/license/wifi-direct-plugin-wpasupplicant
diff --git a/plugin/wpasupplicant/CMakeLists.txt b/plugin/wpasupplicant/CMakeLists.txt
deleted file mode 100755 (executable)
index 0d904ba..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(wifi-direct-plugin-wpasupplicant C)
-
-# Set required packages
-INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED wifi-direct glib-2.0 dlog)
-FOREACH(flag ${pkgs_CFLAGS})
-       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/oem)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Wall")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-SET(CMAKE_C_FLAGS_RELEASE "-O2")
-
-SET(LIBDIR ${LIB_INSTALL_DIR})
-
-ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
-ADD_DEFINITIONS("-DUSE_DLOG")
-
-#EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
-SET(ARCH "${ARCHITECTURE}")
-IF("${ARCH}" MATCHES "^arm.*|.*86.*")
-
-       SET(SRCS 
-               wfd-plugin-wpasupplicant.c
-               )
-
-       # library build
-       ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
-       TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
-       #SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.1.0)
-       SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME})
-
-       # install
-       INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${LIBDIR})
-
-ELSE()
-
-       SET(SRCS 
-               wfd-plugin-wpasupplicant-emul.c
-               )
-
-       # library build
-       ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
-       TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
-       #SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.1.0)
-       SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME})
-
-       # install
-       INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib)
-
-ENDIF()
diff --git a/plugin/wpasupplicant/ctrl_iface_dbus/CMakeLists.txt b/plugin/wpasupplicant/ctrl_iface_dbus/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..60b1077
--- /dev/null
@@ -0,0 +1,30 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(wifi-direct-plugin-wpasupplicant C)
+
+# Set required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED capi-network-wifi-direct glib-2.0 gio-2.0 dlog)
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/oem)
+INCLUDE_DIRECTORIES(SRCS include)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+SET(SRCS
+       wfd-plugin-wpasupplicant.c
+       dbus/wfd-plugin-supplicant-dbus.c
+       )
+
+# library build
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+#SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.1.0)
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME})
+
+# install
+INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib)
diff --git a/plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.c b/plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.c
new file mode 100755 (executable)
index 0000000..5ad4189
--- /dev/null
@@ -0,0 +1,180 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "wfd-plugin-log.h"
+#include "wfd-plugin-supplicant-dbus.h"
+
+int dbus_set_method_param(dbus_method_param_s *params, char *method_name,
+               char *object_path, GDBusConnection *connection)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       if(params == NULL || connection == NULL || object_path == NULL ||
+                method_name == NULL)
+       {
+               WDP_LOGE("Invalid Arguments!");
+               return -1;
+       }
+
+       params->connection = connection;
+       g_strlcpy(params->object_path, object_path, DBUS_OBJECT_PATH_MAX);
+       g_strlcpy(params->method_name, method_name, DBUS_METHOD_NAME_MAX);
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int dbus_method_call(dbus_method_param_s *params, char *interface_name,
+               dbus_result_function function, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GVariant *reply = NULL;
+       GError *error = NULL;
+
+       if(!params || !params->connection) {
+               WDP_LOGE("Invalid parameters");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       WDP_LOGD("method [%s]", params->method_name);
+
+       reply = g_dbus_connection_call_sync (
+                       params->connection,
+                       SUPPLICANT_SERVICE, /* bus name */
+                       params->object_path, /* object path */
+                       interface_name, /* interface name */
+                       params->method_name, /* method name */
+                       params->params, /* GVariant *params */
+                       NULL, /* reply_type */
+                       G_DBUS_CALL_FLAGS_NONE, /* flags */
+                       SUPPLICANT_TIMEOUT , /* timeout */
+                       NULL, /* cancellable */
+                       &error); /* error */
+
+       if(error != NULL) {
+               WDP_LOGE("Error! Failed to call method: [%s]",error->message);
+               g_error_free(error);
+               if(reply)
+                       g_variant_unref(reply);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if(reply != NULL) {
+               WDP_LOGE("reply [%s]", g_variant_print(reply,TRUE));
+               if(function)
+                       function(reply, user_data);
+               g_variant_unref(reply);
+       } else {
+               WDP_LOGD("reply is NULL");
+       }
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+void dbus_property_foreach(GVariantIter *iter,
+               dbus_property_function function, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       gchar *key = NULL;
+       GVariant *value = NULL;
+
+       while(g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+
+               if (key) {
+                       if (strcmp(key, "Properties") == 0) {
+                               WDP_LOGE("Properties");
+                               GVariantIter *iter_raw = NULL;
+                               g_variant_get(value, "a{sv}", &iter_raw);
+                               dbus_property_foreach(iter_raw, function, user_data);
+                       } else if (function) {
+                               WDP_LOGE("function");
+                               function(key, value, user_data);
+                       }
+                       WDP_LOGE("do nothing");
+               }
+       }
+       if(function)
+               function(NULL, NULL, user_data);
+       __WDP_LOG_FUNC_EXIT__;
+       return;
+}
+
+int dbus_property_get_all(const char *path, GDBusConnection *connection,
+                       const char *interface, dbus_property_function function,
+                       void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GVariant *param = NULL;
+       GVariant *reply = NULL;
+       GError *error = NULL;
+       GVariantIter *iter = NULL;
+
+       if (!connection) {
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if (!path || !interface) {
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       param = g_variant_new("(s)", interface);
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       reply = g_dbus_connection_call_sync (
+                       connection,
+                       SUPPLICANT_SERVICE, /* bus name */
+                       path, /* object path */
+                       DBUS_PROPERTIES_INTERFACE, /* interface name */
+                       DBUS_PROPERTIES_METHOD_GETALL, /* method name */
+                       param, /* GVariant *params */
+                       NULL, /* reply_type */
+                       G_DBUS_CALL_FLAGS_NONE, /* flags */
+                       SUPPLICANT_TIMEOUT , /* timeout */
+                       NULL, /* cancellable */
+                       &error); /* error */
+
+       if(error != NULL) {
+               WDP_LOGE("Error! Failed to get properties: [%s]",       error->message);
+               g_error_free(error);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if(reply != NULL) {
+               g_variant_get(reply, "(a{sv})", &iter);
+
+               if(iter != NULL){
+
+                       gchar *key = NULL;
+                       GVariant *value = NULL;
+
+                       while(g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+
+                               if(strcmp(key, "Properties") == 0){
+                                       GVariantIter *iter_raw = NULL;
+                                       g_variant_get(value, "a{sv}", &iter_raw);
+                                       dbus_property_foreach(iter_raw, function, user_data);
+                               } else {
+                                       function(key, value, user_data);
+                               }
+                       }
+                       g_variant_iter_free(iter);
+               }
+               g_variant_unref(reply);
+       } else{
+               WDP_LOGE("No properties");
+       }
+       if(function)
+               function(NULL, NULL, user_data);
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
diff --git a/plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.h b/plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.h
new file mode 100644 (file)
index 0000000..32d2607
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef WFD_PLUGIN_SUPPLICANT_DBUS_H
+#define WFD_PLUGIN_SUPPLICANT_DBUS_H
+
+
+#define COMPACT_MACSTR "%02x%02x%02x%02x%02x%02x"
+
+#define SUPPLICANT_TIMEOUT (10 * 1000)
+
+#define SUPPLICANT_SERVICE "fi.w1.wpa_supplicant1"
+#define SUPPLICANT_INTERFACE "fi.w1.wpa_supplicant1"
+#define SUPPLICANT_PATH "/fi/w1/wpa_supplicant1"
+
+#define SUPPLICANT_IFACE SUPPLICANT_INTERFACE ".Interface"
+#define SUPPLICANT_NETWORK SUPPLICANT_INTERFACE ".Network"
+#define SUPPLICNAT_WPS SUPPLICANT_IFACE ".WPS"
+#define SUPPLICNAT_P2PDEVICE SUPPLICANT_IFACE ".P2PDevice"
+#define SUPPLICANT_P2P_PEER SUPPLICANT_INTERFACE ".Peer"
+#define SUPPLICANT_P2P_GROUP SUPPLICANT_INTERFACE ".Group"
+#define SUPPLICANT_P2P_PERSISTENTGROUP SUPPLICANT_INTERFACE ".PersistentGroup"
+
+#define SUPPLICANT_METHOD_GETINTERFACE "GetInterface"
+#define SUPPLICANT_METHOD_REMOVEINTERFACE "RemoveInterface"
+#define SUPPLICANT_METHOD_CREATEINTERFACE "CreateInterface"
+
+#define DBUS_METHOD_NAME_MAX 32
+#define DBUS_OBJECT_PATH_MAX 150
+#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
+#define DBUS_PROPERTIES_METHOD_GET "Get"
+#define DBUS_PROPERTIES_METHOD_SET "Set"
+#define DBUS_PROPERTIES_METHOD_GETALL "GetAll"
+
+#define SIGNAL_PROPERTIES_CHANGED "PropertiesChanged"
+
+#define CHECK_KEY_VALUE(key, value)\
+       do {\
+               if (key)\
+                       WDP_LOGD("Key : [%s]", key);\
+               if (value) {\
+                       WDP_LOGD("value [%s]", g_variant_print(value,TRUE));\
+                       WDP_LOGD("value type [%s]", g_variant_get_type_string(value));\
+               }\
+       } while (0)
+
+#define DEBUG_SIGNAL(sender_name, object_path, interface_name, signal_name, parameters)\
+       do {\
+               WDP_LOGD("signal sender name [%s]", sender_name);\
+               WDP_LOGD("signal object path [%s]", object_path);\
+               WDP_LOGD("signal interface name [%s]", interface_name);\
+               WDP_LOGD("signal signal name [%s]", signal_name);\
+               WDP_LOGD("signal params [%s]", g_variant_print(parameters, TRUE));\
+               WDP_LOGD("signal params type [%s]", g_variant_get_type_string(parameters));\
+       } while (0)
+
+typedef void (*dbus_result_function) (GVariant *value, void *user_data);
+
+typedef void (*dbus_property_function) (const char *key,
+               GVariant *value, void *user_data);
+
+typedef struct {
+       GDBusConnection *connection;
+       char object_path[DBUS_OBJECT_PATH_MAX];
+       char method_name[DBUS_METHOD_NAME_MAX];
+       GVariant *params;
+}dbus_method_param_s;
+
+int dbus_set_method_param(dbus_method_param_s *params, char *method_name,
+               char *object_path, GDBusConnection *connection);
+
+int dbus_method_call(dbus_method_param_s *params, char *interface_name,
+               dbus_result_function function, void *user_data);
+
+int dbus_property_get_all(const char *path, GDBusConnection *connection,
+               const char *interface, dbus_property_function function,
+               void *user_data);
+
+void dbus_property_foreach(GVariantIter *iter,
+               dbus_property_function function, void *user_data);
+
+#endif //WFD_PLUGIN_SUPPLICANT_DBUS_H
diff --git a/plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-log.h b/plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-log.h
new file mode 100644 (file)
index 0000000..a515aa5
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * This file declares wifi direct wpasupplicant plugin functions and structures.
+ *
+ * @file               wfd-plugin-log.h
+ * @author     Gibyoung Kim (lastkgb.kim@samsung.com)
+ * @version    0.7
+ */
+
+#ifndef __WFD_PLUGIN_LOG_H_
+#define __WFD_PLUGIN_LOG_H_
+
+#ifdef USE_DLOG
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "WIFI_DIRECT_PLUGIN"
+
+#define WDP_LOGV(format, args...) LOGV(format, ##args)
+#define WDP_LOGD(format, args...) LOGD(format, ##args)
+#define WDP_LOGI(format, args...) LOGI(format, ##args)
+#define WDP_LOGW(format, args...) LOGW(format, ##args)
+#define WDP_LOGE(format, args...) LOGE(format, ##args)
+#define WDP_LOGF(format, args...) LOGF(format, ##args)
+
+#define __WDP_LOG_FUNC_ENTER__ LOGD("Enter")
+#define __WDP_LOG_FUNC_EXIT__ LOGD("Quit")
+
+#define WDP_SECLOGI(format, args...) SECURE_LOG(LOG_INFO, LOG_TAG, format, ##args)
+#define WDP_SECLOGD(format, args...) SECURE_LOG(LOG_DEBUG, LOG_TAG, format, ##args)
+
+#else /* USE_DLOG */
+
+#define WDP_LOGV(format, args...)
+#define WDP_LOGD(format, args...)
+#define WDP_LOGI(format, args...)
+#define WDP_LOGW(format, args...)
+#define WDP_LOGE(format, args...)
+#define WDP_LOGF(format, args...)
+
+#define __WDP_LOG_FUNC_ENTER__
+#define __WDP_LOG_FUNC_EXIT__
+
+#define WDP_SECLOGI(format, args...)
+#define WDP_SECLOGD(format, args...)
+
+#endif /* USE_DLOG */
+
+#endif /* __WFD_PLUGIN_LOG_H_ */
diff --git a/plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-wpasupplicant.h b/plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-wpasupplicant.h
new file mode 100755 (executable)
index 0000000..7d610ef
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * This file declares wifi direct wpasupplicant plugin functions and structures.
+ *
+ * @file               wfd-plugin-wpasupplicant.h
+ * @author     Gibyoung Kim (lastkgb.kim@samsung.com)
+ * @version    0.7
+ */
+
+#ifndef __WFD_PLUGIN_WPASUPPLICANT_H__
+#define __WFD_PLUGIN_WPASUPPLICANT_H__
+
+
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+#define IP2STR(a) (a)[0], (a)[1], (a)[2], (a)[3]
+#define IPSTR "%d.%d.%d.%d"
+#define MAC2SECSTR(a) (a)[0], (a)[4], (a)[5]
+#define MACSECSTR "%02x:%02x:%02x"
+#define IP2SECSTR(a) (a)[0], (a)[3]
+#define IPSECSTR "%d..%d"
+#define OBJECT_PATH_MAX 150
+
+#if !defined TIZEN_TV
+#define DEFAULT_MAC_FILE_PATH "/opt/etc/.mac.info"
+#else
+#define DEFAULT_MAC_FILE_PATH "/sys/class/net/p2p0/address"
+#endif
+#define CONF_FILE_PATH "/usr/etc/wifi-direct/p2p_supp.conf"
+
+#if defined TIZEN_TV
+/*For TIZEN TV Platform*/
+#define COMMON_IFACE_NAME "p2p0"
+#define GROUP_IFACE_NAME "p2p0"
+#define GROUP_IFACE_PREFIX "p2p"
+#else /*TIZEN_TV*/
+#define COMMON_IFACE_NAME "wlan0"
+#define GROUP_IFACE_NAME "p2p-wlan0-0"
+#define GROUP_IFACE_PREFIX "p2p-wlan0-"
+#endif /*TIZEN_TV*/
+
+#define WS_POLL_TIMEOUT 5000
+#define WS_CONN_RETRY_COUNT 10
+#define WS_PINSTR_LEN 8
+#define WS_SSID_LEN 32
+#define WS_MACSTR_LEN 18
+#define WS_MACADDR_LEN 6
+#define WS_MAX_PERSISTENT_COUNT 20
+
+#define WS_DEVTYPE_LEN 8
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+#define SERV_DISC_REQ_ALL "02000001"
+#define SERV_DISC_REQ_BONJOUR "02000101"
+#define SERV_DISC_REQ_UPNP "02000201"
+
+#define SERVICE_TYPE_LEN 8
+#define WS_MAX_SERVICE_LEN 1024
+#define SERVICE_QUERY_LEN 4
+
+#define SERVICE_TYPE_BT_ADDR "0000f00b"
+#define SERVICE_TYPE_ALL "0000f00c"
+#define SERVICE_TYPE_CONTACT_INFO "0000f00d"
+#define SERV_BROADCAST_ADDRESS "00:00:00:00:00:00"
+
+#define WS_QTYPE_PTR 0x0c
+#define WS_QTYPE_TXT 0x10
+#define WS_TCP_PTR_HEX "\xc0\x0c"
+#define WS_UDP_PTR_HEX "\xc0\x1e"
+#define WS_PTR_TYPE_HEX "\x00\x0c\x01"
+#define WS_TXT_TYPE_HEX "\x00\x10\x01"
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+/* Config Method bitmap */
+#define WS_CONFIG_METHOD_DISPLAY 0x0008
+#define WS_CONFIG_METHOD_PUSHBUTTON 0x0080
+#define WS_CONFIG_METHOD_KEYPAD 0x0100
+
+#define WS_DBUS_STR_PBC "pbc"
+#define WS_DBUS_STR_DISPLAY "display"
+#define WS_DBUS_STR_KEYPAD "keypad"
+#define WS_DBUS_STR_JOIN "join"
+#define WS_DBUS_STR_AUTH "auth"
+#define WS_DBUS_STR_PERSISTENT "persistent"
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+#define WS_WFD_INFO_PRIMARY_SINK 0x01
+#define WS_WFD_INFO_SECONDARY_SINK 0x02
+#define WS_WFD_INFO_AVAILABLITY 0x10
+#define WS_WFD_INFO_WSD_SUPPORT 0x40
+#define WS_WFD_INFO_TDLS_SUPPORT 0x80
+#define WS_WFD_INFO_HDCP_SUPPORT 0x100
+#define WS_WFD_INFO_SYNC_SUPPORT 0x200
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+typedef enum {
+       WS_IFTYPE_NONE,
+       WS_IFTYPE_STATION,
+       WS_IFTYPE_GROUP,
+} ws_iftype_e;
+
+typedef enum {
+       WS_PRI_DEV_TYPE_NONE,
+       WS_PRI_DEV_TYPE_COMPUTER = 1,
+       WS_PRI_DEV_TYPE_INPUT_DEVICE = 2,
+       WS_PRI_DEV_TYPE_PRINTER = 3,
+       WS_PRI_DEV_TYPE_CAMERA = 4,
+       WS_PRI_DEV_TYPE_STORAGE = 5,
+       WS_PRI_DEV_TYPE_NETWORK_INFRA = 6,
+       WS_PRI_DEV_TYPE_DISPLAY = 7,
+       WS_PRI_DEV_TYPE_MULTIMEDIA_DEVICE = 8,
+       WS_PRI_DEV_TYPE_GAME_DEVICE = 9,
+       WS_PRI_DEV_TYPE_TELEPHONE = 10,
+       WS_PRI_DEV_TYPE_AUDIO = 11,
+       WS_PRI_DEV_TYPE_OTHER = 255,
+} ws_device_type_e;
+
+typedef enum {
+       /* The Service Discovery field shall be set to 1
+        * if the P2P Device supports Service Discovery,
+        * and is set to 0 otherwise. */
+       WS_DEVICE_CAP_SERVICE_DISCOVERY = 0x01,
+
+       /* Within a P2P Group Info attribute and a (Re)association
+        * request frame the P2P Client Discoverability field shall be set to 1
+        * when the P2P Device supports P2P Client Discoverability,
+        * and is set to 0 otherwise.
+        * This field shall be reserved and set to 0 in all other frames or uses. */
+       WS_DEVICE_CAP_CLIENT_DISCOVERABILITY = 0x02,
+
+       /* The Concurrent Operation field shall be set to 1
+        * when the P2P Device supports Concurrent Operation with WLAN,
+        * and is set to 0 otherwise. */
+       WS_DEVICE_CAP_CONCURRENT_OPERATION = 0x04,
+
+       /* The P2P Infrastructure Managed field shall be set to 1
+        * when the P2P interface of the P2P Device is capable of being
+        * managed by the WLAN (infrastructure network) based on
+        * P2P Coexistence Parameters, and set to 0 otherwise. */
+       WS_DEVICE_CAP_INFRASTRUCTURE_MANAGED = 0x08,
+
+       /* The P2P Device Limit field shall be set to 1
+        * when the P2P Device is unable to participate in additional P2P Groups,
+        * and set to 0 otherwise. */
+       WS_DEVICE_CAP_DEVICE_LIMIT = 0x10,
+
+       /* The P2P Invitation Procedure field shall be set to 1
+        * if the P2P Device is capable of processing P2P Invitation Procedure
+        * signaling, and set to 0 otherwise. */
+       WS_DEVICE_CAP_INVITATION_PROCEDURE = 0x20,
+} ws_device_cap_flag_e;
+
+typedef enum {
+       /* The P2P Group Owner field shall be set to 1
+        * when the P2P Device is operating as a Group Owner,
+        * and set to 0 otherwise. */
+       WS_GROUP_CAP_GROUP_OWNER = 0x01,
+
+       /* The Persistent P2P Group field shall be set to 1
+        * when the P2P Device is hosting, or intends to host,
+        * a persistent P2P Group, and set to 0 otherwise. */
+       WS_GROUP_CAP_PERSISTENT_GROUP = 0x02,
+
+       /* The P2P Group Limit field shall be set to 1
+        * when the P2P Group Owner is unable to add additional Clients
+        * to its P2P Group, and set to 0 otherwise. */
+       WS_GROUP_CAP_GROUP_LIMIT = 0x04,
+
+       /* The Intra-BSS Distribution field shall be set to 1
+        * if the P2P Device is hosting, or intends to host,
+        * a P2P Group that provides a data distribution service
+        * between Clients in the P2P Group.
+        * The Intra-BSS Distribution field shall be set to 0,
+        * if the P2P Device is not a P2P Group Owner,
+        * or is not providing such a data distribution service. */
+       WS_GROUP_CAP_INTRA_BSS_DISTRIB = 0x08,
+
+       /* The Cross Connection field shall be set to 1
+        * if the P2P Device is hosting, or intends to host,
+        * a P2P Group that provides cross connection
+        * between the P2P Group and a WLAN.
+        * The Cross Connection field shall be set to 0
+        * if the P2P Device is not a P2P Group Owner,
+        * or is not providing a cross connection service. */
+       WS_GROUP_CAP_CROSS_CONNECTION = 0x10,
+
+       /* The Persistent Reconnect field shall be set to 1
+        * when the P2P Device is hosting, or intends to host,
+        * a persistent P2P Group that allows reconnection
+        * without user intervention, and set to 0 otherwise. */
+       WS_GROUP_CAP_PERSISTENT_RECONN = 0x20,
+
+       /* The Group Formation field shall be set to 1
+        * when the P2P Device is operating as a Group Owner
+        * in the Provisioning phase of Group Formation,
+        * and set to 0 otherwise. */
+       WS_GROUP_CAP_GROUP_FORMATION = 0x40,
+} ws_group_cap_flag_e;
+
+typedef enum {
+       /* If the Device Password ID is Default, the Enrollee should use
+        * its PIN password (from the label or display). This password may
+        * correspond to the label, display, or a user-defined password
+        * that has been configured to replace the original device password. */
+       WS_DEV_PASSWD_ID_DEFAULT = 0x0000,
+
+       /* User-specified indicates that the user has overridden the password
+        * with a manually selected value. */
+       WS_DEV_PASSWD_ID_USER_SPECIFIED = 0x0001,
+
+       /* Machine-specified indicates that the original PIN password has been
+        * overridden by a strong, machine-generated device password value. */
+       WS_DEV_PASSWD_ID_MACHINE_SPECIFIED = 0x0002,
+
+       /* The Rekey value indicates that the device's 256-bit rekeying
+        * password will be used. */
+       WS_DEV_PASSWD_ID_REKEY = 0x0003,
+
+       /* The PushButton value indicates that the PIN is the all-zero value
+        * reserved for the Push Button Configuration method. */
+       WS_DEV_PASSWD_ID_PUSH_BUTTON = 0x0004,
+
+       /* The Registrar-specified value indicates a PIN that has been
+        * obtained from the Registrar (via a display or other out-of-band
+        * method). This value may be further augmented with the optional
+        * "Identity" attribute in M1. */
+       WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED = 0x0005,  // ENTER-PIN
+} ws_dev_passwd_id_e;
+
+typedef enum {
+       WPS_ERROR_NONE,
+
+       WPS_ERROR_OOBINFO_READ_FAIL,
+       WPS_ERROR_DECRYPTION_FAIL,
+       WPS_ERROR_2G_NOT_SUPPORTED,
+       WPS_ERROR_5G_NOT_SUPPORTED,
+       WPS_ERROR_WEAK_SIGNAL,
+       WPS_ERROR_NET_AUTH_FAIL,
+       WPS_ERROR_NET_ASSOC_FAIL,
+       WPS_ERROR_NO_DHCP_RESPONSE,
+       WPS_ERROR_DHCP_CONFIG_FAIL,
+       WPS_ERROR_IP_CONFLICT,
+
+       WPS_ERROR_REGISTRAT_CONN_FAIL,
+       WPS_ERROR_PBC_SESSION_OVERLAP,
+       WPS_ERROR_ROGUE_ACTIVITY,
+       WPS_ERROR_DEVICE_BUSY,
+       WPS_ERROR_SETUP_LOCKED,
+       WPS_ERROR_MESSAGE_TIMEOUT,
+       WPS_ERROR_SESSION_TIMEOUT,
+       WPS_ERROR_PASSWORD_MISMATCH,
+} ws_wps_error_e;
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+typedef enum {
+       WFD_SUBELM_ID_DEV_INFO,
+       WFD_SUBELM_ID_ASSOC_BSSID,
+       WFD_SUBELM_ID_AUDIO_FORMAT,
+       WFD_SUBELM_ID_VIDEO_FORMAT,
+       WFD_SUBELM_ID_3D_FORMAT,
+       WFD_SUBELM_ID_CONTENT_PROTECTION,
+
+       WFD_SUBELM_ID_CUPLED_SYNC_INFO,
+       WFD_SUBELM_ID_EXT_CAPAB,
+       WFD_SUBELM_ID_LOCAL_IP,
+       WFD_SUBELM_ID_SESSION_INFO,
+       WFD_SUBELM_ID_ALT_MAC,
+} ws_wfd_subelm_id_e;
+#define WFD_SUBELEM_LEN_DEV_INFO 6
+#define WFD_SUBELM_LEN_ASSOC_BSSID 6
+#define WFD_SUBELM_LEN_CUPLED_SYNC_INFO 7
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+typedef enum {
+       WFD_OEM_NETFLAG_CURRENT,
+       WFD_OEM_NETFLAG_DISABLED,
+       WFD_OEM_NETFLAG_TEMP_DISABLED,
+       WFD_OEM_NETFLAG_P2P_PERSISTENT,
+} ws_netowrk_flag_e;
+
+typedef struct {
+       int network_id;
+       char ssid[OEM_DEV_NAME_LEN+1];
+       unsigned char bssid[OEM_MACADDR_LEN];
+       char persistent_path[OBJECT_PATH_MAX];
+       int total;
+} ws_network_info_s;
+
+typedef struct {
+       int initialized;        // check whether plugin is initialized or not. block init function if initialized
+       int activated;
+       int concurrent;
+
+       GDBusConnection *g_dbus;
+       guint supp_sub_id;
+       char iface_path[150];
+       char group_iface_path[150];
+       guint p2pdevice_sub_id;
+       guint group_sub_id;
+       guint group_iface_sub_id;
+       unsigned char local_dev_addr[WS_MACADDR_LEN];
+       wfd_oem_event_cb callback;
+       void *user_data;
+} ws_dbus_plugin_data_s;
+
+int ws_init(wfd_oem_event_cb callback, void *user_data);
+int ws_deinit();
+int ws_activate(int concurrent);
+int ws_deactivate(int concurrent);
+int ws_start_scan(wfd_oem_scan_param_s *param);
+int ws_restart_scan(int freq);
+int ws_stop_scan();
+int ws_get_visibility(int *visibility);
+int ws_set_visibility(int visibility);
+int ws_get_scan_result(GList **peers, int *peer_count);
+int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer);
+int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join);
+int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param);
+int ws_disconnect(unsigned char *peer_addr);
+int ws_reject_connection(unsigned char *peer_addr);
+int ws_cancel_connection(unsigned char *peer_addr);
+int ws_get_connected_peers(GList **peers, int *peer_count);
+int ws_get_pin(char *pin);
+int ws_set_pin(char *pin);
+int ws_get_supported_wps_mode();
+int ws_create_group(int persistent, int freq, const char *passphrase);
+int ws_destroy_group(const char *ifname);
+int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param);
+int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin);
+int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin);
+int ws_wps_cancel();
+int ws_get_dev_name(char *dev_name);
+int ws_set_dev_name(char *dev_name);
+int ws_get_dev_mac(char *dev_mac);
+int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type);
+int ws_set_dev_type(int pri_dev_type, int sec_dev_type);
+int ws_get_go_intent(int *go_intent);
+int ws_set_go_intent(int go_intent);
+int ws_set_country(char *ccode);
+
+int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count);
+int ws_remove_persistent_group(char *ssid, unsigned char *bssid);
+int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect);
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+int ws_start_service_discovery(unsigned char *mac_addr, int service_type);
+int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type);
+
+int ws_serv_add(wfd_oem_new_service_s *service);
+int ws_serv_del(wfd_oem_new_service_s *service);
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int ws_miracast_init(int enable);
+int ws_set_display(wfd_oem_display_s *wifi_display);
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+int ws_refresh();
+
+#endif /* __WFD_PLUGIN_WPASUPPLICANT_H__ */
diff --git a/plugin/wpasupplicant/ctrl_iface_dbus/wfd-plugin-wpasupplicant.c b/plugin/wpasupplicant/ctrl_iface_dbus/wfd-plugin-wpasupplicant.c
new file mode 100755 (executable)
index 0000000..8bfff65
--- /dev/null
@@ -0,0 +1,4304 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * This file implements wifi direct wpasupplicant dbus plugin functions.
+ *
+ * @file               wfd-plugin-dbus-wpasupplicant.c
+ * @author     Jiung Yu (jiung.yu@samsung.com)
+ * @version    0.7
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#define _GNU_SOURCE
+#include <poll.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "wifi-direct-oem.h"
+#include "wfd-plugin-log.h"
+#include "wfd-plugin-wpasupplicant.h"
+#include "dbus/wfd-plugin-supplicant-dbus.h"
+
+#define NETCONFIG_SERVICE "net.netconfig"
+#define NETCONFIG_WIFI_INTERFACE "net.netconfig.wifi"
+#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
+
+#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
+
+static wfd_oem_ops_s supplicant_ops = {
+       .init = ws_init,
+       .deinit = ws_deinit,
+       .activate = ws_activate,
+       .deactivate = ws_deactivate,
+
+       .start_scan = ws_start_scan,
+       .stop_scan = ws_stop_scan,
+       .get_visibility = ws_get_visibility,
+       .set_visibility = ws_set_visibility,
+       .get_scan_result = ws_get_scan_result,
+       .get_peer_info = ws_get_peer_info,
+
+       .prov_disc_req = ws_prov_disc_req,
+
+       .connect = ws_connect,
+       .disconnect = ws_disconnect,
+       .reject_connection = ws_reject_connection,
+       .cancel_connection = ws_cancel_connection,
+
+       .get_connected_peers = ws_get_connected_peers,
+       .get_pin = ws_get_pin,
+       .set_pin = ws_set_pin,
+       .get_supported_wps_mode = ws_get_supported_wps_mode,
+
+       .create_group = ws_create_group,
+       .destroy_group = ws_destroy_group,
+       .invite = ws_invite,
+       .wps_start = ws_wps_start,
+       .enrollee_start = ws_enrollee_start,
+       .wps_cancel = ws_wps_cancel,
+
+       .get_dev_name = ws_get_dev_name,
+       .set_dev_name = ws_set_dev_name,
+       .get_dev_mac = ws_get_dev_mac,
+       .get_dev_type = ws_get_dev_type,
+       .set_dev_type = ws_set_dev_type,
+       .get_go_intent = ws_get_go_intent,
+       .set_go_intent = ws_set_go_intent,
+       .set_country = ws_set_country,
+       .get_persistent_groups = ws_get_persistent_groups,
+       .remove_persistent_group = ws_remove_persistent_group,
+       .set_persistent_reconnect = ws_set_persistent_reconnect,
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       .start_service_discovery = ws_start_service_discovery,
+       .cancel_service_discovery = ws_cancel_service_discovery,
+
+       .serv_add = ws_serv_add,
+       .serv_del = ws_serv_del,
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       .miracast_init = ws_miracast_init,
+       .set_display = ws_set_display,
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       .refresh = ws_refresh,
+
+       };
+
+static ws_dbus_plugin_data_s *g_pd;
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+static GList *service_list;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+static void _supplicant_signal_cb(GDBusConnection *connection,
+               const gchar *sender, const gchar *object_path, const gchar *interface,
+               const gchar *signal, GVariant *parameters, gpointer user_data);
+
+static void _p2pdevice_signal_cb(GDBusConnection *connection,
+               const gchar *sender, const gchar *object_path, const gchar *interface,
+               const gchar *signal, GVariant *parameters, gpointer user_data);
+
+static void _group_signal_cb(GDBusConnection *connection,
+               const gchar *sender, const gchar *object_path, const gchar *interface,
+               const gchar *signal, GVariant *parameters, gpointer user_data);
+
+static int __ws_txt_to_mac(unsigned char *txt, unsigned char *mac)
+{
+       int i = 0;
+
+       if (!txt || !mac) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       for (;;) {
+               mac[i++] = (char) strtoul((char *)txt, (char **)&txt, 16);
+               if (!*txt++ || i == 6)
+                       break;
+       }
+
+       if (i != WS_MACADDR_LEN)
+               return -1;
+
+       return 0;
+}
+
+static int __ws_mac_compact_to_normal(char *compact, unsigned char *mac)
+{
+       g_snprintf((char *)mac, OEM_MACSTR_LEN, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
+                       compact[0], compact[1], compact[2], compact[3],
+                       compact[4], compact[5], compact[6], compact[7],
+                       compact[8], compact[9], compact[10], compact[11]);
+       return 0;
+}
+
+static char *__ws_wps_to_txt(int wps_mode)
+{
+       switch (wps_mode) {
+       case WFD_OEM_WPS_MODE_PBC:
+               return WS_DBUS_STR_PBC;
+               break;
+       case WFD_OEM_WPS_MODE_DISPLAY:
+               return WS_DBUS_STR_DISPLAY;
+               break;
+       case WFD_OEM_WPS_MODE_KEYPAD:
+               return WS_DBUS_STR_KEYPAD;
+               break;
+       default:
+               return "";
+               break;
+       }
+}
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+static int __ws_byte_to_hex(char *buf, int buf_size, unsigned char *data, int data_len)
+{
+       int i;
+       char *pos = buf;
+       char *end = buf + buf_size;
+       int ret;
+       if (buf_size == 0)
+               return 0;
+       for (i = 0; i < data_len; i++) {
+               ret = snprintf(pos, end - pos, "%02x", data[i]);
+               if (ret < 0 || ret >= end - pos) {
+                       end[-1] = '\0';
+                       return pos - buf;
+               }
+               pos += ret;
+       }
+       end[-1] = '\0';
+       return pos - buf;
+}
+
+static int __ws_hex_to_num(char *src, int len)
+{
+       char *temp = NULL;
+       int num = 0;
+
+       if (!src || len < 0) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       temp = (char*) g_try_malloc0(len+1);
+       if (!temp) {
+               WDP_LOGE("Failed to allocate memory");
+               return -1;
+       }
+
+       memcpy(temp, src, len);
+       num = strtoul(temp, NULL, 16);
+       g_free(temp);
+
+       return num;
+}
+
+static int __ws_hex_to_txt(char *src, int length, char *dest)
+{
+       // TODO: check it is good to change dest parameter as double pointer.
+       // It could be better to allocate memory for dest parameter here.
+       char *temp = NULL;
+       char *ptr = NULL;
+       int len = 0;
+       int i = 0;
+
+       if (!src || length < 0 || !dest) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       // TODO: flush destination memory
+
+       ptr = src;
+       temp = dest;
+
+       if (!length)
+               len = strlen(src);
+       else
+               len = length;
+
+       for (i=0; i<len/2 && *ptr!=0; i++) {
+               temp[i] = (char) __ws_hex_to_num(ptr, 2);
+               if (temp[i] < 0) {
+                       WDP_LOGE("Failed to convert hexa string to num");
+                       return -1;
+               }
+               ptr += 2;
+       }
+
+       return 0;
+}
+
+gboolean _ws_util_execute_file(const char *file_path,
+       char *const args[], char *const envs[])
+{
+       pid_t pid = 0;
+       int rv = 0;
+       errno = 0;
+       register unsigned int index = 0;
+
+       while (args[index] != NULL) {
+               WDP_LOGD("[%s]", args[index]);
+               index++;
+       }
+
+       if (!(pid = fork())) {
+               WDP_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
+               WDP_LOGD("Inside child, exec (%s) command", file_path);
+
+               errno = 0;
+               if (execve(file_path, args, envs) == -1) {
+                       WDP_LOGE("Fail to execute command (%s)", strerror(errno));
+                       exit(1);
+               }
+       } else if (pid > 0) {
+               if (waitpid(pid, &rv, 0) == -1)
+                       WDP_LOGD("wait pid (%u) rv (%d)", pid, rv);
+               if (WIFEXITED(rv)) {
+                       WDP_LOGD("exited, rv=%d", WEXITSTATUS(rv));
+               } else if (WIFSIGNALED(rv)) {
+                       WDP_LOGD("killed by signal %d", WTERMSIG(rv));
+               } else if (WIFSTOPPED(rv)) {
+                       WDP_LOGD("stopped by signal %d", WSTOPSIG(rv));
+               } else if (WIFCONTINUED(rv)) {
+                       WDP_LOGD("continued");
+               }
+
+               return TRUE;
+       }
+
+       WDP_LOGE("failed to fork (%s)", strerror(errno));
+       return FALSE;
+}
+
+static int __ws_segment_to_service(char *segment, wfd_oem_new_service_s **service)
+{
+       wfd_oem_new_service_s *serv_tmp = NULL;
+       char *ptr = NULL;
+       char *temp = NULL;
+       int len = 0;
+       int i = 0;
+
+       if (!segment || !service) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       ptr = segment;
+       WDP_LOGD("Segment: %s", segment);
+
+       serv_tmp = (wfd_oem_new_service_s*) calloc(1, sizeof(wfd_oem_new_service_s));
+       if (!serv_tmp) {
+               WDP_LOGE("Failed to allocate memory for service");
+               return -1;
+       }
+
+       serv_tmp->protocol = __ws_hex_to_num(ptr, 2);
+       serv_tmp->trans_id = __ws_hex_to_num(ptr+2, 2);
+       serv_tmp->status = __ws_hex_to_num(ptr+4, 2);
+       ptr += 6;
+       WDP_LOGD("Protocol[%d], Transaction ID[%d], Status[%d]", serv_tmp->protocol, serv_tmp->trans_id, serv_tmp->status);
+
+       if (serv_tmp->status != 0) {
+               WDP_LOGE("Service status is not success");
+               free(serv_tmp);
+               return -1;
+       }
+
+       if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
+               WDP_LOGD("===== Bonjour service =====");
+               char compr[5] = {0, };
+               char query[256] = {0, };
+               char rdata[256] = {0, };
+               int dns_type = 0;
+
+               while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
+                       len = __ws_hex_to_num(ptr, 2);
+                       ptr +=2;
+                       if (len) {
+                               temp = (char*) calloc(1, len+2);
+                               temp[0] = '.';
+                               for (i=0; i<len; i++) {
+                                       temp[i+1] = (char) __ws_hex_to_num(ptr, 2);
+                                       ptr += 2;
+                               }
+                               strncat(query, temp, len+1);
+                               free(temp);
+                               temp = NULL;
+                       }
+               }
+
+               if (!strncmp(ptr, "c0", 2)) {
+                       memcpy(compr, ptr, 4);
+                       ptr += 2;
+
+                       if (!strncmp(ptr, "27", 2)) {
+                               WDP_LOGD("Segment ended");
+                               ptr += 2;
+                       } else {
+                               ptr += 2;
+                               dns_type = __ws_hex_to_num(ptr, 4);
+                               ptr += 6;
+                               if (dns_type == 12) {
+                                       if (!strncmp(compr, "c011", 4))
+                                               strncat(query, ".local.", 7);
+                                       else if (!strncmp(compr, "c00c", 4))
+                                               strncat(query, "._tcp.local.", 12);
+                                       else if (!strncmp(compr, "c01c", 4))
+                                               strncat(query, "._udp.local.", 12);
+                               }
+                       }
+               }
+               serv_tmp->data.bonjour.query = strdup(query + 1);
+               while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
+                       len = __ws_hex_to_num(ptr, 2);
+                       ptr += 2;
+                       if (len) {
+                               temp = (char*) calloc(1, len+2);
+                               temp[0] = '.';
+                               for (i=0; i<len; i++) {
+                                       temp[i+1] = (char) __ws_hex_to_num(ptr, 2);
+                                       ptr += 2;
+                               }
+                               strncat(rdata, temp, len+1);
+                               free(temp);
+                               temp = NULL;
+                       }
+               }
+               serv_tmp->data.bonjour.rdata = strdup(rdata + 1);
+
+               WDP_LOGD("Query: %s", serv_tmp->data.bonjour.query);
+               WDP_LOGD("RData: %s", serv_tmp->data.bonjour.rdata);
+       } else if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_VENDOR) {
+               WDP_LOGD("===== Vendor specific service =====");
+               if (!strncmp(ptr, "0000f00b", 8)) {
+                       WDP_LOGD("\tSAMSUNG_BT_ADDR");
+                       ptr += 16;
+                       serv_tmp->protocol = WFD_OEM_SERVICE_TYPE_BT_ADDR;
+                       serv_tmp->data.vendor.data1 = (char*) calloc(1, 9);
+                       g_strlcpy(serv_tmp->data.vendor.data1, "0000f00b", 9);
+                       serv_tmp->data.vendor.data2 = (char*) calloc(1, 18);
+                       __ws_hex_to_txt(ptr, 0, serv_tmp->data.vendor.data2);
+               }
+               WDP_LOGD("Info1: %s", serv_tmp->data.vendor.data1);
+               WDP_LOGD("Info2: %s", serv_tmp->data.vendor.data2);
+       } else {
+               WDP_LOGE("Not supported yet. Only bonjour and samsung vendor service supproted [%d]",
+                                       serv_tmp->protocol);
+               free(serv_tmp);
+               return -1;
+       }
+
+       *service = serv_tmp;
+
+       return 0;
+}
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+static void __ws_path_to_addr(char *peer_path,
+               unsigned char *dev_addr, GVariant *parameter)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       static unsigned char peer_dev[WS_MACSTR_LEN] = {'\0',};
+       const char *path = NULL;
+       char *loc = NULL;
+
+       g_variant_get(parameter, "(o)", &path);
+       g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
+       WDP_LOGE("Retrive Added path [%s]", peer_path);
+
+       loc = strrchr(peer_path,'/');
+       __ws_mac_compact_to_normal(loc + 1, peer_dev);
+
+       __ws_txt_to_mac(peer_dev, dev_addr);
+       WDP_LOGE("peer mac [" MACSTR "]", MAC2STR(dev_addr));
+
+       return;
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static int __ws_unpack_ay(unsigned char *dst, GVariant *src, int size)
+{
+       GVariantIter *iter = NULL;
+       int length = 0;
+       int res = 1;
+
+       if (!dst || !src || size == 0) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_variant_get(src, "ay", &iter);
+       if (iter == NULL) {
+               WDP_LOGE("failed to get iterator");
+               return -1;
+       }
+
+       while (g_variant_iter_loop (iter, "y", &dst[length])) {
+               length++;
+               if(length >= size)
+                       break;
+       }
+       g_variant_iter_free(iter);
+
+       if (length < size) {
+               WDP_LOGE("array is shorter than size");
+               res = -1;
+       }
+
+       return res;
+}
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+static int __parsing_wfd_info(unsigned char *wfd_dev_info,
+               wfd_oem_display_s *display )
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       int wfd_info = 0;
+       if (!wfd_dev_info || !display) {
+               WDP_LOGE("Invalid parameter");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       wfd_info = (wfd_dev_info[3]<<8 | wfd_dev_info[4]);
+
+       if (wfd_info & WS_WFD_INFO_PRIMARY_SINK)
+               display->type |= WS_WFD_INFO_PRIMARY_SINK;
+       if (wfd_info & WS_WFD_INFO_SECONDARY_SINK)
+               display->type |= WS_WFD_INFO_SECONDARY_SINK;
+
+       display->availablity = (wfd_info & WS_WFD_INFO_AVAILABLITY) >> 4;
+       display->hdcp_support = (wfd_info & WS_WFD_INFO_HDCP_SUPPORT) >> 8;
+
+       display->port = (wfd_dev_info[5]<<8 | wfd_dev_info[6]);
+       display->max_tput = (wfd_dev_info[7]<<8 | wfd_dev_info[8]);
+
+       WDP_LOGD("type [%d],availablity [%d],hdcp_support [%d],ctrl_port [%d] "
+                       "max_tput[%d]", display->type, display->availablity,
+                       display->hdcp_support, display->port,display->max_tput);
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+static void _supplicant_signal_cb(GDBusConnection *connection,
+               const gchar *sender, const gchar *object_path, const gchar *interface,
+               const gchar *signal, GVariant *parameters, gpointer user_data)
+{
+       DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
+
+       if (!g_strcmp0(signal,"InterfaceAdded")) {
+               WDP_LOGD("InterfaceAdded");
+               static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+               const char *path = NULL;
+               GVariantIter *iter = NULL;
+               const char *ifname = NULL;
+
+               g_variant_get(parameters, "(oa{sv})", &path, &iter);
+
+               g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
+               WDP_LOGD("Retrive Added path [%s]", interface_path);
+
+               if (iter != NULL) {
+                       gchar *key = NULL;
+                       GVariant *value = NULL;
+
+                       while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+                               CHECK_KEY_VALUE(key, value);
+
+                               if (!g_strcmp0(key,"Ifname")) {
+                                       g_variant_get(value, "s", &ifname);
+                                       WDP_LOGD("Retrive added interface [%s]", ifname);
+                                       if(!g_strcmp0(ifname, GROUP_IFACE_NAME))
+                                               g_strlcpy(g_pd->group_iface_path, path, DBUS_OBJECT_PATH_MAX);
+                               }
+                       }
+                       g_variant_iter_free(iter);
+               }
+
+       } else if (!g_strcmp0(signal,"InterfaceRemoved")) {
+               WDP_LOGE("InterfaceRemoved");
+               static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+               const char *path = NULL;
+
+               g_variant_get(parameters, "(o)", &path);
+               g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
+
+               WDP_LOGD("Retrive removed path [%s]", interface_path);
+               if (!g_strcmp0(g_pd->group_iface_path, interface_path))
+                       memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
+
+       } else if(!g_strcmp0(signal,"PropertiesChanged")){
+               WDP_LOGD("PropertiesChanged");
+       }
+}
+
+static void __ws_get_peer_property(const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       wfd_oem_device_s *peer = (wfd_oem_device_s *)user_data;
+       if(!peer) {
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "DeviceName") == 0) {
+               const char *name = NULL;
+
+               g_variant_get(value, "s", &name);
+               g_strlcpy(peer->dev_name, name, WS_SSID_LEN);
+               WDP_LOGD("[%s]", peer->dev_name);
+
+       } else if (g_strcmp0(key, "config_method") == 0) {
+               int config_methods = 0;
+               g_variant_get(value, "q", &config_methods);
+
+               if (config_methods & WS_CONFIG_METHOD_DISPLAY)
+                       peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
+               if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
+                       peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
+               if (config_methods & WS_CONFIG_METHOD_KEYPAD)
+                       peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
+               WDP_LOGD("[0x%x]", peer->config_methods);
+
+       } else if (g_strcmp0(key, "level") == 0) {
+
+       } else if (g_strcmp0(key, "devicecapability") == 0) {
+               unsigned char devicecapability = 0;
+
+               g_variant_get(value, "y", &devicecapability);
+               peer->dev_flags = (int)devicecapability;
+               WDP_LOGD("[0x%02x]", peer->dev_flags);
+
+       } else if (g_strcmp0(key, "groupcapability") == 0) {
+               unsigned char groupcapability = 0;
+
+               g_variant_get(value, "y", &groupcapability);
+               WDP_LOGD("[0x%02x]", groupcapability);
+               if (groupcapability & WS_GROUP_CAP_GROUP_OWNER) {
+                       peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
+                       peer->dev_role = WFD_OEM_DEV_ROLE_GO;
+               }
+               if (groupcapability & WS_GROUP_CAP_PERSISTENT_GROUP)
+                       peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
+
+       } else if (g_strcmp0(key, "PrimaryDeviceType") == 0) {
+               unsigned char primarydevicetype[WS_DEVTYPE_LEN] = {0,};
+
+               if(__ws_unpack_ay(primarydevicetype, value, WS_DEVTYPE_LEN)) {
+                       peer->pri_dev_type = primarydevicetype[1];
+                       peer->sec_dev_type = primarydevicetype[WS_DEVTYPE_LEN -1];
+               }
+       } else if (g_strcmp0(key, "SecondaryDeviceTypes") == 0) {
+       } else if (g_strcmp0(key, "VendorExtension") == 0) {
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       } else if (g_strcmp0(key, "IEs") == 0) {
+               unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
+
+               if(__ws_unpack_ay(ies, value, WFD_SUBELEM_LEN_DEV_INFO + 3))
+                       __parsing_wfd_info(ies, &(peer->display));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+       } else if (g_strcmp0(key, "DeviceAddress") == 0) {
+
+               if (__ws_unpack_ay(peer->dev_addr, value, WS_MACADDR_LEN))
+                       WDP_LOGD("[" MACSTR "]", MAC2STR(peer->dev_addr));
+
+       } else if (g_strcmp0(key, "InterfacedAddress") == 0) {
+
+               if (__ws_unpack_ay(peer->intf_addr, value, WS_MACADDR_LEN))
+                       WDP_LOGE("[" MACSTR "]", MAC2STR(peer->intf_addr));
+
+       }  else {
+               WDP_LOGE("Unknown value");
+       }
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void __ws_peer_property(const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       if(!user_data) {
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       wfd_oem_dev_data_s *peer = (wfd_oem_dev_data_s *)user_data;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "DeviceName") == 0) {
+               const char *name = NULL;
+
+               g_variant_get(value, "s", &name);
+               g_strlcpy(peer->name, name, WS_SSID_LEN);
+               WDP_LOGD("[%s]", peer->name);
+
+       } else if (g_strcmp0(key, "config_method") == 0) {
+               int config_methods = 0;
+
+               g_variant_get(value, "q", &config_methods);
+
+               if (config_methods & WS_CONFIG_METHOD_DISPLAY)
+                       peer->config_methods |= WFD_OEM_WPS_MODE_DISPLAY;
+               if (config_methods & WS_CONFIG_METHOD_PUSHBUTTON)
+                       peer->config_methods |= WFD_OEM_WPS_MODE_PBC;
+               if (config_methods & WS_CONFIG_METHOD_KEYPAD)
+                       peer->config_methods |= WFD_OEM_WPS_MODE_KEYPAD;
+               WDP_LOGD("[0x%x]", peer->config_methods);
+
+       } else if (g_strcmp0(key, "level") == 0) {
+
+       } else if (g_strcmp0(key, "devicecapability") == 0) {
+               unsigned char devicecapability = 0;
+
+               g_variant_get(value, "y", &devicecapability);
+               peer->dev_flags = (int)devicecapability;
+               WDP_LOGD("[0x%02x]", peer->dev_flags);
+
+       } else if (g_strcmp0(key, "groupcapability") == 0) {
+               unsigned char groupcapability = 0;
+
+               g_variant_get(value, "y", &groupcapability);
+               WDP_LOGD("[0x%02x]", groupcapability);
+               if (groupcapability & WS_GROUP_CAP_GROUP_OWNER) {
+                       peer->group_flags = WFD_OEM_GROUP_FLAG_GROUP_OWNER;
+                       peer->dev_role = WFD_OEM_DEV_ROLE_GO;
+               }
+               if (groupcapability & WS_GROUP_CAP_PERSISTENT_GROUP)
+                       peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
+
+       } else if (g_strcmp0(key, "PrimaryDeviceType") == 0) {
+               unsigned char primarydevicetype[WS_DEVTYPE_LEN] = {0,};
+
+               if (__ws_unpack_ay(primarydevicetype, value, WS_DEVTYPE_LEN)) {
+                       peer->pri_dev_type = primarydevicetype[1];
+                       peer->sec_dev_type = primarydevicetype[WS_DEVTYPE_LEN -1];
+               }
+       } else if (g_strcmp0(key, "SecondaryDeviceTypes") == 0) {
+       } else if (g_strcmp0(key, "VendorExtension") == 0) {
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       } else if (g_strcmp0(key, "IEs") == 0) {
+               unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
+
+               if(__ws_unpack_ay(ies, value, WFD_SUBELEM_LEN_DEV_INFO + 3))
+                       __parsing_wfd_info(ies, &(peer->display));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+       } else if (g_strcmp0(key, "DeviceAddress") == 0) {
+
+               if (__ws_unpack_ay(peer->p2p_dev_addr, value, WS_MACADDR_LEN))
+                       WDP_LOGE("[" MACSTR "]", MAC2STR(peer->p2p_dev_addr));
+
+       } else if (g_strcmp0(key, "InterfacedAddress") == 0) {
+
+               if (__ws_unpack_ay(peer->p2p_intf_addr, value, WS_MACADDR_LEN))
+                       WDP_LOGE("[" MACSTR "]", MAC2STR(peer->p2p_intf_addr));
+
+       }  else {
+               WDP_LOGE("Unknown value");
+       }
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+void __ws_interface_property(const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
+       if(!event)
+               return;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "Ifname") == 0) {
+               const char *ifname = NULL;
+
+               g_variant_get(value, "s", &ifname);
+               g_strlcpy(event->ifname, ifname, OEM_IFACE_NAME_LEN+1);
+               WDP_LOGE("Ifname [%s]", event->ifname);
+
+       }
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+void __ws_group_property(const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
+       if(!event || !event->edata)
+               return;
+
+       wfd_oem_group_data_s *group = (wfd_oem_group_data_s *)event->edata;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "Role") == 0) {
+               const char *role = NULL;
+
+               g_variant_get(value, "s", &role);
+               WDP_LOGD("role [%s]", role);
+
+               if (!strncmp(role, "GO", 2))
+                       event->dev_role = WFD_OEM_DEV_ROLE_GO;
+               else if (!strncmp(role, "client", 6))
+                       event->dev_role = WFD_OEM_DEV_ROLE_GC;
+
+       } else if (g_strcmp0(key, "Frequency") == 0) {
+               int frequency = 0;
+
+               g_variant_get(value, "q", &frequency);
+               group->freq = (int)frequency;
+
+       } else if (g_strcmp0(key, "Passphrase") == 0) {
+               const char *passphrase = NULL;
+
+               g_variant_get(value, "s", &passphrase);
+               g_strlcpy(group->pass, passphrase, OEM_PASS_PHRASE_LEN+1);
+               WDP_LOGD("passphrase [%s]", group->pass);
+
+       } else if (g_strcmp0(key, "Group") == 0) {
+
+       } else if (g_strcmp0(key, "SSID") == 0) {
+               unsigned char ssid[WS_SSID_LEN +1] = {0,};
+
+               __ws_unpack_ay(ssid, value, WS_SSID_LEN);
+                       memcpy(group->ssid, ssid, WS_SSID_LEN+1);
+                       WDP_LOGD("ssid [%s]", group->ssid);
+
+       } else if (g_strcmp0(key, "BSSID") == 0) {
+
+               if (__ws_unpack_ay(group->go_dev_addr, value, WS_MACADDR_LEN))
+                       WDP_LOGE("[" MACSTR "]", MAC2STR(group->go_dev_addr));
+
+       } else {
+               WDP_LOGE("Unknown value");
+       }
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+void __ws_extract_group_details(const char *key, GVariant *value, void *user_data)
+{
+
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
+       if(!event || !event->edata)
+               return;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "interface_object") == 0) {
+               static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+               const char *i_path = NULL;
+
+               g_variant_get(value, "o", &i_path);
+               g_strlcpy(interface_path, i_path, DBUS_OBJECT_PATH_MAX);
+               WDP_LOGD("Retrive Added path [%s]", interface_path);
+               g_strlcpy(g_pd->group_iface_path, interface_path, DBUS_OBJECT_PATH_MAX);
+               dbus_property_get_all(interface_path, g_pd->g_dbus,
+                               SUPPLICANT_IFACE, __ws_interface_property, event);
+
+       } else if (g_strcmp0(key, "role") == 0) {
+               const char *role = NULL;
+
+               g_variant_get(value, "s", &role);
+               WDP_LOGD("role [%s]", role);
+
+               if (!strncmp(role, "GO", 2))
+                       event->dev_role = WFD_OEM_DEV_ROLE_GO;
+               else if (!strncmp(role, "client", 6))
+                       event->dev_role = WFD_OEM_DEV_ROLE_GC;
+
+       } else if (g_strcmp0(key, "group_object") == 0) {
+               static char group_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+               const char *g_path;
+
+               g_variant_get(value, "o", &g_path);
+               g_strlcpy(group_path, g_path, DBUS_OBJECT_PATH_MAX);
+               WDP_LOGD("Retrive group path [%s]", group_path);
+               dbus_property_get_all(group_path, g_pd->g_dbus, SUPPLICANT_P2P_GROUP,
+                               __ws_group_property, event);
+
+               g_pd->group_sub_id =
+                       g_dbus_connection_signal_subscribe(
+                               g_pd->g_dbus,
+                               SUPPLICANT_SERVICE, /* bus name */
+                               SUPPLICANT_P2P_GROUP, /* interface */
+                               NULL, /* member */
+                               group_path, /* object path */
+                               NULL, /* arg0 */
+                               G_DBUS_SIGNAL_FLAGS_NONE,
+                               _group_signal_cb,
+                               NULL, NULL);
+       }
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+void __ws_extract_gonegfailaure_details(const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
+       if(!event || !event->edata)
+               return;
+
+       wfd_oem_conn_data_s *conn = (wfd_oem_conn_data_s *)event->edata;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "peer_object") == 0) {
+               static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+               const char *path;
+
+               g_variant_get(value, "o", &path);
+               g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
+               WDP_LOGD("Retrive peer path [%s]", peer_path);
+
+       } else if (g_strcmp0(key, "status") == 0) {
+               int status = 0;
+
+               g_variant_get(value, "i", &status);
+               WDP_LOGD("Retrive status [%d]", status);
+               conn->status = status;
+       }
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+void __ws_extract_gonegsuccess_details(const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
+       wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s *)event->edata;
+       if(!event || !edata)
+               return;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "peer_object") == 0) {
+
+       } else if (g_strcmp0(key, "status") == 0) {
+
+       } else if (g_strcmp0(key, "passphrase") == 0) {
+
+       } else if (g_strcmp0(key, "role_go") == 0) {
+               //local device role
+               const char *role = NULL;
+
+               g_variant_get(value, "s", &role);
+               if (!strncmp(role, "GO", 2))
+                       event->dev_role = WFD_OEM_DEV_ROLE_GO;
+               else if (!strncmp(role, "client", 6))
+                       event->dev_role = WFD_OEM_DEV_ROLE_GC;
+
+       } else if (g_strcmp0(key, "ssid") == 0) {
+               unsigned char ssid[WS_SSID_LEN +1] = {0,};
+
+               __ws_unpack_ay(ssid, value, WS_SSID_LEN);
+                       memcpy(edata->ssid, ssid, WS_SSID_LEN+1);
+                       WDP_LOGD("ssid [%s]", edata->ssid);
+
+       } else if (g_strcmp0(key, "peer_device_addr") == 0) {
+
+               if(__ws_unpack_ay(edata->peer_device_addr, value, WS_MACADDR_LEN))
+                       WDP_LOGD("[" MACSTR "]", MAC2STR(edata->peer_device_addr));
+
+       } else if(g_strcmp0(key, "peer_interface_addr") == 0) {
+
+               if(__ws_unpack_ay(edata->peer_intf_addr, value, WS_MACADDR_LEN))
+                       WDP_LOGD("[" MACSTR "]", MAC2STR(edata->peer_intf_addr));
+
+       } else if (g_strcmp0(key, "wps_method") == 0) {
+
+       } else if (g_strcmp0(key, "frequency_list") == 0) {
+
+       } else if (g_strcmp0(key, "persistent_group") == 0) {
+
+               g_variant_get(value, "i", &(edata->persistent_group));
+               WDP_LOGD("persistent_group [%d]", edata->persistent_group);
+
+       } else if (g_strcmp0(key, "peer_config_timeout") == 0) {
+
+       }
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+void __ws_extract_peer_service(wfd_oem_event_s *data, unsigned char *service_hex, int tlvs_len)
+{
+       GList *services = NULL;
+       wfd_oem_new_service_s *new_service = NULL;
+       char *segment = NULL;
+       int count = 0;
+       int ptr = 0;
+       int length = 0;
+       int res = 0;
+
+       while(ptr + 2 < WS_MAX_SERVICE_LEN &&
+                       (length = (service_hex[ptr+1]*256) + service_hex[ptr]) > 0) {
+               segment = (char*) g_try_malloc0(length*2+1);
+               if(segment) {
+                       __ws_byte_to_hex(segment, length * 2 + 1, &service_hex[ptr + 3], length);
+                       res = __ws_segment_to_service(segment, &new_service);
+                       if (res < 0) {
+                               WDP_LOGE("Failed to convert segment as service instance");
+                               g_free(segment);
+                               segment = NULL;
+                               continue;
+                       }
+                       services = g_list_append(services, new_service);
+                       count++;
+                       ptr += length + 4;
+                       g_free(segment);
+                       segment = NULL;
+               }
+               data->edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
+               data->dev_role = count;
+               data->edata = (void*) services;
+       }
+}
+
+void __ws_extract_servicediscoveryresponse_details(const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s *event = (wfd_oem_event_s *)user_data;
+
+       if(!event)
+               return;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "peer_object") == 0) {
+               static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+               __ws_path_to_addr(peer_path, event->dev_addr, value);
+
+       } else if (g_strcmp0(key, "update_indicator")) {
+
+       } else if (g_strcmp0(key, "tlvs")) {
+               GVariantIter *iter = NULL;
+               unsigned char service_hex[WS_MAX_SERVICE_LEN];
+               int byte_length = 0;
+
+               g_variant_get(value, "ay", &iter);
+               if (iter == NULL) {
+                       WDP_LOGE("failed to get iterator");
+                       return;
+               }
+
+               memset(service_hex, 0x0, WS_MAX_SERVICE_LEN);
+               while (g_variant_iter_loop (iter, "y", &service_hex[byte_length]))
+                       byte_length++;
+
+               __ws_extract_peer_service(event, service_hex, byte_length);
+       }
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_device_found(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PEER_FOUND;
+
+       __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_device_lost(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
+       event.event_id = WFD_OEM_EVENT_PEER_DISAPPEARED;
+
+       __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+       g_pd->callback(g_pd->user_data, &event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_find_stoppped(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
+       event.event_id = WFD_OEM_EVENT_DISCOVERY_FINISHED;
+
+       g_pd->callback(g_pd->user_data, &event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_prov_disc_req_display_pin(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
+       const char *path = NULL;
+       const char *pin = NULL;
+       char *loc = NULL;
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
+       event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
+
+       g_variant_get(parameters, "(os)", &path, &pin);
+       g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
+       WDP_LOGD("Retrive Added path [%s]", peer_path);
+
+       loc = strrchr(peer_path,'/');
+       __ws_mac_compact_to_normal(loc + 1, peer_dev);
+       __ws_txt_to_mac(peer_dev, event.dev_addr);
+       WDP_LOGD("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
+
+       g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
+       WDP_LOGD("Retrive pin [%s]", event.wps_pin);
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_prov_disc_resp_display_pin(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
+       const char *path = NULL;
+       const char *pin = NULL;
+       char *loc = NULL;
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
+       event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
+
+       g_variant_get(parameters, "(os)", &path, &pin);
+       g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
+       WDP_LOGD("Retrive Added path [%s]", peer_path);
+
+       loc = strrchr(peer_path,'/');
+       __ws_mac_compact_to_normal(loc + 1, peer_dev);
+       __ws_txt_to_mac(peer_dev, event.dev_addr);
+       WDP_LOGD("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
+
+       g_strlcpy(event.wps_pin, pin, WS_PINSTR_LEN + 1);
+       WDP_LOGE("Retrive pin [%s]", event.wps_pin);
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_prov_disc_req_enter_pin(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
+       event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
+
+       __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_prov_disc_resp_enter_pin(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
+       event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
+
+       __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_prov_disc_pbc_req(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
+       event.wps_mode = WFD_OEM_WPS_MODE_PBC;
+
+       __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_prov_disc_pbc_resp(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
+       event.wps_mode = WFD_OEM_WPS_MODE_PBC;
+
+       __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_prov_disc_failure(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
+       const char *path = NULL;
+       int prov_status = 0;
+       char *loc = NULL;
+
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_PROV_DISC_FAIL;
+
+       g_variant_get(parameters, "(oi)", &path, &prov_status);
+       g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
+       WDP_LOGD("Retrive Added path [%s]", peer_path);
+       WDP_LOGD("Retrive Failure stateus [%d]", prov_status);
+
+       loc = strrchr(peer_path,'/');
+       __ws_mac_compact_to_normal(loc + 1, peer_dev);
+       __ws_txt_to_mac(peer_dev, event.dev_addr);
+       WDP_LOGE("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
+
+       g_pd->callback(g_pd->user_data, &event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_group_started(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       wfd_oem_event_s event;
+       wfd_oem_group_data_s *edata = NULL;
+
+       edata = (wfd_oem_group_data_s*)calloc(1, sizeof(wfd_oem_group_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_GROUP;
+       event.event_id = WFD_OEM_EVENT_GROUP_CREATED;
+
+       if(parameters != NULL){
+               g_variant_get(parameters, "(a{sv})", &iter);
+
+               if (iter != NULL) {
+                       dbus_property_foreach(iter, __ws_extract_group_details, &event);
+                       g_variant_iter_free(iter);
+               }
+       } else {
+               WDP_LOGE("No properties");
+       }
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_go_neg_success(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       wfd_oem_event_s event;
+       wfd_oem_conn_data_s *edata = NULL;
+
+       edata = (wfd_oem_conn_data_s*)calloc(1, sizeof(wfd_oem_conn_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_CONN;
+       event.event_id = WFD_OEM_EVENT_GO_NEG_DONE;
+
+       if (parameters != NULL){
+               g_variant_get(parameters, "(a{sv})", &iter);
+
+               if (iter != NULL) {
+                       dbus_property_foreach(iter, __ws_extract_gonegsuccess_details, &event);
+                       g_variant_iter_free(iter);
+               }
+       } else {
+               WDP_LOGE("No properties");
+       }
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_go_neg_failure(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       wfd_oem_event_s event;
+       wfd_oem_conn_data_s *edata = NULL;
+
+       edata = (wfd_oem_conn_data_s *) g_try_malloc0(sizeof(wfd_oem_conn_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
+
+       if (parameters != NULL) {
+               g_variant_get(parameters, "(a{sv})", &iter);
+
+               if (iter != NULL) {
+                       dbus_property_foreach(iter, __ws_extract_gonegfailaure_details, &event);
+                       g_variant_iter_free(iter);
+               }
+       } else {
+               WDP_LOGE("No properties");
+       }
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_go_neg_request(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       wfd_oem_dev_data_s *edata = NULL;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       static unsigned char peer_dev[OEM_MACSTR_LEN] = {'\0',};
+       const char *path = NULL;
+       char * loc = NULL;
+
+       int dev_pwd_id = 0;
+
+       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+       if (!edata) {
+               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.edata = (void*) edata;
+       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+       event.event_id = WFD_OEM_EVENT_GO_NEG_REQ;
+
+       g_variant_get(parameters, "(oq)", &path, &dev_pwd_id);
+       g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
+       WDP_LOGD("Retrive peer path [%s]", peer_path);
+
+       WDP_LOGD("Retrive dev_passwd_id [%d]", dev_pwd_id);
+
+       if (dev_pwd_id == WS_DEV_PASSWD_ID_PUSH_BUTTON)
+               event.wps_mode = WFD_OEM_WPS_MODE_PBC;
+       else if (dev_pwd_id == WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED)
+               event.wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
+       else if (dev_pwd_id == WS_DEV_PASSWD_ID_USER_SPECIFIED)
+               event.wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
+       else
+               event.wps_mode = WFD_OEM_WPS_MODE_NONE;
+
+       g_variant_get(parameters, "(o)", &path);
+       g_strlcpy(peer_path, path, DBUS_OBJECT_PATH_MAX);
+       WDP_LOGD("Retrive Added path [%s]", peer_path);
+
+       loc = strrchr(peer_path,'/');
+       __ws_mac_compact_to_normal(loc + 1, peer_dev);
+       __ws_txt_to_mac(peer_dev, event.dev_addr);
+       WDP_LOGD("peer mac [" MACSTR "]", MAC2STR(event.dev_addr));
+
+       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                       __ws_peer_property, event.edata);
+
+       g_pd->callback(g_pd->user_data, &event);
+       g_free(event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_invitation_result(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+//     g_pd->callback(g_pd->user_data, event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_group_finished(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.event_id = WFD_OEM_EVENT_GROUP_DESTROYED;
+       event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
+
+       g_dbus_connection_signal_unsubscribe(g_pd->g_dbus, g_pd->group_sub_id);
+       memset(g_pd->group_iface_path, 0x0, DBUS_OBJECT_PATH_MAX);
+
+       g_pd->callback(g_pd->user_data, &event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_service_discovery_response(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       wfd_oem_event_s event;
+
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.event_id = WFD_OEM_EVENT_SERV_DISC_RESP;
+
+       if(parameters != NULL) {
+               g_variant_get(parameters, "(a{sv}", &iter);
+               if(iter != NULL) {
+                       dbus_property_foreach(iter, __ws_extract_servicediscoveryresponse_details, &event);
+                       event.edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
+                       g_variant_iter_free(iter);
+               }
+       } else {
+               WDP_LOGE("No Properties");
+       }
+
+       g_pd->callback(g_pd->user_data, &event);
+
+       if (event.edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE)
+               g_list_free((GList*) event.edata);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_persistent_group_added(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+//     g_pd->callback(g_pd->user_data, &event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_persistent_group_removed(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_event_s event;
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+//     g_pd->callback(g_pd->user_data, &event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static void _ws_process_wps_failed(GDBusConnection *connection,
+               const gchar *object_path, GVariant *parameters)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GVariantIter *iter = NULL;
+       wfd_oem_event_s event;
+       const char *name = NULL;
+
+       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+       event.event_id = WFD_OEM_EVENT_WPS_FAIL;
+
+       g_variant_get(parameters, "(sa{sv})", &name, &iter);
+
+       WDP_LOGD("code [%s]", name);
+
+       if (iter != NULL) {
+
+               gchar *key = NULL;
+               GVariant *value = NULL;
+
+               while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+                       CHECK_KEY_VALUE(key, value);
+               }
+               g_variant_iter_free(iter);
+       }
+
+       g_pd->callback(g_pd->user_data, &event);
+
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static struct {
+       const char *interface;
+       const char *member;
+       void (*function) (GDBusConnection *connection,const gchar *object_path,
+                       GVariant *parameters);
+} ws_p2pdevice_signal_map[] = {
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "DeviceFound",
+               _ws_process_device_found
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "DeviceLost",
+               _ws_process_device_lost
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "FindStopped",
+               _ws_process_find_stoppped
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "ProvisionDiscoveryRequestDisplayPin",
+               _ws_process_prov_disc_req_display_pin
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "ProvisionDiscoveryResponseDisplayPin",
+               _ws_process_prov_disc_resp_display_pin
+       },
+       {
+                       SUPPLICNAT_P2PDEVICE,
+               "ProvisionDiscoveryRequestEnterPin",
+               _ws_process_prov_disc_req_enter_pin
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "ProvisionDiscoveryResponseEnterPin",
+               _ws_process_prov_disc_resp_enter_pin
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "ProvisionDiscoveryPBCRequest",
+               _ws_process_prov_disc_pbc_req
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "ProvisionDiscoveryPBCResponse",
+               _ws_process_prov_disc_pbc_resp
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "ProvisionDiscoveryFailure",
+               _ws_process_prov_disc_failure
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "GroupStarted",
+               _ws_process_group_started
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "GONegotiationSuccess",
+               _ws_process_go_neg_success
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "GONegotiationFailure",
+               _ws_process_go_neg_failure
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "GONegotiationRequest",
+               _ws_process_go_neg_request
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "InvitationResult",
+               _ws_process_invitation_result
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "GroupFinished",
+               _ws_process_group_finished
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "ServiceDiscoveryResponse",
+               _ws_process_service_discovery_response
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "PersistentGroupAdded",
+               _ws_process_persistent_group_added
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "PersistentGroupRemoved",
+               _ws_process_persistent_group_removed
+       },
+       {
+               SUPPLICNAT_P2PDEVICE,
+               "WpsFailed ",
+               _ws_process_wps_failed
+       },
+       {
+               NULL,
+               NULL,
+               NULL
+       }
+};
+
+static void _p2pdevice_signal_cb(GDBusConnection *connection,
+               const gchar *sender, const gchar *object_path, const gchar *interface,
+               const gchar *signal, GVariant *parameters, gpointer user_data)
+{
+       int i = 0;
+       DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
+
+       for (i = 0; ws_p2pdevice_signal_map[i].member != NULL; i++) {
+               if (!g_strcmp0(signal, ws_p2pdevice_signal_map[i].member) &&
+                               ws_p2pdevice_signal_map[i].function != NULL)
+                       ws_p2pdevice_signal_map[i].function(connection, object_path, parameters);
+       }
+}
+
+
+static void _group_signal_cb(GDBusConnection *connection,
+               const gchar *sender, const gchar *object_path, const gchar *interface,
+               const gchar *signal, GVariant *parameters, gpointer user_data)
+{
+       DEBUG_SIGNAL(sender, object_path, interface, signal, parameters);
+
+       if(!g_strcmp0(signal,"PeerJoined")){
+
+                       wfd_oem_event_s event;
+                       wfd_oem_dev_data_s *edata = NULL;
+
+                       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+                       edata = (wfd_oem_dev_data_s *) g_try_malloc0(sizeof(wfd_oem_dev_data_s));
+                       if (!edata) {
+                               WDP_LOGF("Failed to allocate memory for event. [%s]",
+                                               strerror(errno));
+                               __WDP_LOG_FUNC_EXIT__;
+                               return;
+                       }
+                       memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+                       event.edata = (void*) edata;
+                       event.edata_type = WFD_OEM_EDATA_TYPE_DEVICE;
+                       event.event_id = WFD_OEM_EVENT_STA_CONNECTED;
+
+                       __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+                       dbus_property_get_all(peer_path, g_pd->g_dbus, SUPPLICANT_P2P_PEER,
+                                               __ws_peer_property, event.edata);
+
+                       g_pd->callback(g_pd->user_data, &event);
+                       g_free(edata);
+
+       } else if (!g_strcmp0(signal,"PeerDisconnected")) {
+
+               wfd_oem_event_s event;
+
+               static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+
+               memset(&event, 0x0, sizeof(wfd_oem_event_s));
+
+               event.edata_type = WFD_OEM_EDATA_TYPE_NONE;
+               event.event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
+
+               __ws_path_to_addr(peer_path, event.dev_addr, parameters);
+
+               g_pd->callback(g_pd->user_data, &event);
+       }
+}
+
+static void __register_p2pdevice_signal(GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       ws_dbus_plugin_data_s * pd_data;
+       static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       const char *path = NULL;
+
+       pd_data = (ws_dbus_plugin_data_s *)g_pd;
+
+       g_variant_get(value, "(o)", &path);
+       g_strlcpy(interface_path, path, DBUS_OBJECT_PATH_MAX);
+       g_strlcpy(pd_data->iface_path, path, DBUS_OBJECT_PATH_MAX);
+
+       WDP_LOGD("interface object path [%s]", interface_path);
+       /* subscribe interface p2p signal */
+       WDP_LOGD("register P2PDevice iface signal");
+       pd_data->p2pdevice_sub_id = g_dbus_connection_signal_subscribe(
+               pd_data->g_dbus,
+               SUPPLICANT_SERVICE, /* bus name */
+               SUPPLICNAT_P2PDEVICE, /* interface */
+               NULL, /* member */
+               NULL, /* object path */
+               NULL, /* arg0 */
+               G_DBUS_SIGNAL_FLAGS_NONE,
+               _p2pdevice_signal_cb,
+               NULL, NULL);
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static int _ws_create_interface(const char *iface_name)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       dbus_method_param_s params;
+
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "CreateInterface", SUPPLICANT_PATH, g_dbus);
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE ("a{sv}"));
+       g_variant_builder_add(builder, "{sv}", "Ifname", g_variant_new_string(iface_name));
+       g_variant_builder_add(builder, "{sv}", "Driver", g_variant_new_string("nl80211"));
+       g_variant_builder_add(builder, "{sv}", "ConfigFile", g_variant_new_string(CONF_FILE_PATH));
+       params.params = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+
+       res = dbus_method_call(&params, SUPPLICANT_INTERFACE, __register_p2pdevice_signal, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to CreateInterface");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+static int _ws_get_interface(const char *iface_name)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+
+       dbus_set_method_param(&params, SUPPLICANT_METHOD_GETINTERFACE,
+                       SUPPLICANT_PATH, g_pd->g_dbus);
+
+       params.params = g_variant_new("(s)", iface_name);
+       WDP_LOGE("param [%s]", g_variant_print(params.params,TRUE));
+
+       res = dbus_method_call(&params, SUPPLICANT_INTERFACE,
+                               __register_p2pdevice_signal, g_pd);
+
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to get interface");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+#if 0
+static int _ws_remove_interface(const char *iface_name)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       static char interface_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+
+       res = _ws_get_interface(iface_name, interface_path);
+       if (res < 0) {
+               WDP_LOGE("Failed to get interface object");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "RemoveInterface", SUPPLICANT_PATH, g_dbus);
+       params.params = g_variant_new("(o)", interface_path);
+
+       res = dbus_method_call(&params, SUPPLICANT_INTERFACE, NULL, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to RemoveInterface");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif
+
+static int _ws_init_dbus_connection(void)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *conn = NULL;
+       GError *error = NULL;
+       int res = 0;
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+       if (conn == NULL) {
+               if(error != NULL){
+                       WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
+                                       error->message);
+                       g_error_free(error);
+               }
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       g_pd->g_dbus = conn;
+
+       WDP_LOGD("register supplicant signal");
+       /* subscribe supplicant signal */
+       g_pd->supp_sub_id = g_dbus_connection_signal_subscribe(
+               g_pd->g_dbus,
+               SUPPLICANT_SERVICE, /* bus name */
+               SUPPLICANT_INTERFACE, /* interface */
+               NULL, /* member */
+               SUPPLICANT_PATH, /* object path */
+               NULL, /* arg0 */
+               G_DBUS_SIGNAL_FLAGS_NONE,
+               _supplicant_signal_cb,
+               NULL, NULL);
+
+       if(_ws_get_interface(COMMON_IFACE_NAME) < 0)
+               res = _ws_create_interface(COMMON_IFACE_NAME);
+
+       if (res < 0)
+                       WDP_LOGE("Failed to subscribe interface signal");
+       else
+               WDP_LOGI("Successfully register signal filters");
+       return res;
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+static int _ws_deinit_dbus_connection(void)
+{
+       GDBusConnection *g_dbus = NULL;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       if(g_pd != NULL) {
+               g_dbus_connection_signal_unsubscribe(g_dbus, g_pd->supp_sub_id);
+               g_dbus_connection_signal_unsubscribe(g_dbus, g_pd->p2pdevice_sub_id);
+               g_dbus_connection_signal_unsubscribe(g_dbus, g_pd->group_sub_id);
+       }
+
+       g_object_unref(g_dbus);
+       return 0;
+}
+
+int wfd_plugin_load(wfd_oem_ops_s **ops)
+{
+       if (!ops) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       *ops = &supplicant_ops;
+
+       return 0;
+}
+
+static int _ws_reset_plugin(ws_dbus_plugin_data_s *g_pd)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       if (!g_pd) {
+               WDP_LOGE("Invalid parameter");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       _ws_deinit_dbus_connection();
+
+       if (g_pd->activated)
+               ws_deactivate(g_pd->concurrent);
+
+       g_free(g_pd);
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+
+static int __ws_check_net_interface(char* if_name)
+{
+       struct ifreq ifr;
+       int fd;
+
+       if (if_name == NULL) {
+               WDP_LOGE("Invalid param");
+               return -1;
+       }
+
+       fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+       if (fd < 0) {
+               WDP_LOGE("socket create error: %d", fd);
+               return -2;
+       }
+
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
+       ifr.ifr_name[IFNAMSIZ-1] = '\0';
+
+       if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+               close(fd);
+               WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s", strerror(errno)); /* interface is not found. */
+               return -3;
+       }
+
+       close(fd);
+
+       if (ifr.ifr_flags & IFF_UP) {
+               WDP_LOGD("%s interface is up", if_name);
+               return 1;
+       } else if (!(ifr.ifr_flags & IFF_UP)) {
+               WDP_LOGD("%s interface is down", if_name);
+               return 0;
+       }
+       return 0;
+}
+
+int ws_init(wfd_oem_event_cb callback, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       if (g_pd)
+               _ws_reset_plugin(g_pd);
+
+       errno = 0;
+       g_pd = (ws_dbus_plugin_data_s*) g_try_malloc0 (sizeof(ws_dbus_plugin_data_s));
+       if (!g_pd) {
+               WDP_LOGE("Failed to allocate memory for plugin data. [%s]", strerror(errno));
+               return -1;
+       }
+
+       g_pd->callback = callback;
+       g_pd->user_data = user_data;
+       g_pd->initialized = TRUE;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_deinit()
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       if (g_pd) {
+               _ws_reset_plugin(g_pd);
+               g_pd = NULL;
+       }
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+#if 0
+static int __ws_p2p_firmware_start(void)
+{
+       GError *error = NULL;
+       GVariant *reply = NULL;
+       GVariant *param = NULL;
+       GDBusConnection *connection = NULL;
+       const char *device = "p2p";
+
+       connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (connection == NULL) {
+               if(error != NULL){
+                       WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
+                                       error->message);
+                       g_error_free(error);
+               }
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       param = g_variant_new("(s)", device);
+
+       reply = g_dbus_connection_call_sync (connection,
+                       NETCONFIG_SERVICE, /* bus name */
+                       NETCONFIG_WIFI_PATH, /* object path */
+                       NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
+                       "Start", /* method name */
+                       param, /* GVariant *params */
+                       NULL, /* reply_type */
+                       G_DBUS_CALL_FLAGS_NONE, /* flags */
+                       NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
+                       NULL, /* cancellable */
+                       &error); /* error */
+
+       if(error != NULL){
+               if(strstr(error->message, ".AlreadyExists") != NULL) {
+                       WDP_LOGD("p2p already enabled");
+                       g_error_free(error);
+
+               } else {
+                       WDP_LOGE("Error! Failed to call net-config method: [%s]",
+                                       error->message);
+                       g_error_free(error);
+                       if(reply)
+                                g_variant_unref(reply);
+                       g_object_unref(connection);
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+       }
+       if(reply)
+                g_variant_unref(reply);
+       g_object_unref(connection);
+       return 0;
+}
+
+static int __ws_p2p_firmware_stop(void)
+{
+       GError *error = NULL;
+       GVariant *reply = NULL;
+       GVariant *param = NULL;
+       GDBusConnection *connection = NULL;
+       const char *device = "p2p";
+
+       connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (connection == NULL) {
+               if(error != NULL){
+                       WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
+                                       error->message);
+                       g_error_free(error);
+               }
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       param = g_variant_new("(s)", device);
+
+       reply = g_dbus_connection_call_sync (connection,
+                       NETCONFIG_SERVICE, /* bus name */
+                       NETCONFIG_WIFI_PATH, /* object path */
+                       NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
+                       "Stop", /* method name */
+                       param, /* GVariant *params */
+                       NULL, /* reply_type */
+                       G_DBUS_CALL_FLAGS_NONE, /* flags */
+                       NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
+                       NULL, /* cancellable */
+                       &error); /* error */
+
+       if(error != NULL){
+               if(strstr(error->message, ".AlreadyExists") != NULL) {
+                       WDP_LOGD("p2p already disabled");
+                       g_error_free(error);
+
+               } else {
+                       WDP_LOGE("Error! Failed to call net-config method: [%s]",
+                                       error->message);
+                       g_error_free(error);
+                       if(reply)
+                                g_variant_unref(reply);
+                       g_object_unref(connection);
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+       }
+       if(reply)
+                g_variant_unref(reply);
+       g_object_unref(connection);
+       return 0;
+}
+
+static int __ws_p2p_supplicant_start(void)
+{
+       gboolean rv = FALSE;
+       const char *path = "/usr/sbin/p2p_supp.sh";
+       char *const args[] = { "/usr/sbin/p2p_supp.sh", "start_dbus", NULL };
+       char *const envs[] = { NULL };
+
+       rv = _ws_util_execute_file(path, args, envs);
+
+       if (rv != TRUE) {
+               WDP_LOGE("Failed to start p2p_supp.sh");
+               return -1;
+       }
+
+       WDP_LOGI("Successfully started p2p_supp.sh");
+       return 0;
+}
+#endif
+
+static int __ws_if_up(void)
+{
+       gboolean rv = FALSE;
+       const char *path = "/usr/sbin/ifconfig";
+       char *const args[] = { "/usr/sbin/ifconfig", "wlan0", "up", NULL };
+       char *const envs[] = { NULL };
+
+       rv = _ws_util_execute_file(path, args, envs);
+
+       if (rv != TRUE) {
+               WDP_LOGE("Failed to start if down");
+               return -1;
+       }
+
+       WDP_LOGI("Successfully if up");
+       return 0;
+}
+
+static int __ws_if_down(void)
+{
+       gboolean rv = FALSE;
+       const char *path = "/usr/sbin/ifconfig";
+       char *const args[] = { "/usr/sbin/ifconfig", "wlan0", "down", NULL };
+       char *const envs[] = { NULL };
+
+       rv = _ws_util_execute_file(path, args, envs);
+
+       if (rv != TRUE) {
+               WDP_LOGE("Failed to start if down");
+               return -1;
+       }
+
+       WDP_LOGI("Successfully if down");
+       return 0;
+}
+
+static int __ws_p2p_supplicant_stop(void)
+{
+       gboolean rv = FALSE;
+       const char *path = "/usr/sbin/p2p_supp.sh";
+       char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
+       char *const envs[] = { NULL };
+
+       rv = _ws_util_execute_file(path, args, envs);
+
+       if (rv != TRUE) {
+               WDP_LOGE("Failed to stop p2p_supp.sh");
+               return -1;
+       }
+
+       WDP_LOGI("Successfully stopped p2p_supp.sh");
+       return 0;
+}
+
+#if 0
+static int __ws_p2p_on(void)
+{
+       DBusError error;
+       DBusMessage *reply = NULL;
+       DBusMessage *message = NULL;
+       DBusConnection *connection = NULL;
+
+       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (connection == NULL) {
+               WDP_LOGE("Failed to get system bus");
+               return -EIO;
+       }
+
+       message = dbus_message_new_method_call(NETCONFIG_SERVICE,
+                       NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
+       if (message == NULL) {
+               WDP_LOGE("Failed DBus method call");
+               dbus_connection_unref(connection);
+               return -EIO;
+       }
+
+       dbus_error_init(&error);
+
+       reply = dbus_connection_send_with_reply_and_block(connection, message,
+                       NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
+       if (dbus_error_is_set(&error) == TRUE) {
+               if (NULL != strstr(error.message, ".AlreadyExists")) {
+                       // p2p already enabled
+               } else {
+                       WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
+                                       "DBus error [%s: %s]", error.name, error.message);
+
+                       dbus_error_free(&error);
+               }
+
+               dbus_error_free(&error);
+       }
+
+       if (reply != NULL)
+               dbus_message_unref(reply);
+
+       dbus_message_unref(message);
+       dbus_connection_unref(connection);
+
+       return 0;
+}
+
+static int __ws_p2p_off(void)
+{
+       DBusError error;
+       DBusMessage *reply = NULL;
+       DBusMessage *message = NULL;
+       DBusConnection *connection = NULL;
+
+       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (connection == NULL) {
+               WDP_LOGE("Failed to get system bus");
+               return -EIO;
+       }
+
+       message = dbus_message_new_method_call(NETCONFIG_SERVICE,
+                       NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
+       if (message == NULL) {
+               WDP_LOGE("Failed DBus method call");
+               dbus_connection_unref(connection);
+               return -EIO;
+       }
+
+       dbus_error_init(&error);
+
+       reply = dbus_connection_send_with_reply_and_block(connection, message,
+                       NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
+       if (dbus_error_is_set(&error) == TRUE) {
+               if (NULL != strstr(error.message, ".AlreadyExists")) {
+                       // p2p already disabled
+               } else {
+                       WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
+                                       "DBus error [%s: %s]", error.name, error.message);
+
+                       dbus_error_free(&error);
+               }
+
+               dbus_error_free(&error);
+       }
+
+       if (reply != NULL)
+               dbus_message_unref(reply);
+
+       dbus_message_unref(message);
+       dbus_connection_unref(connection);
+
+       return 0;
+}
+#endif
+
+int ws_activate(int concurrent)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       int res = 0;
+       int retry_count = 0;
+
+       while (retry_count < WS_CONN_RETRY_COUNT) {
+               /* load wlan driver */
+               res = __ws_if_up();
+               if (res < 0) {
+                       WDP_LOGE("Failed to load driver [ret=%d]", res);
+                       return -1;
+               }
+               WDP_LOGI("P2P firmware started with error %d", res);
+
+               if (__ws_check_net_interface(COMMON_IFACE_NAME) < 0) {
+                       usleep(150000); // wait for 150ms
+                       retry_count++;
+                       WDP_LOGE("interface is not up: retry, %d", retry_count);
+               } else {
+                       break;
+               }
+       }
+
+       if (retry_count >= WS_CONN_RETRY_COUNT) {
+               WDP_LOGE("Driver loading is failed", res);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       if (retry_count > 0) {
+               // Give driver marginal time to config net
+               WDP_LOGE("Driver loading is done. Wait marginal time for driver");
+               sleep(1); // 1s
+       }
+
+       g_pd->concurrent = concurrent;
+
+       res = _ws_init_dbus_connection();
+       if (res < 0) {
+               res = __ws_p2p_supplicant_stop();
+               WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
+               res = __ws_if_down();
+               WDP_LOGI("P2P firmware stopped with error %d", res);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       g_pd->activated = TRUE;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_deactivate(int concurrent)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       int res = 0;
+
+       if (!g_pd->activated) {
+               WDP_LOGE("Wi-Fi Direct is not activated");
+               return -1;
+       }
+
+       ws_stop_scan();
+
+       g_pd->concurrent = concurrent;
+
+       _ws_deinit_dbus_connection();
+
+       res = __ws_p2p_supplicant_stop();
+       WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
+
+       res = __ws_if_down();
+       WDP_LOGI("P2P firmware stopped with error %d", res);
+       g_pd->activated = FALSE;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+static int _ws_flush()
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "Flush", g_pd->iface_path, g_dbus);
+       params.params = NULL;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to flush");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+static int _ws_cancel()
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "Cancel", g_pd->iface_path , g_dbus);
+       params.params = NULL;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to cancel");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+#if 0
+static gboolean _retry_start_scan(gpointer data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       WDP_LOGD("Succeeded to start scan");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif
+
+int ws_start_scan(wfd_oem_scan_param_s *param)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       if (!param) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE) {
+
+               dbus_set_method_param(&params, "Find",  g_pd->iface_path, g_dbus);
+
+               builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+
+                       if (param->scan_time)
+                               g_variant_builder_add (builder, "{sv}", "Timeout",
+                                                       g_variant_new_int32(param->scan_time));
+                       if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
+                               g_variant_builder_add (builder, "{sv}", "DiscoveryType",
+                                                       g_variant_new_string("social"));
+
+                       value = g_variant_new ("(a{sv})", builder);
+                       g_variant_builder_unref (builder);
+       } else {
+
+               dbus_set_method_param(&params, "Listen", g_pd->iface_path, g_dbus);
+               value = g_variant_new ("(i)", param->scan_time);
+       }
+
+       params.params = value;
+
+       WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       g_variant_unref(value);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to start scan");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_restart_scan(int freq)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "Find", g_pd->iface_path, g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+       g_variant_builder_add (builder, "{sv}", "Timeout", g_variant_new_int32(2));
+       g_variant_builder_add (builder, "{sv}", "DiscoveryType",
+                               g_variant_new_string("social"));
+       value = g_variant_new ("(a{sv})", builder);
+       g_variant_builder_unref (builder);
+
+       params.params = value;
+
+       WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       g_variant_unref(value);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to start scan");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_stop_scan()
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "StopFind", g_pd->iface_path, g_dbus);
+       params.params = NULL;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       if (res < 0)
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to stop scan");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_get_visibility(int *visibility)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_set_visibility(int visibility)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_scan_result(GList **peers, int *peer_count)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       wfd_oem_device_s *ws_dev = NULL;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       int res = 0;
+
+       if (!peer_addr || !peer) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+
+       ws_dev = (wfd_oem_device_s *) g_try_malloc0(sizeof(wfd_oem_device_s));
+       if (!ws_dev) {
+               WDP_LOGF("Failed to allocate memory device. [%s]",
+                               strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
+                       COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
+
+       WDP_LOGD("get peer path [%s]", peer_path);
+
+       res = dbus_property_get_all(peer_path, g_dbus, SUPPLICANT_P2P_PEER,
+                               __ws_get_peer_property, ws_dev);
+
+       if (res < 0) {
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+                       g_free(ws_dev);
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+       } else {
+               WDP_LOGD("succeeded to get peer info");
+               *peer = ws_dev;
+       }
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       int res = 0;
+
+       if (!peer_addr) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "ProvisionDiscoveryRequest", g_pd->iface_path, g_dbus);
+
+       g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
+                       COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
+       WDP_LOGD("get peer path [%s]", peer_path);
+
+       value = g_variant_new ("(os)", peer_path, __ws_wps_to_txt(wps_mode));
+       WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       g_variant_unref(value);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to send prov disc to peer[" MACSTR "]", MAC2STR(peer_addr));
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       int res = 0;
+
+       if (!peer_addr || !param) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "Connect", g_pd->iface_path, g_dbus);
+
+       g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
+                       COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
+       WDP_LOGD("get peer path [%s]", peer_path);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+       g_variant_builder_add (builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
+       if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
+               g_variant_builder_add (builder, "{sv}", "persistent", g_variant_new_boolean(TRUE));
+
+       if (param->conn_flags & WFD_OEM_CONN_TYPE_JOIN)
+               g_variant_builder_add (builder, "{sv}", "join", g_variant_new_boolean(TRUE));
+
+       if (param->conn_flags& WFD_OEM_CONN_TYPE_AUTH)
+               g_variant_builder_add (builder, "{sv}", "autorize_only", g_variant_new_boolean(TRUE));
+
+       if (param->wps_pin[0] != '\0')
+               g_variant_builder_add (builder, "{sv}", "pin", g_variant_new_string(param->wps_pin));
+
+       g_variant_builder_add (builder, "{sv}", "wps_method",
+                               g_variant_new_string(__ws_wps_to_txt(param->wps_mode)));
+
+       value = g_variant_new ("(a{sv})", builder);
+       g_variant_builder_unref (builder);
+
+       WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       g_variant_unref(value);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_disconnect(unsigned char *peer_addr)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       int res = 0;
+
+       if (!peer_addr) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "RemoveClient", g_pd->iface_path ,g_dbus);
+
+       g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
+                       COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
+       WDP_LOGE("get peer path [%s]", peer_path);
+
+       value = g_variant_new ("(oi)", peer_path, 0);
+       WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       g_variant_unref(value);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to stop scan");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_reject_connection(unsigned char *peer_addr)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       int res = 0;
+
+       if (!peer_addr) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "RejectPeer", g_pd->iface_path ,g_dbus);
+
+       g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
+                       COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
+       WDP_LOGE("get peer path [%s]", peer_path);
+
+       value = g_variant_new ("(o)", peer_path);
+       WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       g_variant_unref(value);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to reject peer[" MACSTR "]", MAC2STR(peer_addr));
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_cancel_connection(unsigned char *peer_addr)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       _ws_cancel();
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_connected_peers(GList **peers, int *peer_count)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_pin(char *pin)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_set_pin(char *pin)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_supported_wps_mode()
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_create_group(int persistent, int freq, const char *passphrase)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "GroupAdd", g_pd->iface_path, g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+
+       if (persistent)
+               g_variant_builder_add (builder, "{sv}", "persistent", g_variant_new_boolean(TRUE));
+
+       if(freq)
+               g_variant_builder_add (builder, "{sv}", "frequency", g_variant_new_int32(freq));
+       else
+               g_variant_builder_add (builder, "{sv}", "frequency", g_variant_new_int32(2));
+
+       value = g_variant_new ("(a{sv})", builder);
+       g_variant_builder_unref (builder);
+
+       WDP_LOGD("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       g_variant_unref(value);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to add group");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_destroy_group(const char *ifname)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       if (!ifname) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "Disconnect", g_pd->group_iface_path, g_dbus);
+       params.params = NULL;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       if (res < 0) {
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+       } else {
+               _ws_flush();
+               WDP_LOGD("Succeeded to remove group");
+       }
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
+{
+       __WDP_LOG_FUNC_ENTER__;
+               GDBusConnection *g_dbus = NULL;
+               GVariantBuilder *builder = NULL;
+               GVariant *value = NULL;
+               dbus_method_param_s params;
+               static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+               int res = 0;
+
+               if (!peer_addr || !param) {
+                       WDP_LOGE("Invalid parameter");
+                       return -1;
+               }
+               g_dbus = g_pd->g_dbus;
+               if (!g_dbus) {
+                       WDP_LOGE("DBus connection is NULL");
+                       return -1;
+               }
+               memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+               dbus_set_method_param(&params, "Invite", g_pd->group_iface_path, g_dbus);
+
+               g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
+                               COMPACT_MACSTR, g_pd->iface_path, MAC2STR(peer_addr));
+               WDP_LOGE("get peer path [%s]", peer_path);
+
+               builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+               g_variant_builder_add (builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
+               value = g_variant_new ("(a{sv})", builder);
+               g_variant_builder_unref (builder);
+
+               WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+               params.params = value;
+
+               res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+               g_variant_unref(value);
+               if (res < 0)
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+               else
+                       WDP_LOGD("Succeeded to invite peer[" MACSTR "]", MAC2STR(peer_addr));
+
+               __WDP_LOG_FUNC_EXIT__;
+               return 0;
+}
+
+// Only group owner can use this command
+int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       GVariant *dev_addr = NULL;
+       dbus_method_param_s params;
+       int i = 0;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "Start", g_pd->group_iface_path, g_dbus);
+
+       if (peer_addr != NULL) {
+               builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+               for(i = 0; i < WS_MACADDR_LEN; i++)
+                       g_variant_builder_add(builder, "y", peer_addr[i]);
+
+               dev_addr = g_variant_new ("ay", builder);
+               g_variant_builder_unref (builder);
+       }
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+       g_variant_builder_add (builder, "{sv}", "Role", g_variant_new_string("enrollee"));
+       if (peer_addr != NULL)
+               g_variant_builder_add (builder, "{sv}", "P2PDeviceAddress", dev_addr);
+
+       if (pin != NULL && pin[0] != '\0') {
+               g_variant_builder_add (builder, "{sv}", "Type", g_variant_new_string("pin"));
+               g_variant_builder_add (builder, "{sv}", "Pin", g_variant_new_string(pin));
+       } else {
+               g_variant_builder_add (builder, "{sv}", "Type", g_variant_new_string("pbc"));
+       }
+
+       value = g_variant_new ("(a{sv})", builder);
+       g_variant_builder_unref (builder);
+
+       WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_WPS, NULL, NULL);
+       g_variant_unref(params.params);
+
+       if (peer_addr != NULL)
+               g_variant_unref(dev_addr);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to run wps");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       WDP_LOGD("Succeeded to start WPS");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_wps_cancel()
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "Cancel", g_pd->group_iface_path, g_dbus);
+       params.params = NULL;
+
+       res = dbus_method_call(&params, SUPPLICNAT_WPS, NULL, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to cancel WPS");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_dev_name(char *dev_name)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_set_dev_name(char *dev_name)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+
+       GVariant *value = NULL;
+       GVariant *param = NULL;
+       GVariantBuilder *builder = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       if (!dev_name) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
+                        g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+       g_variant_builder_add (builder, "{sv}", "DeviceName",
+                               g_variant_new_string(dev_name));
+       g_variant_builder_add (builder, "{sv}", "SsidPostfix",
+                                g_variant_new_string(dev_name));
+       value = g_variant_new ("a{sv}", builder);
+       g_variant_builder_unref (builder);
+
+       param = g_variant_new("(ssv)", SUPPLICNAT_P2PDEVICE,
+                               "P2PDeviceConfig", value);
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       params.params = param;
+
+       res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
+       g_variant_unref(value);
+       g_variant_unref(param);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to set device name");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_get_dev_mac(char *dev_mac)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_get_go_intent(int *go_intent)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariant *param = NULL;
+       GVariant *reply = NULL;
+       GError *error = NULL;
+       GVariantIter *iter = NULL;
+
+
+       if (!go_intent) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+
+       param = g_variant_new("(ss)", SUPPLICNAT_P2PDEVICE, "P2PDeviceConfig");
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       reply = g_dbus_connection_call_sync (
+                       g_dbus,
+                       SUPPLICANT_SERVICE, /* bus name */
+                       SUPPLICANT_INTERFACE, /* object path */
+                       DBUS_PROPERTIES_INTERFACE, /* interface name */
+                       DBUS_PROPERTIES_METHOD_GET, /* method name */
+                       param, /* GVariant *params */
+                       NULL, /* reply_type */
+                       G_DBUS_CALL_FLAGS_NONE, /* flags */
+                       SUPPLICANT_TIMEOUT , /* timeout */
+                       NULL, /* cancellable */
+                       &error); /* error */
+
+       if(error != NULL) {
+               WDP_LOGE("Error! Failed to get interface State: [%s]",
+                               error->message);
+               g_error_free(error);
+               if(reply)
+                       g_variant_unref(reply);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       g_variant_unref(param);
+
+
+       if(reply != NULL){
+               g_variant_get(reply, "(a{sv})", &iter);
+
+               if(iter != NULL){
+
+                       gchar *key = NULL;
+                       GVariant *value = NULL;
+
+                       while(g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+                               CHECK_KEY_VALUE(key, value);
+                               if(g_strcmp0(key, "GOIntent") == 0)
+                                       g_variant_get(value, "u", go_intent);
+                       }
+                       g_variant_iter_free(iter);
+               }
+               g_variant_unref(reply);
+       }
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_set_go_intent(int go_intent)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+
+       GVariant *value = NULL;
+       GVariant *param = NULL;
+       GVariantBuilder *builder = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
+                        g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+       g_variant_builder_add (builder, "{sv}", "GOIntent",
+                               g_variant_new_uint32(go_intent));
+       value = g_variant_new ("a{sv}", builder);
+       g_variant_builder_unref (builder);
+
+       param = g_variant_new("(ssv)", SUPPLICNAT_P2PDEVICE, "P2PDeviceConfig", value);
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       params.params = param;
+
+       res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
+       g_variant_unref(value);
+       g_variant_unref(param);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGE("Succeeded to set go intent");
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_set_country(char *ccode)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+
+       GVariant *value = NULL;
+       GVariant *param = NULL;
+
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
+                        g_dbus);
+
+       value = g_variant_new_string(ccode);
+
+       param = g_variant_new("(ssv)", SUPPLICANT_IFACE, "Country", value);
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       params.params = param;
+
+       res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
+       g_variant_unref(value);
+       g_variant_unref(param);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to set country(%s)", ccode);
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+void __parsing_networks (const char *key, GVariant *value, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       if(!user_data) {
+               __WDP_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       ws_network_info_s *network = (ws_network_info_s *)user_data;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "ssid") == 0) {
+               const char *ssid = NULL;
+               g_variant_get(value, "s", &ssid);
+               WDP_LOGD("ssid [%s]", ssid);
+               g_strlcpy(network->ssid, ssid + 1, WS_SSID_LEN + 1);
+               network->ssid[strlen(ssid) - 2] = '\0';
+
+       } else if (g_strcmp0(key, "bssid") == 0) {
+               unsigned char *bssid = NULL;
+               g_variant_get(value, "s", &bssid);
+               WDP_LOGD("bssid [%s]", bssid);
+               __ws_txt_to_mac(bssid, network->bssid);
+
+       } else if (g_strcmp0(key, "mode") == 0) {
+
+       }
+       return;
+}
+
+void __ws_extract_p2pdevice_details(const char *key, GVariant *value, void *user_data)
+{
+
+       __WDP_LOG_FUNC_ENTER__;
+
+       CHECK_KEY_VALUE(key, value);
+
+       if (g_strcmp0(key, "PersistentGroups") == 0) {
+               GVariantIter *iter = NULL;
+               const char *path = NULL;
+               int num = 0;
+
+               ws_network_info_s *networks = NULL;
+               networks = (ws_network_info_s *)user_data;
+               if(!networks) {
+                       WDP_LOGE("network is NULL");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return;
+               }
+
+               g_variant_get(value, "ao", &iter);
+               while(g_variant_iter_loop(iter, "o", &path)) {
+                       if(num >= WS_MAX_PERSISTENT_COUNT)
+                               break;
+                       WDP_LOGD("Retrive persistent path [%s]", path);
+                       g_strlcpy(networks[num].persistent_path, path, DBUS_OBJECT_PATH_MAX);
+                       WDP_LOGD("Retrive persistent path [%s]", networks[num].persistent_path);
+                       dbus_property_get_all(networks[num].persistent_path, g_pd->g_dbus,
+                                       SUPPLICANT_P2P_PERSISTENTGROUP, __parsing_networks, &networks[num]);
+                       num++;
+               }
+               networks[0].total = num;
+               WDP_LOGE("total number [%d]", num);
+
+       }
+       __WDP_LOG_FUNC_EXIT__;
+}
+
+
+int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+
+       ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
+       wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
+       int i, cnt = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICNAT_P2PDEVICE, __ws_extract_p2pdevice_details, &networks[0]);
+
+       cnt = networks[0].total;
+
+       WDP_LOGD("Persistent Group Count=%d", cnt);
+       if (cnt > WS_MAX_PERSISTENT_COUNT) {
+               WDP_LOGE("Persistent group count exceeded or parsing error");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       wfd_persistent_groups = (wfd_oem_persistent_group_s*) g_try_malloc0(cnt * sizeof(wfd_oem_persistent_group_s));
+       for(i = 0; i < cnt; i++) {
+               WDP_LOGD("----persistent group [%d]----", i);
+               WDP_LOGD("network_id=%d", networks[i].network_id);
+               WDP_LOGD("ssid=%s", networks[i].ssid);
+               WDP_LOGD("bssid=" MACSTR, MAC2STR(networks[i].bssid));
+
+               wfd_persistent_groups[i].network_id = networks[i].network_id;
+               g_strlcpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN + 1);
+               memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
+       }
+
+       *group_count = cnt;
+       *groups = wfd_persistent_groups;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+
+       dbus_method_param_s params;
+       ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
+       int i, cnt = 0;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       dbus_property_get_all(g_pd->iface_path, g_dbus, SUPPLICNAT_P2PDEVICE, __ws_extract_p2pdevice_details, networks);
+
+       cnt = networks[0].total;
+
+       WDP_LOGD("Persistent Group Count=%d", cnt);
+       if (cnt > WS_MAX_PERSISTENT_COUNT) {
+               WDP_LOGE("Persistent group count exceeded or parsing error");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       for(i=0;i<cnt;i++) {
+               WDP_LOGD("----persistent group [%d]----", i);
+               WDP_LOGD("network_id=%d", networks[i].network_id);
+               WDP_LOGD("network ssid=%s", networks[i].ssid);
+               WDP_LOGD("network bssid=" MACSTR, MAC2STR(networks[i].bssid));
+
+               WDP_LOGD("ssid=%s", ssid);
+               WDP_LOGD("bssid=" MACSTR, MAC2STR(bssid));
+
+
+               if (!memcmp(bssid, networks[i].bssid, WS_MACADDR_LEN) &&
+                               !strcmp(ssid, networks[i].ssid)) {
+
+                       WDP_LOGD("Persistent group found [%d: %s]", networks[i].network_id, ssid);
+
+                       memset(&params, 0x0, sizeof(dbus_method_param_s));
+                       dbus_set_method_param(&params, "RemovePersistentGroup",
+                                       g_pd->iface_path, g_dbus);
+                       params.params = g_variant_new ("(o)", networks[i].persistent_path);
+
+                       WDP_LOGD("params [%s]", g_variant_print(params.params, TRUE));
+                       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+                       if (res < 0) {
+                               WDP_LOGE("Failed to send command to wpa_supplicant");
+                               __WDP_LOG_FUNC_EXIT__;
+                               return -1;
+                       }
+                       WDP_LOGD("Succeeded to remove persistent group");;
+                       break;
+               }
+       }
+
+       if (i == cnt) {
+               WDP_LOGE("Persistent group not found [%s]", ssid);
+               return -1;
+       }
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+
+       GVariant *value = NULL;
+       GVariant *param = NULL;
+       GVariantBuilder *builder = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, g_pd->iface_path,
+                       g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+       g_variant_builder_add (builder, "{sv}", "PersistentReconnect",
+                               g_variant_new_boolean(reconnect));
+       value = g_variant_new ("a{sv}", builder);
+       g_variant_builder_unref (builder);
+
+       param = g_variant_new("(ssv)", SUPPLICNAT_P2PDEVICE, "P2PDeviceConfig", value);
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       params.params = param;
+
+       res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
+       g_variant_unref(value);
+       g_variant_unref(param);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to set persistent reconnect");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+static int __ws_compress_query(char *compressed, char *query, int qtype)
+{
+       char *token = NULL;
+       char *temp = NULL;
+       int token_num = 0;
+       int token_len = 0;
+       int length = 0;
+
+       token = strtok_r(query, ".", &temp);
+       while (token) {
+               if (!strcmp(token, "local")) {
+                       WDP_LOGD("Query conversion done");
+                       break;
+
+               } else if (!strncmp(token, "_tcp", 4)) {
+                       memcpy(&compressed[length], WS_TCP_PTR_HEX, 2);
+                       length+=2;
+
+               } else if (!strncmp(token, "_udp", 4)) {
+                       memcpy(&compressed[length], WS_UDP_PTR_HEX, 2);
+                       length+=2;
+
+               } else {
+                       WDP_LOGD("Token: [%s]", token);
+                       token_len = strlen(token);
+                       compressed[length] = token_len;
+                       length++;
+
+                       memcpy(&compressed[length], token, token_len);
+                       length+=token_len;
+               }
+               token_num++;
+               token = strtok_r(NULL, ".", &temp);
+       }
+       if(qtype == WS_QTYPE_PTR || token_num == 2) {
+               memcpy(&compressed[length], WS_PTR_TYPE_HEX, 3);
+       } else if (qtype == WS_QTYPE_TXT || token_num == 3) {
+               memcpy(&compressed[length], WS_TXT_TYPE_HEX, 3);
+       }
+       length+=3;
+       WDP_LOGD("converted query length [%d] token num [%d]", length, token_num);
+
+       return length;
+}
+
+static int __ws_compress_rdata(char *compressed, char *rdata, int qtype)
+{
+       char *token = NULL;
+       char *temp = NULL;
+       int token_len = 0;
+       int length = 0;
+
+       if (qtype == WS_QTYPE_PTR) {
+
+               token = strtok_r(rdata, ".", &temp);
+               if (token) {
+                       WDP_LOGD("Token: %s", token);
+                       token_len = strlen(token);
+                       compressed[length] = token_len;
+                       length++;
+
+                       memcpy(&compressed[length], token, token_len);
+                       length+=token_len;
+               }
+
+               compressed[length] = 0xc0;
+               compressed[length+1] = 0x27;
+               length+=2;
+
+       } else if (qtype == WS_QTYPE_TXT) {
+
+               token = strtok_r(rdata, ",", &temp);
+
+               while (token) {
+                       WDP_LOGD("Token: [%s]", token);
+
+                       token_len = strlen(token);
+                       compressed[length] = token_len;
+                       length++;
+
+                       memcpy(&compressed[length], token, token_len);
+                       length+=token_len;
+
+                       token = strtok_r(NULL, ",", &temp);
+               }
+       } else {
+               WDP_LOGD("RDATA is NULL");
+       }
+       return length;
+}
+
+int _convert_bonjour_to_args(char *query, char *rdata, GVariantBuilder *builder)
+{
+       GVariantBuilder *args = NULL;
+       char compressed[256] = {0, };
+       char *temp = NULL;
+       int length = 0;
+       int qtype = 0;
+       int i = 0;
+
+       if (!query || !builder) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       if (!rdata || !strlen(rdata)) {
+               WDP_LOGD("RDATA is NULL\n");
+       } else {
+               temp = strstr(rdata, query);
+
+               if(temp != NULL && temp - rdata > 0)
+                       qtype = WS_QTYPE_PTR;
+               else
+                       qtype = WS_QTYPE_TXT;
+               temp = NULL;
+       }
+
+       /* compress query */
+       length = __ws_compress_query(compressed, query, qtype);
+
+       args = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+       for (i = 0; i < length; i++)
+               g_variant_builder_add(args, "y", compressed[i]);
+       g_variant_builder_add (builder, "{sv}", "query", g_variant_new ("ay", args));
+       g_variant_builder_unref (args);
+
+       memset(compressed, 0x0, 256);
+       length = 0;
+       args = NULL;
+
+       if(qtype != 0) {
+               length = __ws_compress_rdata(compressed, rdata, qtype);
+
+               args = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+               for (i = 0; i < length; i++)
+                       g_variant_builder_add(args, "y", compressed[i]);
+               g_variant_builder_add (builder, "{sv}", "response", g_variant_new ("ay", args));
+               g_variant_builder_unref (args);
+       }
+
+       return 0;
+}
+
+int _check_service_query_exists(wfd_oem_service_s *service)
+{
+       int count = 0;
+       wfd_oem_service_s *data = NULL;
+
+       for (count = 0; count < g_list_length(service_list); count ++) {
+               data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
+               if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
+                       WDP_LOGD("Query already exists");
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
+{
+       if (NULL == s_type || NULL == mac_str || NULL == query_id)
+               return NULL;
+
+       int count = 0;
+       wfd_oem_service_s *data = NULL;
+
+       for (count = 0; count < g_list_length(service_list); count ++) {
+               data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
+               if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
+                               memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
+                       strncpy(query_id, data->query_id, OEM_QUERY_ID_LEN);
+                       break;
+               }
+       }
+       if (strlen(query_id) <= 0) {
+               WDP_LOGD("!! Query ID not found !!");
+               return NULL;
+       }
+
+       WDP_LOGD("query id :[0x%s]",query_id);
+
+       return data;
+}
+
+void __add_service_query(GVariant *value, void *mac_addr)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_service_s *service = NULL;
+
+       long long unsigned ref = 0;
+       unsigned char *mac_address = (unsigned char *)mac_addr;
+       char mac_str[18] = {0, };
+
+       int res = 0;
+
+       g_variant_get(value, "(t)", &ref);
+
+       service = (wfd_oem_service_s*) g_try_malloc0(sizeof(wfd_oem_service_s));
+       if (!service) {
+               WDP_LOGE("Failed to allocate memory for service");
+               return;
+       }
+
+       if (mac_address[0] == 0 && mac_address[1] == 0 && mac_address[2] == 0 &&
+                       mac_address[3] == 0 && mac_address[4] == 0 && mac_address[5] == 0) {
+               g_snprintf(mac_str, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
+       } else {
+               g_snprintf(mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_address));
+       }
+
+       g_strlcpy(service->dev_addr, mac_str, OEM_MACSTR_LEN);
+       g_snprintf(service->query_id, OEM_QUERY_ID_LEN + 1, "0x%llx", ref);
+
+       res = _check_service_query_exists(service);
+       if(res) {
+               free(service);
+       } else {
+               service_list = g_list_append(service_list, service);
+       }
+
+       __WDP_LOG_FUNC_EXIT__;
+       return;
+
+}
+
+/* for now, supplicant dbus interface only provides upnp service fully */
+int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       static char peer_path[DBUS_OBJECT_PATH_MAX] = {'\0',};
+       int i = 0;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "ServiceDiscoveryRequest", g_pd->iface_path, g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+
+       if(mac_addr) {
+               g_snprintf(peer_path, DBUS_OBJECT_PATH_MAX, "%s/Peers/"
+                               COMPACT_MACSTR, g_pd->iface_path, MAC2STR(mac_addr));
+               WDP_LOGD("get peer path [%s]", peer_path);
+               g_variant_builder_add (builder, "{sv}", "peer", g_variant_new_object_path(peer_path));
+       }
+
+       if (service_type == WFD_OEM_SERVICE_TYPE_ALL) {
+
+               char *service_all = "\x02\x00\x00\x01";
+               GVariantBuilder *query = NULL;
+
+               query = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+               for (i = 0; i < SERVICE_QUERY_LEN; i++)
+                       g_variant_builder_add(query, "y", service_all[i]);
+               g_variant_builder_add (builder, "{sv}", "query", g_variant_new ("ay", query));
+               g_variant_builder_unref (query);
+
+               } else if (service_type == WFD_OEM_SERVICE_TYPE_UPNP) {
+
+               g_variant_builder_add (builder, "{sv}", "service_type", g_variant_new_string("upnp"));
+               g_variant_builder_add (builder, "{sv}", "version", g_variant_new_uint16(TRUE));
+
+       } else if (service_type == WFD_OEM_SERVICE_TYPE_BONJOUR) {
+
+               char *service_bonjour = "\x02\x00\x01\x01";
+               GVariantBuilder *query = NULL;
+
+               query = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+               for (i = 0; i < SERVICE_QUERY_LEN; i++)
+                       g_variant_builder_add(query, "y", service_bonjour[i]);
+               g_variant_builder_add (builder, "{sv}", "query", g_variant_new ("ay", query));
+               g_variant_builder_unref (query);
+       }
+
+       value = g_variant_new ("(a{sv})", builder);
+       g_variant_builder_unref (builder);
+
+       WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, __add_service_query, mac_addr);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to start service discovery");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       dbus_method_param_s params;
+       wfd_oem_service_s *data = NULL;
+       char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
+       char s_type[OEM_SERVICE_TYPE_LEN + 1] ={0, };
+       char mac_str[18] = {0, };
+
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+
+       if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
+               mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
+               snprintf(mac_str, WS_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
+       } else {
+               snprintf(mac_str, WS_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
+       }
+
+       switch(service_type) {
+               case WFD_OEM_SERVICE_TYPE_ALL:
+                       strncpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN);
+               break;
+               case WFD_OEM_SERVICE_TYPE_BONJOUR:
+                       strncpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN);
+               break;
+               case WFD_OEM_SERVICE_TYPE_UPNP:
+                       strncpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN);
+               break;
+               case WFD_OEM_SERVICE_TYPE_BT_ADDR:
+                       strncpy(s_type, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
+                       break;
+               case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
+                       strncpy(s_type, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
+                       break;
+               default:
+                       __WDP_LOG_FUNC_EXIT__;
+                       WDP_LOGE("Invalid Service type");
+                       return -1;
+       }
+
+       WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
+       WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
+
+       data = _remove_service_query(s_type, mac_str, query_id);
+       if (NULL == data)
+               return -1;
+
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "ServiceDiscoveryCancelRequest", g_pd->iface_path, g_dbus);
+
+       params.params = g_variant_new ("(t)", strtoul(query_id, NULL, 16));
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to cancel service discovery");
+
+       service_list = g_list_remove(service_list, data);
+       free(data);
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_serv_add(wfd_oem_new_service_s *service)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "AddService", g_pd->iface_path, g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}") );
+
+       if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
+
+               WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
+               WDP_LOGD("Query: %s", service->data.bonjour.query);
+               WDP_LOGD("RData: %s", service->data.bonjour.rdata);
+
+               res = _convert_bonjour_to_args(service->data.bonjour.query,
+                                                           service->data.bonjour.rdata, builder);
+               if (res < 0) {
+                       WDP_LOGE("Failed to convert Key string");
+                       g_variant_builder_unref (builder);
+                       return -1;
+               }
+
+       } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
+               g_variant_builder_add (builder, "{sv}", "service_type", g_variant_new_string("upnp"));
+               g_variant_builder_add (builder, "{sv}", "version", g_variant_new_uint16(TRUE));
+               g_variant_builder_add (builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
+       }
+
+       value = g_variant_new ("(a{sv})", builder);
+       g_variant_builder_unref (builder);
+
+       WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to add service");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int ws_serv_del(wfd_oem_new_service_s *service)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, "DeleteService", g_pd->iface_path, g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+
+       if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
+
+               WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
+               WDP_LOGD("Query: %s", service->data.bonjour.query);
+
+               res = _convert_bonjour_to_args(service->data.bonjour.query,
+                                                           NULL, builder);
+               if (res < 0) {
+                       WDP_LOGE("Failed to convert Key string");
+                       g_variant_builder_unref (builder);
+                       return -1;
+               }
+
+       } else if (service->protocol == WFD_OEM_SERVICE_TYPE_UPNP) {
+               g_variant_builder_add (builder, "{sv}", "service_type", g_variant_new_string("upnp"));
+               g_variant_builder_add (builder, "{sv}", "version", g_variant_new_uint16(TRUE));
+               g_variant_builder_add (builder, "{sv}", "service", g_variant_new_string(service->data.upnp.service));
+       }
+
+       value = g_variant_new ("(a{sv})", builder);
+       g_variant_builder_unref (builder);
+
+       WDP_LOGE("params [%s]", g_variant_print(value, TRUE));
+
+       params.params = value;
+
+       res = dbus_method_call(&params, SUPPLICNAT_P2PDEVICE, NULL, NULL);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to del service");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+
+int _ws_disable_display()
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+       GVariantBuilder *builder = NULL;
+       GVariant *value = NULL;
+       GVariant *param = NULL;
+       dbus_method_param_s params;
+       int res = 0;
+
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
+                        g_dbus);
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+       value = g_variant_new ("ay", builder);
+       g_variant_builder_unref (builder);
+
+       param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       params.params = param;
+
+       res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
+       g_variant_unref(value);
+       g_variant_unref(param);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to disable Wi-Fi display");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_miracast_init(int enable)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       wfd_oem_display_s wifi_display;
+       int res = 0;
+
+       memset(&wifi_display, 0x0, sizeof(wfd_oem_display_s));
+
+       wifi_display.availablity = enable;
+       wifi_display.hdcp_support = 1;
+       wifi_display.port = 0x07E6;
+       wifi_display.max_tput = 0x0028;
+
+       res = ws_set_display(&wifi_display);
+       if (res < 0) {
+               WDP_LOGE("Failed to set miracast parameter(device info)");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if(!enable) {
+               res = _ws_disable_display();
+               if (res < 0)
+                       WDP_LOGE("Failed to disable wifi display");
+               else
+                       WDP_LOGD("Succeeded to disable wifi display");
+       }
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+
+int ws_set_display(wfd_oem_display_s *wifi_display)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       GDBusConnection *g_dbus = NULL;
+
+       GVariant *value = NULL;
+       GVariant *param = NULL;
+       GVariantBuilder *builder = NULL;
+       dbus_method_param_s params;
+       int i = 0;
+       int res = 0;
+
+       unsigned char ies[WFD_SUBELEM_LEN_DEV_INFO + 3] = {0,};
+
+       if (!wifi_display) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+       g_dbus = g_pd->g_dbus;
+       if (!g_dbus) {
+               WDP_LOGE("DBus connection is NULL");
+               return -1;
+       }
+       memset(&params, 0x0, sizeof(dbus_method_param_s));
+
+       dbus_set_method_param(&params, DBUS_PROPERTIES_METHOD_SET, SUPPLICANT_PATH,
+                        g_dbus);
+
+       ies[2] = WFD_SUBELEM_LEN_DEV_INFO;
+       ies[3] = wifi_display->hdcp_support;
+       ies[4] = (wifi_display->type) | (wifi_display->availablity<<4);
+       ies[5] = wifi_display->port>>8;
+       ies[6] = wifi_display->port&0xff;
+       ies[7] = wifi_display->max_tput>>8;
+       ies[8] = wifi_display->max_tput&0xff;
+
+       builder = g_variant_builder_new (G_VARIANT_TYPE ("ay"));
+       for(i = 0; i < WFD_SUBELEM_LEN_DEV_INFO + 3; i++)
+               g_variant_builder_add(builder, "y", ies[i]);
+       value = g_variant_new ("ay", builder);
+       g_variant_builder_unref (builder);
+
+       WDP_LOGD("value [%s]", g_variant_print(value,TRUE));
+
+       param = g_variant_new("(ssv)", SUPPLICANT_INTERFACE, "WFDIEs", value);
+       WDP_LOGE("param [%s]", g_variant_print(param,TRUE));
+
+       params.params = param;
+
+       res = dbus_method_call(&params, DBUS_PROPERTIES_INTERFACE, NULL, NULL);
+       g_variant_unref(value);
+       g_variant_unref(param);
+       if (res < 0)
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+       else
+               WDP_LOGD("Succeeded to set Wi-Fi Display");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return res;
+}
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+int ws_refresh()
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       _ws_cancel();
+       _ws_flush();
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
diff --git a/plugin/wpasupplicant/ctrl_iface_sock/CMakeLists.txt b/plugin/wpasupplicant/ctrl_iface_sock/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..bd1747f
--- /dev/null
@@ -0,0 +1,28 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(wifi-direct-plugin-wpasupplicant C)
+
+# Set required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED capi-network-wifi-direct glib-2.0 gio-2.0 dlog)
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/oem)
+INCLUDE_DIRECTORIES(SRCS include)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+SET(SRCS
+       wfd-plugin-wpasupplicant.c
+       )
+
+# library build
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+#SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.1.0)
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME})
+
+# install
+INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib)
old mode 100644 (file)
new mode 100755 (executable)
similarity index 77%
rename from plugin/wpasupplicant/wfd-plugin-wpasupplicant.h
rename to plugin/wpasupplicant/ctrl_iface_sock/include/wfd-plugin-wpasupplicant.h
index 0cb4673..c11b5d4
 #define WDP_LOGE(format, args...) LOGE(format, ##args)
 #define WDP_LOGF(format, args...) LOGF(format, ##args)
 
-#define __WDP_LOG_FUNC_ENTER__ LOGV("Enter")
-#define __WDP_LOG_FUNC_EXIT__ LOGV("Quit")
+#define __WDP_LOG_FUNC_ENTER__ LOGD("Enter")
+#define __WDP_LOG_FUNC_EXIT__ LOGD("Quit")
+
+#define WDP_SECLOGI(format, args...) SECURE_LOG(LOG_INFO, LOG_TAG, format, ##args)
+#define WDP_SECLOGD(format, args...) SECURE_LOG(LOG_DEBUG, LOG_TAG, format, ##args)
 
 #else /* USE_DLOG */
 
 #define __WDP_LOG_FUNC_ENTER__
 #define __WDP_LOG_FUNC_EXIT__
 
+#define WDP_SECLOGI(format, args...)
+#define WDP_SECLOGD(format, args...)
+
 #endif /* USE_DLOG */
 
 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+#define IP2STR(a) (a)[0], (a)[1], (a)[2], (a)[3]
+#define IPSTR "%d.%d.%d.%d"
+#define MAC2SECSTR(a) (a)[0], (a)[4], (a)[5]
+#define MACSECSTR "%02x:%02x:%02x"
+#define IP2SECSTR(a) (a)[0], (a)[3]
+#define IPSECSTR "%d..%d"
+
+#if !defined TIZEN_TV
+#define DEFAULT_MAC_FILE_PATH "/opt/etc/.mac.info"
+#else
+#define DEFAULT_MAC_FILE_PATH "/sys/class/net/p2p0/address"
+#endif
 
+#define SOCK_FD_MIN 3
 #define GLOBAL_INTF_PATH "/tmp/wpa_ctrl_global"
 #define SUPPL_GLOBAL_INTF_PATH "/var/run/wpa_global"
 #define SUPPL_IFACE_PATH "/var/run/wpa_supplicant/"
-#define SOCK_FD_MIN 3
-
+#define SUPPL_GROUP_IFACE_PATH "/var/run/wpa_supplicant/"
+
+#if defined TIZEN_TV
+/*For TIZEN TV Platform*/
+#define COMMON_IFACE_NAME "p2p0"
+#define GROUP_IFACE_NAME "p2p0"
+#define GROUP_IFACE_PREFIX "p2p"
+#else /*TIZEN_TV*/
 #define COMMON_IFACE_NAME "wlan0"
 #define GROUP_IFACE_NAME "p2p-wlan0-0"
+#define GROUP_IFACE_PREFIX "p2p-wlan0-"
+#endif /*TIZEN_TV*/
 
 #define WS_POLL_TIMEOUT 5000
 #define WS_CONN_RETRY_COUNT 10
 #define WS_PINSTR_LEN 8
 #define WS_DEVTYPESTR_LEN 14
+#define WS_REPLY_LEN 1024
 #define WS_SSID_LEN 32
 #define WS_MACSTR_LEN 18
 #define WS_MACADDR_LEN 6
 #define WS_NETFLAG_LEN 32
 #define WS_MAX_PERSISTENT_COUNT 20
+#define WS_SCAN_RETRY_COUNT 10
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+#define BT_ADDR_PATH "/csa/bluetooth/.bd_addr"
+
+#define SERV_DISC_REQ_ALL "02000001"
+#define SERV_DISC_REQ_BONJOUR "02000101"
+#define SERV_DISC_REQ_UPNP "02000201"
 
-#define SERVICE_TYPE_ALL "02000001"
-#define SERVICE_TYPE_BONJOUR "02000102"
-#define SERVICE_TYPE_UPNP "02000203"
-#define SERVICE_TYPE_VENDOR_SPECIFIC "0200ff04"
-#define CMD_LENGTH 80
+#define SAMSUNG_VENDOR_OUI "0000f0"
+#define SAMSUNG_SERVICE_BT "0b"
+#define SAMSUNG_SERVICE_CONTACT "0d"
+#define SAMSUNG_SERVICE_ALL "0c"
+
+#define SERVICE_TYPE_BT_ADDR "0000f00b"
+#define SERVICE_TYPE_ALL "0000f00c"
+#define SERVICE_TYPE_CONTACT_INFO "0000f00d"
+#define SERVICE_TYPE_LEN 8
+#define SERV_BROADCAST_ADDRESS "00:00:00:00:00:00"
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
 /* Config Method bitmap */
 #define WS_CONFIG_METHOD_DISPLAY 0x0008
 #define WS_CMD_WPS_CANCEL "WPS_CANCEL"
 #define WS_CMD_SET "SET "
 #define WS_CMD_GET "GET "
+#define WS_CMD_P2P_SET "P2P_SET "
 #define WS_CMD_STATUS "STATUS"
 #define WS_CMD_STATUS_P2P "STATUS P2P"
 #define WS_CMD_LOG_LEVEL "LOG_LEVEL"
 #define WS_CMD_LIST_NETWORKS "LIST_NETWORKS"
 #define WS_CMD_REMOVE_NETWORK "REMOVE_NETWORK"
 
+#define WS_CMD_DISCONNECT "P2P_DISCONNECT "
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+#define WS_CMD_SERVICE_ADD "P2P_SERVICE_ADD"
+#define WS_CMD_SERVICE_DEL "P2P_SERVICE_DEL"
+#define WS_CMD_SERV_DISC_REQ "P2P_SERV_DISC_REQ"
+#define WS_CMD_SERV_DISC_CANCEL "P2P_SERV_DISC_CANCEL_REQ"
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#define WS_CMD_SUBELEM_SET "WFD_SUBELEM_SET "
+
 #define WS_STR_PBC " pbc"
 #define WS_STR_DISPLAY " display"
 #define WS_STR_KEYPAD " keypad"
 #define WS_STR_JOIN " join"
 #define WS_STR_AUTH " auth"
 #define WS_STR_PERSISTENT " persistent"
+#define WS_STR_FREQ " freq="
 #define WS_STR_FREQ_2G " freq=2"
-#define WS_STR_WIFI_DISPLAY "wifi_display"
 
-#define WS_CMD_P2P_SERVICE_ADD "P2P_SERVICE_ADD "
-#define WS_CMD_P2P_SERVICE_DEL "P2P_SERVICE_DEL "
-#define WS_CMD_P2P_SERV_DISC_REQ "P2P_SERV_DISC_REQ "
-#define WS_CMD_P2P_SERV_DISC_CANCEL "P2P_SERV_DISC_CANCEL_REQ "
+#define WS_STR_ATTR_LISTEN_CLASS "p2p_listen_reg_class"
+#define WS_STR_ATTR_OPER_CLASS "p2p_oper_reg_class"
 
-#define WS_CMD_WFD_SUBELEM_SET "WFD_SUBELEM_SET "
-#define WS_CMD_WFD_SUBELEM_GET "WFD_SUBELEM_GET "
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+#define WS_WFD_INFO_PRIMARY_SINK 0x01
+#define WS_WFD_INFO_SECONDARY_SINK 0x02
+#define WS_WFD_INFO_AVAILABLITY 0x10
+#define WS_WFD_INFO_WSD_SUPPORT 0x40
+#define WS_WFD_INFO_TDLS_SUPPORT 0x80
+#define WS_WFD_INFO_HDCP_SUPPORT 0x100
+#define WS_WFD_INFO_SYNC_SUPPORT 0x200
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
 typedef enum {
        WS_IFTYPE_NONE,
@@ -198,9 +257,11 @@ typedef enum {
        WS_EVENT_GROUP_STARTED,
        WS_EVENT_GROUP_REMOVED,
 
-       WS_EVENT_SERV_DISC_RESP,
+       WS_EVENT_TERMINATING,   // 24
 
-       WS_EVENT_TERMINATING,
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       WS_EVENT_SERV_DISC_RESP,
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
        WS_EVENT_LIMIT,
 } ws_event_id_e;
@@ -215,8 +276,9 @@ typedef enum {
        WS_DEV_INFO_DEV_CAP,    // dev_capab=
        WS_DEV_INFO_GROUP_CAP,  // group_capab=
        WS_DEV_INFO_P2P_GO_ADDR,        // p2p_go_addr=
-       WS_DEV_INFO_WFD_SUBELEMS,       // wfd_subelems=
-
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       WS_DEV_INFO_WFD_DEV_INFO,       // wfd_dev_info=
+#endif
        WS_DEV_INFO_LIMIT,
 } ws_dev_info_id_e;
 
@@ -274,7 +336,6 @@ enum
        WS_PEER_INFO_CONFIG_METHODS,
        WS_PEER_INFO_DEV_CAPAB,
        WS_PEER_INFO_GROUP_CAPAB,
-       WS_PEER_INFO_IS_WFD_DEVICE,
        WS_PEER_INFO_GO_NEG_REQ_SENT,
        WS_PEER_INFO_GO_STATE,
        WS_PEER_INFO_DIALOG_TOKEN,
@@ -286,7 +347,9 @@ enum
        WS_PEER_INFO_STATUS,
        WS_PEER_INFO_WAIT_COUNT,
        WS_PEER_INFO_INVITATION_REQS,
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
        WS_PEER_INFO_WFD_SUBELEMS,
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
        WS_PEER_INFO_LIMIT,
 } ws_peer_info_id_e;
@@ -326,7 +389,7 @@ typedef enum {
        WS_DEVICE_CAP_INVITATION_PROCEDURE = 0x20,
 } ws_device_cap_flag_e;
 
-typedef enum { 
+typedef enum {
        /* The P2P Group Owner field shall be set to 1
         * when the P2P Device is operating as a Group Owner,
         * and set to 0 otherwise. */
@@ -378,61 +441,32 @@ typedef enum {
         * its PIN password (from the label or display). This password may
         * correspond to the label, display, or a user-defined password
         * that has been configured to replace the original device password. */
-       DEV_PASSWD_ID_DEFAULT = 0x0000,
+       WS_DEV_PASSWD_ID_DEFAULT = 0x0000,
 
        /* User-specified indicates that the user has overridden the password
         * with a manually selected value. */
-       DEV_PASSWD_ID_USER_SPECIFIED = 0x0001,
+       WS_DEV_PASSWD_ID_USER_SPECIFIED = 0x0001,
 
        /* Machine-specified indicates that the original PIN password has been
         * overridden by a strong, machine-generated device password value. */
-       DEV_PASSWD_ID_MACHINE_SPECIFIED = 0x0002,
+       WS_DEV_PASSWD_ID_MACHINE_SPECIFIED = 0x0002,
 
        /* The Rekey value indicates that the device's 256-bit rekeying
         * password will be used. */
-       DEV_PASSWD_ID_REKEY = 0x0003,
+       WS_DEV_PASSWD_ID_REKEY = 0x0003,
 
        /* The PushButton value indicates that the PIN is the all-zero value
         * reserved for the Push Button Configuration method. */
-       DEV_PASSWD_ID_PUSH_BUTTON = 0x0004,
+       WS_DEV_PASSWD_ID_PUSH_BUTTON = 0x0004,
 
        /* The Registrar-specified value indicates a PIN that has been
         * obtained from the Registrar (via a display or other out-of-band
         * method). This value may be further augmented with the optional
         * "Identity" attribute in M1. */
-       DEV_PASSWD_ID_REGISTRAR_SPECIFIED = 0x0005,     // ENTER-PIN
+       WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED = 0x0005,  // ENTER-PIN
 } ws_dev_passwd_id_e;
 
 typedef enum {
-       WFD_SUBELEM_ID_DEVICE_INFO = 0,
-       WFD_SUBELEM_ID_ASSOCIATED_BSSID = 1,
-       WFD_SUBELEM_ID_AUDIO_FORMATS = 2,
-       WFD_SUBELEM_ID_VIDEO_FORMATS = 3,
-       WFD_SUBELEM_ID_3D_VIDEO_FORMATS = 4,
-       WFD_SUBELEM_ID_CONTENT_PROTECTION = 5,
-       WFD_SUBELEM_ID_COUPLED_SINK = 6,
-       WFD_SUBELEM_ID_EXT_CAPAB = 7,
-       WFD_SUBELEM_ID_LOCAL_IP_ADDRESS = 8,
-       WFD_SUBELEM_ID_SESSION_INFO = 9,
-       WFD_SUBELEM_ID_ALT_MAC_ADDRESS = 10,
-}ws_wfd_subelem_id_e;
-
-typedef enum {
-       WFD_DEVICE_TYPE = 0x0003,
-       WFD_DEVICE_COUPLED_SINK_OPERATION_SUPPORT_AT_WFD_SOURCE = 0x0004,
-       WFD_DEVICE_COUPLED_SINK_OPERATION_SUPPORT_AT_WFD_SINK = 0x0008,
-       WFD_DEVICE_SESSION_AVAILABILITY = 0x0030,
-       WFD_DEVICE_SERVICE_DISCOVERY_SUPPORT = 0x0040,
-       WFD_DEVICE_PREFERRED_CONNECTIVITY = 0x0080,
-       WFD_DEVICE_CONTENT_PROTECTION_SUPPORT = 0x0100,
-       WFD_DEVICE_TIME_SYNCHRONIZATION_SUPPORT = 0x0200,
-       WFD_DEVICE_AUDIO_UNSUPPORTED_AT_PRIMARY_SINK = 0x0400,
-       WFD_DEVICE_AUDIO_ONLY_SUPPORT_AT_WFD_SOURCE = 0x0800,
-       WFD_DEVICE_TDLS_PERSISTENT_GROUP = 0x1000,
-       WFD_DEVICE_TDLS_PERSISTENT_GROUP_REINVOKE = 0x2000,
-}ws_wfd_device_info_e;
-
-typedef enum {
        WPS_ERROR_NONE,
 
        WPS_ERROR_OOBINFO_READ_FAIL,
@@ -456,6 +490,26 @@ typedef enum {
        WPS_ERROR_PASSWORD_MISMATCH,
 } ws_wps_error_e;
 
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+typedef enum {
+       WFD_SUBELM_ID_DEV_INFO,
+       WFD_SUBELM_ID_ASSOC_BSSID,
+       WFD_SUBELM_ID_AUDIO_FORMAT,
+       WFD_SUBELM_ID_VIDEO_FORMAT,
+       WFD_SUBELM_ID_3D_FORMAT,
+       WFD_SUBELM_ID_CONTENT_PROTECTION,
+
+       WFD_SUBELM_ID_CUPLED_SYNC_INFO,
+       WFD_SUBELM_ID_EXT_CAPAB,
+       WFD_SUBELM_ID_LOCAL_IP,
+       WFD_SUBELM_ID_SESSION_INFO,
+       WFD_SUBELM_ID_ALT_MAC,
+} ws_wfd_subelm_id_e;
+#define WFD_SUBELEM_LEN_DEV_INFO 6
+#define WFD_SUBELM_LEN_ASSOC_BSSID 6
+#define WFD_SUBELM_LEN_CUPLED_SYNC_INFO 7
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
 typedef struct {
        char *string;
        int index;
@@ -487,21 +541,19 @@ typedef struct {
 typedef struct {
        int initialized;        // check whether plugin is initialized or not. block init function if initialized
        int activated;
+       int concurrent;
        int global_sock;
        ws_sock_data_s *common;
        ws_sock_data_s *group;
-       int group_cnt;
-
-       unsigned char pd_addr[OEM_MACADDR_LEN];
-
+       unsigned char local_dev_addr[WS_MACADDR_LEN];
        wfd_oem_event_cb callback;
        void *user_data;
 } ws_plugin_data_s;
 
 int ws_init(wfd_oem_event_cb callback, void *user_data);
 int ws_deinit();
-int ws_activate();
-int ws_deactivate();
+int ws_activate(int concurrent);
+int ws_deactivate(int concurrent);
 int ws_start_scan(wfd_oem_scan_param_s *param);
 int ws_restart_scan(int freq);
 int ws_stop_scan();
@@ -518,7 +570,7 @@ int ws_get_connected_peers(GList **peers, int *peer_count);
 int ws_get_pin(char *pin);
 int ws_set_pin(char *pin);
 int ws_get_supported_wps_mode();
-int ws_create_group(int persistent, int freq);
+int ws_create_group(int persistent, int freq, const char *passphrase);
 int ws_destroy_group(const char *ifname);
 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param);
 int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin);
@@ -531,16 +583,25 @@ int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type);
 int ws_set_dev_type(int pri_dev_type, int sec_dev_type);
 int ws_get_go_intent(int *go_intent);
 int ws_set_go_intent(int go_intent);
+int ws_set_country(char *ccode);
+
 int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count);
 int ws_remove_persistent_group(char *ssid, unsigned char *bssid);
 int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect);
 
-int ws_service_add(wfd_oem_service_e type,char *data);
-int ws_service_del(wfd_oem_service_e type,char *data);
-int ws_serv_disc_req(unsigned char* MAC, wfd_oem_service_e type,char *data);
-int ws_serv_disc_cancel(int identifier);
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+int ws_start_service_discovery(unsigned char *mac_addr, int service_type);
+int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type);
+
+int ws_serv_add(wfd_oem_new_service_s *service);
+int ws_serv_del(wfd_oem_new_service_s *service);
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int ws_miracast_init(int enable);
+int ws_set_display(wfd_oem_display_s *wifi_display);
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
-int ws_init_wifi_display(wfd_oem_display_e type, int port, int hdcp);
-int ws_deinit_wifi_display();
+int ws_refresh();
 
 #endif /* __WFD_PLUGIN_WPASUPPLICANT_H__ */
@@ -29,9 +29,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include <sys/wait.h>
 #include <unistd.h>
 #include <fcntl.h>
 #define _GNU_SOURCE
 #include <net/if.h>
 
 #include <glib.h>
+#include <gio/gio.h>
 
 #include "wifi-direct-oem.h"
 #include "wfd-plugin-wpasupplicant.h"
 
+#define NETCONFIG_SERVICE                              "net.netconfig"
+#define NETCONFIG_WIFI_INTERFACE               "net.netconfig.wifi"
+#define NETCONFIG_WIFI_PATH                            "/net/netconfig/wifi"
+
+#define NETCONFIG_DBUS_REPLY_TIMEOUT   (10 * 1000)
+
 ws_string_s ws_event_strs[] = {
        // discovery
        {"P2P-DEVICE-FOUND", WS_EVENT_DEVICE_FOUND},
@@ -60,6 +67,7 @@ ws_string_s ws_event_strs[] = {
 
        // connection
        {"P2P-GO-NEG-REQUEST", WS_EVENT_GO_NEG_REQUEST},
+       {"P2P: Received GO Negotiation Request from", WS_EVENT_GO_NEG_REQUEST},
        {"P2P-GO-NEG-FAILURE", WS_EVENT_GO_NEG_FAILURE},
        {"P2P-GO-NEG-SUCCESS", WS_EVENT_GO_NEG_SUCCESS},
        {"WPS-FAIL", WS_EVENT_WPS_FAIL},
@@ -82,10 +90,13 @@ ws_string_s ws_event_strs[] = {
        {"P2P-GROUP-STARTED", WS_EVENT_GROUP_STARTED},
        {"P2P-GROUP-REMOVED", WS_EVENT_GROUP_REMOVED},
 
-       //service
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
        {"P2P-SERV-DISC-RESP", WS_EVENT_SERV_DISC_RESP},
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
        {"CTRL-EVENT-TERMINATING", WS_EVENT_TERMINATING},
+
+       {"", WS_EVENT_LIMIT},
        };
 
 ws_string_s ws_dev_info_strs[] = {
@@ -96,7 +107,9 @@ ws_string_s ws_dev_info_strs[] = {
        {"dev_capab", WS_DEV_INFO_DEV_CAP},
        {"group_capab", WS_DEV_INFO_GROUP_CAP},
        {"p2p_go_addr", WS_DEV_INFO_P2P_GO_ADDR},
-       {"wfd_subelems", WS_DEV_INFO_WFD_SUBELEMS},
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       {"wfd_dev_info", WS_DEV_INFO_WFD_DEV_INFO},
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
        {"", WS_DEV_INFO_LIMIT},
        };
 
@@ -143,7 +156,6 @@ ws_string_s ws_peer_info_strs[] = {
        {"config_methods", WS_PEER_INFO_CONFIG_METHODS},
        {"dev_capab", WS_PEER_INFO_DEV_CAPAB},
        {"group_capab", WS_PEER_INFO_GROUP_CAPAB},
-       {"is_wfd_device", WS_PEER_INFO_IS_WFD_DEVICE},
        {"go_neg_req_sent", WS_PEER_INFO_GO_NEG_REQ_SENT},
        {"go_state", WS_PEER_INFO_GO_STATE},
        {"dialog_token", WS_PEER_INFO_DIALOG_TOKEN},
@@ -155,7 +167,23 @@ ws_string_s ws_peer_info_strs[] = {
        {"status", WS_PEER_INFO_STATUS},
        {"wait_count", WS_PEER_INFO_WAIT_COUNT},
        {"invitation_reqs", WS_PEER_INFO_INVITATION_REQS},
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
        {"wfd_subelems", WS_PEER_INFO_WFD_SUBELEMS},
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+       };
+
+ws_string_s ws_conf_attr_strs[] = {
+       {"device_name", WFD_OEM_CONFIG_ATTR_STR_DEVICE_NAME},
+       {"p2p_ssid_postfix", WFD_OEM_CONFIG_ATTR_STR_SSID_POSTFIX},
+       {"country", WFD_OEM_CONFIG_ATTR_STR_COUNTRY},
+       {"p2p_go_intent", WFD_OEM_CONFIG_ATTR_NUM_GO_INTENT},
+       {"p2p_listen_channel", WFD_OEM_CONFIG_ATTR_NUM_LISTEN_FREQ},
+       {"p2p_oper_channel", WFD_OEM_CONFIG_ATTR_NUM_OPER_FREQ},
+       {"p2p_pref_chan", WFD_OEM_CONFIG_ATTR_NUM_PREF_FREQ},
+       {"persistent_reconnect", WFD_OEM_CONFIG_ATTR_NUM_PERSIST_RECONN},
+       {"wifi_display", WFD_OEM_CONFIG_ATTR_NUM_WIFI_DISPLAY},
+       {"p2p_disabled", WFD_OEM_CONFIG_ATTR_NUM_P2P_DISABLED},
+       {"max_num_sta", WFD_OEM_CONFIG_ATTR_NUM_MAX_STA},
        };
 
 static wfd_oem_ops_s supplicant_ops = {
@@ -197,21 +225,35 @@ static wfd_oem_ops_s supplicant_ops = {
        .set_dev_type = ws_set_dev_type,
        .get_go_intent = ws_get_go_intent,
        .set_go_intent = ws_set_go_intent,
+       .set_country = ws_set_country,
        .get_persistent_groups = ws_get_persistent_groups,
        .remove_persistent_group = ws_remove_persistent_group,
        .set_persistent_reconnect = ws_set_persistent_reconnect,
 
-       .service_add = ws_service_add,
-       .service_del = ws_service_del,
-       .serv_disc_req = ws_serv_disc_req,
-       .serv_disc_cancel = ws_serv_disc_cancel,
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       .start_service_discovery = ws_start_service_discovery,
+       .cancel_service_discovery = ws_cancel_service_discovery,
+
+       .serv_add = ws_serv_add,
+       .serv_del = ws_serv_del,
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       .miracast_init = ws_miracast_init,
+       .set_display = ws_set_display,
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       .refresh = ws_refresh,
 
-       .init_wifi_display = ws_init_wifi_display,
-       .deinit_wifi_display= ws_deinit_wifi_display,
        };
 
 static ws_plugin_data_s *g_pd;
-static unsigned char null_mac[OEM_MACADDR_LEN];
+static unsigned char g_pd_out[OEM_MACADDR_LEN];
+static unsigned char null_mac[OEM_MACADDR_LEN] = {0, 0, 0, 0, 0, 0};
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+static GList *service_list;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
 static gboolean ws_event_handler(GIOChannel *source,
                                                           GIOCondition condition,
@@ -229,6 +271,83 @@ int wfd_plugin_load(wfd_oem_ops_s **ops)
        return 0;
 }
 
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+static int _change_str_order(char *src, int length, int unit, char *dest)
+{
+       int i = 0;
+
+       if (!src || length < 0 || length < unit || !dest) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       for (i=0; i<length/unit; i++)
+               memcpy(dest + length - (i+1)*unit, src + i*unit, unit);
+
+       return 0;
+}
+
+
+static int _ws_hex_to_num(char *src, int len)
+{
+       char *temp = NULL;
+       int num = 0;
+
+       if (!src || len < 0) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       temp = (char*) calloc(1, len+1);
+       if (!temp) {
+               WDP_LOGE("Failed to allocate memory");
+               return -1;
+       }
+
+       memcpy(temp, src, len);
+       num = strtoul(temp, NULL, 16);
+       free(temp);
+
+       return num;
+}
+
+static int _ws_hex_to_txt(char *src, int length, char *dest)
+{
+       // TODO: check it is good to change dest parameter as double pointer.
+       // It could be better to allocate memory for dest parameter here.
+       char *temp = NULL;
+       char *ptr = NULL;
+       int len = 0;
+       int i = 0;
+
+       if (!src || length < 0 || !dest) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       // TODO: flush destination memory
+
+       ptr = src;
+       temp = dest;
+
+       if (!length)
+               len = strlen(src);
+       else
+               len = length;
+
+       for (i=0; i<len/2 && *ptr!=0; i++) {
+               temp[i] = (char) _ws_hex_to_num(ptr, 2);
+               if (temp[i] < 0) {
+                       WDP_LOGE("Failed to convert hexa string to num");
+                       return -1;
+               }
+               ptr += 2;
+       }
+
+       return 0;
+}
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
 static int _ws_txt_to_devtype(char *txt, int *pri, int *sec)
 {
        if (!txt || !pri || !sec) {
@@ -289,7 +408,8 @@ static char *_ws_wps_to_txt(int wps_mode)
 
 static int _ws_freq_to_channel(int freq)
 {
-       if (freq < 2412 || freq > 5825) {
+       if (freq < 2412 || freq > 5825 ||
+               (freq > 2484 && freq < 5180)) {
                WDP_LOGE("Invalid parameter");
                return -1;
        }
@@ -364,13 +484,13 @@ static int _ws_check_socket(int sock)
        } else {
 
                if (p_fd.revents & POLLERR) {
-                       WDP_LOGF("Error! POLLERR from socket[%d]", sock);
+                       WDP_LOGE("Error! POLLERR from socket[%d]", sock);
                        return -1;
                } else if (p_fd.revents & POLLHUP) {
-                       WDP_LOGF("Error! POLLHUP from socket[%d]", sock);
+                       WDP_LOGE("Error! POLLHUP from socket[%d]", sock);
                        return -1;
                } else if (p_fd.revents & POLLNVAL) {
-                       WDP_LOGF("Error! POLLNVAL from socket[%d]", sock);
+                       WDP_LOGE("Error! POLLNVAL from socket[%d]", sock);
                        return -1;
                } else if (p_fd.revents & POLLIN) {
                        WDP_LOGD("POLLIN from socket [%d]", sock);
@@ -411,7 +531,6 @@ static int _ws_read_sock(int sock, char *data, int data_len)
                                WDP_LOGE("Failed to read data from socket[%d]. [%s]", sock, strerror(errno));
                                return -1;
                        }
-                       WDP_LOGD("===== Read Data =====\n%s", data);
                        data[data_len-1] = '\0';
                        __WDP_LOG_FUNC_EXIT__;
                        return rbytes;
@@ -442,7 +561,7 @@ static int _ws_send_cmd(int sock, char *cmd, char *reply, int reply_len)
                WDP_LOGE("Invalid parameter");
                return -1;
        }
-       WDP_LOGI("Sending command [%s]", cmd);
+       WDP_SECLOGD("Sending command [%s]", cmd);
 
        res = _ws_check_socket(sock);
        if (res < 0) {
@@ -558,11 +677,11 @@ static int _create_ctrl_intf(char *ctrl_intf_path, char *supp_path)
 
        memset(&srv_addr, 0, sizeof(srv_addr));
        srv_addr.sun_family = AF_UNIX;
-       snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), supp_path);
+       snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", supp_path);
 
        memset(&local_addr, 0, sizeof(local_addr));
        local_addr.sun_family = AF_UNIX;
-       snprintf(local_addr.sun_path, sizeof(local_addr.sun_path), ctrl_intf_path);
+       snprintf(local_addr.sun_path, sizeof(local_addr.sun_path), "%s", ctrl_intf_path);
 
        res = bind(sock, (struct sockaddr*) &local_addr, sizeof(local_addr));
        if (res < 0)
@@ -637,11 +756,6 @@ static int _connect_to_supplicant(char *ifname, ws_sock_data_s **sock_data)
                return -1;
        }
 
-       if (sock && sock->ctrl_sock > SOCK_FD_MIN) {
-               WDP_LOGE("Socket already connected [%d]", sock->ctrl_sock);
-               return -1;
-       }
-
        errno = 0;
        sock = (ws_sock_data_s*) calloc(1, sizeof(ws_sock_data_s));
        if (!sock) {
@@ -652,7 +766,11 @@ static int _connect_to_supplicant(char *ifname, ws_sock_data_s **sock_data)
 
        snprintf(ctrl_path, sizeof(ctrl_path), "/tmp/%s_control", ifname);
        snprintf(mon_path, sizeof(mon_path), "/tmp/%s_monitor", ifname);
-       snprintf(suppl_path, sizeof(suppl_path), SUPPL_IFACE_PATH "%s", ifname);
+       if (strncmp(ifname, GROUP_IFACE_NAME, 11))
+               snprintf(suppl_path, sizeof(suppl_path), SUPPL_IFACE_PATH "%s", ifname);
+       else
+               snprintf(suppl_path, sizeof(suppl_path), SUPPL_GROUP_IFACE_PATH "%s", ifname);
+
 
        for(i = 0; i < WS_CONN_RETRY_COUNT; i++) {
                ctrl_sock = _create_ctrl_intf(ctrl_path, suppl_path);
@@ -702,7 +820,8 @@ static int _connect_to_supplicant(char *ifname, ws_sock_data_s **sock_data)
        GIOChannel *gio;
        int gsource = 0;
        gio = g_io_channel_unix_new(mon_sock);
-       gsource = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP, (GIOFunc) ws_event_handler, sock);
+       if (!strstr(ifname, GROUP_IFACE_PREFIX))
+               gsource = g_io_add_watch(gio, G_IO_IN | G_IO_ERR | G_IO_HUP, (GIOFunc) ws_event_handler, sock);
        g_io_channel_unref(gio);
 
        sock->gsource = gsource;
@@ -725,7 +844,7 @@ static gboolean _remove_event_source(gpointer data)
 
        res = g_source_remove(source_id);
        if (!res) {
-               WDP_LOGE("Failed to remove GSource");
+               WDP_LOGE("Failed to remove GSource(%d)", source_id);
                return FALSE;
        }
        WDP_LOGD("Succeeded to remove GSource");
@@ -790,40 +909,49 @@ static int _disconnect_from_supplicant(char *ifname, ws_sock_data_s *sock_data)
        return 0;
 }
 
-static int hex2num(const char c)
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+int _check_service_query_exists(wfd_oem_service_s *service)
 {
-       if (c >= '0' && c <= '9')
-               return c - '0';
-       if (c >= 'a' && c <= 'f')
-               return c - 'a' + 10;
-       if (c >= 'A' && c <= 'F')
-               return c - 'A' + 10;
-       return -1;
-}
+       int count = 0;
+       wfd_oem_service_s *data = NULL;
 
-static int hex2byte(const char *hex)
-{
-       int a, b;
-       a = hex2num(*hex++);
-       if (a < 0)
-               return -1;
-       b = hex2num(*hex++);
-       if (b < 0)
-               return -1;
-       return (a << 4) | b;
+       for (count = 0; count < g_list_length(service_list); count ++) {
+               data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
+               if (strncmp(service->query_id, data->query_id, OEM_QUERY_ID_LEN) == 0) {
+                       WDP_LOGD("Query already exists");
+                       return 1;
+               }
+       }
+       return 0;
 }
 
-static int _get_subelem_len(const char* value)
+static wfd_oem_service_s* _remove_service_query(char * s_type, char *mac_str, char *query_id)
 {
-       int a, b;
-       a = hex2byte(value);
-       b = hex2byte(value + 2);
+       if (NULL == s_type || NULL == mac_str || NULL == query_id)
+               return NULL;
+
+       int count = 0;
+       wfd_oem_service_s *data = NULL;
+
+       for (count = 0; count < g_list_length(service_list); count ++) {
+               data = (wfd_oem_service_s*) g_list_nth_data(service_list, count);
+               if (data && !strncmp(data->service_type, s_type, SERVICE_TYPE_LEN) &&
+                               memcmp(data->dev_addr, mac_str, OEM_MACSTR_LEN - 1) == 0) {
+                       strncpy(query_id, data->query_id, OEM_QUERY_ID_LEN);
+                       break;
+               }
+       }
+       if (strlen(query_id) <= 0) {
+               WDP_LOGD("!! Query ID not found !!");
+               return NULL;
+       }
+
+       WDP_LOGD("query id :[0x%s]",query_id);
+
+       return data;
 
-       if( a >= 0 && b >= 0)
-               return ( a << 8) | b;
-       else
-               return -1;
 }
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
 static int _extract_word(const char *data, char **value)
 {
@@ -844,6 +972,7 @@ static int _extract_word(const char *data, char **value)
                *value = (char*) calloc(1, i+1);
                strncpy(*value, data, i);
                (*value)[i] = '\0';
+               WDP_LOGV("Extracted word: %s", *value);
        }
 
        return i;
@@ -923,56 +1052,123 @@ static int _extract_peer_value_str(const char *data, const char *key, char **val
        return 0;
 }
 
-static int _ws_parse_subelement(int id, char *data, int len,
-                                       wfd_oem_display_info_s *display_info)
+#if 0
+static int _check_dev_type(unsigned char *dev_addr, int *pri_dev_type, int *sec_dev_type)
 {
-       switch (id){
-       case WFD_SUBELEM_ID_DEVICE_INFO:
-               WDP_LOGD("WFD_SUBELEM_ID_DEVICE_INFO subelement ID");
-               if(len != 6){
-                       WDP_LOGE("Wrong Length");
-               }else {
-                       display_info->dev_info[1] = hex2byte(data);
-                       display_info->dev_info[0] = hex2byte(data + 2);
-                       display_info->ctrl_port = _get_subelem_len(data + 4);
-                       display_info->max_tput = _get_subelem_len(data + 8);
-                       display_info->type = display_info->dev_info[0] & WFD_DEVICE_TYPE;
-                       display_info->availability = display_info->dev_info[0] &
-                                       WFD_DEVICE_SESSION_AVAILABILITY;
-                       display_info->hdcp_support = display_info->dev_info[1] &
-                                       (WFD_DEVICE_CONTENT_PROTECTION_SUPPORT >> 8);
-               }
-               break;
-       default:
-               WDP_LOGD("MISC or UNKNOWN WFD subelement ID");
-               break;
+       ws_sock_data_s *sock = g_pd->common;
+       char cmd[32] = {0, };
+       char reply[1024] = {0,};
+       char *manufacturer = NULL;
+       char *model_name = NULL;
+       char *model_number = NULL;
+       int res = 0;
+
+       if (!dev_addr || !pri_dev_type || !sec_dev_type) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
        }
-       return 0;
-}
 
-static int _parsing_wfd_subelems(char *buf, wfd_oem_display_info_s *display_info)
-{
-       char *pos = buf;
-       char *end = buf + strlen(buf);
+       if (!sock) {
+               WDP_LOGE("Socket is NULL");
+               return -1;
+       }
 
-       while (pos < end) {
-               int subelem_len;
-               if (pos + 2 >= end) {
-                       WDP_LOGE("Invalid WFD subelement");
+       snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PEER MACSTR, MAC2STR(dev_addr));
+       res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
+       if (res < 0) {
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+                       __WDP_LOG_FUNC_EXIT__;
                        return -1;
-               }
-               subelem_len = _get_subelem_len(pos + 2);
+       }
 
-               if (pos + 6 + subelem_len*2 > end) {
-                       WDP_LOGE("subelement underflow ");
-                       return -1;
-               }
-               if (_ws_parse_subelement(hex2byte(pos), pos + 6, subelem_len, display_info))
-                       return -1;
-               pos += (6 + subelem_len*2);
+       if (strstr(reply, "FAIL")) {
+               WDP_SECLOGD("Failed to get peer info [" MACSTR "]", MAC2STR(dev_addr));
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       WDP_SECLOGD("Succeeded to get peer info [" MACSTR "]", MAC2STR(dev_addr));
+
+       res = _extract_peer_value_str(reply, "model_number", &model_number);
+       if (res > 0 && !strncmp(model_number, "EAD-T10", 7)) {
+               *pri_dev_type = 8;
+               *sec_dev_type = 5;
+               free(model_number);
+               WDP_LOGD("peer device type set as Dongle");
+               return 0;
+       }
+       if (model_number)
+               free(model_number);
+
+       _extract_peer_value_str(reply, "manufacturer", &manufacturer);
+       _extract_peer_value_str(reply, "model_name", &model_name);
+       if (!manufacturer || !model_name) {
+               WDP_LOGE("parsing error");
+               if (manufacturer)
+                       free(manufacturer);
+               if (model_name)
+                       free(model_name);
+               return -1;
+       }
+
+       if (!strncmp(manufacturer, "SAMSUNG_ELECTRONICS", 19) &&
+                               !strncmp(model_name, "SAMSUNG_MOBILE", 14)) {
+               *pri_dev_type = 8;
+               *sec_dev_type = 4;
+               WDP_LOGD("peer device type set as Homesync");
+               free(manufacturer);
+               free(model_name);
+               return 0;
+       }
+       if (manufacturer)
+               free(manufacturer);
+       if (model_name)
+               free(model_name);
+
+       return -1;
+}
+#endif
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+static int _parsing_wfd_info(char *msg, wfd_oem_display_s *display )
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       char wfd_info_msg[5] = {0, };
+       char ctrl_port_msg[5] = {0, };
+       char max_tput_msg[5] = {0, };
+       int wfd_info = 0;
+       if (!msg || strlen(msg) < 12) {
+               WDP_LOGE("Invalid parameter");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
        }
+       /*wfd_info_msg:0013 1c44 000a */
+       WDP_LOGE("Message to parse: %s", msg);
+
+       strncpy(wfd_info_msg, msg, 4);
+       wfd_info = strtoul(wfd_info_msg, NULL, 16);
+
+       if (wfd_info & WS_WFD_INFO_PRIMARY_SINK)
+               display->type |= WS_WFD_INFO_PRIMARY_SINK;
+       if (wfd_info & WS_WFD_INFO_SECONDARY_SINK)
+               display->type |= WS_WFD_INFO_SECONDARY_SINK;
+
+       display->availablity = (wfd_info & WS_WFD_INFO_AVAILABLITY) >> 4;
+       display->hdcp_support = (wfd_info & WS_WFD_INFO_HDCP_SUPPORT) >> 8;
+
+       strncpy(ctrl_port_msg, msg+4, 4);
+       display->port =  strtoul(ctrl_port_msg, NULL, 16);
+       strncpy(max_tput_msg, msg+8, 4);
+       display->max_tput =  strtoul(max_tput_msg, NULL, 16);
+
+       WDP_LOGE("type [%d],availablity [%d],hdcp_support [%d],ctrl_port [%d] max_tput[%d]",
+                       display->type,display->availablity,display->hdcp_support,
+                       display->port,display->max_tput);
+
+       __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
 static int _parsing_peer_info(char *msg, wfd_oem_device_s *peer)
 {
@@ -1070,8 +1266,6 @@ static int _parsing_peer_info(char *msg, wfd_oem_device_s *peer)
                        if (group_capab & WS_GROUP_CAP_PERSISTENT_GROUP)
                                peer->group_flags = WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
                        break;
-               case WS_PEER_INFO_IS_WFD_DEVICE:
-                       break;
                case WS_PEER_INFO_GO_NEG_REQ_SENT:
                        break;
                case WS_PEER_INFO_GO_STATE:
@@ -1097,9 +1291,13 @@ static int _parsing_peer_info(char *msg, wfd_oem_device_s *peer)
                        break;
                case WS_PEER_INFO_INVITATION_REQS:
                        break;
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
                case WS_PEER_INFO_WFD_SUBELEMS:
-                       res = _parsing_wfd_subelems(infos[i].string, &(peer->wifi_display));
+                       res = _parsing_wfd_info(infos[i].string+6,&peer->display);
+                       if (res < 0)
+                               memset(&peer->display, 0x00, sizeof(wfd_oem_display_s));
                        break;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
                default:
                        break;
                }
@@ -1129,14 +1327,17 @@ static wfd_oem_dev_data_s *_convert_msg_to_dev_info(char *msg)
                WDP_LOGE("Invalid parameter");
                return NULL;
        }
-       WDP_LOGD("msg to be converted [%s]", msg);
+       WDP_SECLOGD("msg to be converted [%s]", msg);
 
        memset(infos, 0x0, (WS_DEV_INFO_LIMIT) * sizeof(ws_string_s));
-       for (i = 0; i < WS_DEV_INFO_LIMIT; i++) {
+       for (i = 0; ws_dev_info_strs[i].index < WS_DEV_INFO_LIMIT; i++) {
                res = _extract_value_str(msg, ws_dev_info_strs[i].string, &infos[info_cnt].string);
                if (res > 0) {
                        infos[info_cnt].index = ws_dev_info_strs[i].index;
-                       WDP_LOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
+                       if (infos[info_cnt].index == WS_DEV_INFO_P2P_DEV_ADDR)
+                               WDP_SECLOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
+                       else
+                               WDP_LOGD("%dth info [%d:%s]", i, infos[info_cnt].index, infos[info_cnt].string);
                        info_cnt++;
                }
        }
@@ -1198,9 +1399,15 @@ static wfd_oem_dev_data_s *_convert_msg_to_dev_info(char *msg)
                        if (res < 0)
                                memset(edata->p2p_go_addr, 0x00, OEM_MACADDR_LEN);
                        break;
-               case WS_DEV_INFO_WFD_SUBELEMS:
-                       res = _parsing_wfd_subelems(infos[i].string, &(edata->wifi_display));
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+               case WS_DEV_INFO_WFD_DEV_INFO:
+                       /* wfd_dev_info=0x00 0006 015d 022a0032 */
+                       res = _parsing_wfd_info(infos[i].string+2,&edata->display);
+                       if (res < 0)
+                               memset(&edata->display, 0x00, sizeof(wfd_oem_display_s));
                        break;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
                default:
                        WDP_LOGE("Unknown parameter [%d:%s]", infos[i].index, infos[i].string);
                        break;
@@ -1220,6 +1427,7 @@ static wfd_oem_conn_data_s *_convert_msg_to_conn_info(char *msg)
        int info_cnt = 0;
        ws_string_s infos[WS_CONN_INFO_LIMIT];
        wfd_oem_conn_data_s *edata = NULL;
+       int dev_pwd_id;
        int res = 0;
 
        if (!msg) {
@@ -1229,7 +1437,7 @@ static wfd_oem_conn_data_s *_convert_msg_to_conn_info(char *msg)
        WDP_LOGD("msg to convert [%s]", msg);
 
        memset(infos, 0x0, (WS_CONN_INFO_LIMIT) * sizeof(ws_string_s));
-       for (i = 0; i < WS_CONN_INFO_LIMIT; i++) {
+       for (i = 0; ws_conn_info_strs[i].index < WS_CONN_INFO_LIMIT; i++) {
                res = _extract_value_str(msg, ws_conn_info_strs[i].string, &infos[info_cnt].string);
                if (res > 0) {
                        infos[info_cnt].index = ws_conn_info_strs[i].index;
@@ -1252,7 +1460,15 @@ static wfd_oem_conn_data_s *_convert_msg_to_conn_info(char *msg)
        for (i = 0; i < info_cnt; i++) {
                switch (infos[i].index) {
                case WS_CONN_INFO_DEV_PWD_ID:
-                       edata->dev_pwd_id = atoi(infos[i].string);
+                       dev_pwd_id = atoi(infos[i].string);
+                       if (dev_pwd_id == WS_DEV_PASSWD_ID_PUSH_BUTTON)
+                               edata->wps_mode = WFD_OEM_WPS_MODE_PBC;
+                       else if (dev_pwd_id == WS_DEV_PASSWD_ID_REGISTRAR_SPECIFIED)
+                               edata->wps_mode = WFD_OEM_WPS_MODE_DISPLAY;
+                       else if (dev_pwd_id == WS_DEV_PASSWD_ID_USER_SPECIFIED)
+                               edata->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
+                       else
+                               edata->wps_mode = WFD_OEM_WPS_MODE_NONE;
                        break;
                case WS_CONN_INFO_STATUS:
                        edata->status = atoi(infos[i].string);
@@ -1288,7 +1504,7 @@ static wfd_oem_invite_data_s *_convert_msg_to_invite_info(char *msg)
        WDP_LOGD("msg to convert [%s]", msg);
 
        memset(infos, 0x0, (WS_INVITE_INFO_LIMIT) * sizeof(ws_string_s));
-       for (i = 0; i < WS_INVITE_INFO_LIMIT; i++) {
+       for (i = 0; ws_invite_info_strs[i].index < WS_INVITE_INFO_LIMIT; i++) {
                res = _extract_value_str(msg, ws_invite_info_strs[i].string, &infos[info_cnt].string);
                if (res > 0) {
                        infos[info_cnt].index = ws_invite_info_strs[i].index;
@@ -1354,7 +1570,7 @@ static wfd_oem_group_data_s *_convert_msg_to_group_info(char *msg)
        WDP_LOGD("msg to convert [%s]", msg);
 
        memset(infos, 0x0, WS_GROUP_INFO_LIMIT * sizeof(ws_string_s));
-       for (i = 0; i < WS_GROUP_INFO_LIMIT; i++) {
+       for (i = 0; ws_group_info_strs[i].index < WS_GROUP_INFO_LIMIT; i++) {
                res = _extract_value_str(msg, ws_group_info_strs[i].string, &infos[info_cnt].string);
                if (res > 0) {
                        infos[info_cnt].index = ws_group_info_strs[i].index;
@@ -1404,6 +1620,131 @@ static wfd_oem_group_data_s *_convert_msg_to_group_info(char *msg)
        return edata;
 }
 
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+static int _ws_segment_to_service(char *segment, wfd_oem_new_service_s **service)
+{
+       wfd_oem_new_service_s *serv_tmp = NULL;
+       char *ptr = NULL;
+       char *temp = NULL;
+       int len = 0;
+       int i = 0;
+
+       if (!segment || !service) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       ptr = segment;
+       WDP_LOGD("Segment: %s", segment);
+
+       serv_tmp = (wfd_oem_new_service_s*) calloc(1, sizeof(wfd_oem_new_service_s));
+       if (!serv_tmp) {
+               WDP_LOGE("Failed to allocate memory for service");
+               return -1;
+       }
+
+       serv_tmp->protocol = _ws_hex_to_num(ptr, 2);
+       serv_tmp->trans_id = _ws_hex_to_num(ptr+2, 2);
+       serv_tmp->status = _ws_hex_to_num(ptr+4, 2);
+       ptr += 6;
+       WDP_LOGD("Protocol[%d], Transaction ID[%d], Status[%d]", serv_tmp->protocol, serv_tmp->trans_id, serv_tmp->status);
+
+       if (serv_tmp->status != 0) {
+               WDP_LOGE("Service status is not success");
+               free(serv_tmp);
+               return -1;
+       }
+
+       if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
+               WDP_LOGD("===== Bonjour service =====");
+               char compr[5] = {0, };
+               char query[256] = {0, };
+               char rdata[256] = {0, };
+               int dns_type = 0;
+
+               while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
+                       len = _ws_hex_to_num(ptr, 2);
+                       ptr +=2;
+                       if (len) {
+                               temp = (char*) calloc(1, len+2);
+                               temp[0] = '.';
+                               for (i=0; i<len; i++) {
+                                       temp[i+1] = (char) _ws_hex_to_num(ptr, 2);
+                                       ptr += 2;
+                               }
+                               strncat(query, temp, len+1);
+                               free(temp);
+                               temp = NULL;
+                       }
+               }
+
+               if (!strncmp(ptr, "c0", 2)) {
+                       memcpy(compr, ptr, 4);
+                       ptr += 2;
+
+                       if (!strncmp(ptr, "27", 2)) {
+                               WDP_LOGD("Segment ended");
+                               ptr += 2;
+                       } else {
+                               ptr += 2;
+                               dns_type = _ws_hex_to_num(ptr, 4);
+                               ptr += 6;
+                               if (dns_type == 12) {
+                                       if (!strncmp(compr, "c011", 4))
+                                               strncat(query, ".local.", 7);
+                                       else if (!strncmp(compr, "c00c", 4))
+                                               strncat(query, "._tcp.local.", 12);
+                                       else if (!strncmp(compr, "c01c", 4))
+                                               strncat(query, "._udp.local.", 12);
+                               }
+                       }
+               }
+               serv_tmp->data.bonjour.query = strdup(query + 1);
+               while (*ptr != 0 && strncmp(ptr, "c0", 2)) {
+                       len = _ws_hex_to_num(ptr, 2);
+                       ptr += 2;
+                       if (len) {
+                               temp = (char*) calloc(1, len+2);
+                               temp[0] = '.';
+                               for (i=0; i<len; i++) {
+                                       temp[i+1] = (char) _ws_hex_to_num(ptr, 2);
+                                       ptr += 2;
+                               }
+                               strncat(rdata, temp, len+1);
+                               free(temp);
+                               temp = NULL;
+                       }
+               }
+               serv_tmp->data.bonjour.rdata = strdup(rdata + 1);
+
+               WDP_LOGD("Query: %s", serv_tmp->data.bonjour.query);
+               WDP_LOGD("RData: %s", serv_tmp->data.bonjour.rdata);
+       } else if (serv_tmp->protocol == WFD_OEM_SERVICE_TYPE_VENDOR) {
+               WDP_LOGD("===== Vendor specific service =====");
+               if (!strncmp(ptr, "0000f00b", 8)) {
+                       WDP_LOGD("\tSAMSUNG_BT_ADDR");
+                       ptr += 16;
+                       serv_tmp->protocol = WFD_OEM_SERVICE_TYPE_BT_ADDR;
+                       serv_tmp->data.vendor.data1 = (char*) calloc(1, 9);
+                       g_strlcpy(serv_tmp->data.vendor.data1, "0000f00b", 9);
+                       serv_tmp->data.vendor.data2 = (char*) calloc(1, 18);
+                       _ws_hex_to_txt(ptr, 0, serv_tmp->data.vendor.data2);
+               }
+               WDP_LOGD("Info1: %s", serv_tmp->data.vendor.data1);
+               WDP_LOGD("Info2: %s", serv_tmp->data.vendor.data2);
+       } else {
+               WDP_LOGE("Not supported yet. Only bonjour and samsung vendor service supproted [%d]",
+                                       serv_tmp->protocol);
+               free(serv_tmp);
+               return -1;
+       }
+
+       *service = serv_tmp;
+
+       return 0;
+}
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
 static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
 {
        __WDP_LOG_FUNC_ENTER__;
@@ -1416,21 +1757,22 @@ static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Event message [%s]", msg);
+       WDP_SECLOGD("Event message [%s]", msg);
 
        // parsing event string
-       for(i = 0; i < WS_EVENT_LIMIT; i++) {
+       for(i = 0; ws_event_strs[i].index < WS_EVENT_LIMIT; i++) {
                if (!strncmp(ws_event_strs[i].string, msg, strlen(ws_event_strs[i].string))) {
                        break;
                }
        }
-       data->event_id = i;
-       WDP_LOGD("Event ID [%d]", i);
 
-       if (i == WS_EVENT_LIMIT) {
-               WDP_LOGE("Unknown event [%d]", i);
+       if (i == sizeof(ws_event_strs)) {
+               WDP_LOGE("Unknown event [%d]", WS_EVENT_LIMIT);
+               data->event_id = WS_EVENT_LIMIT;
                return 1;
        }
+       data->event_id = ws_event_strs[i].index;
+       WDP_LOGD("Event ID [%d]", data->event_id);
 
        // parsing event info
        info_str = msg + strlen(ws_event_strs[i].string) + 1;
@@ -1472,7 +1814,8 @@ static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
                        _ws_txt_to_mac(info_str, data->dev_addr);
                        info_str += OEM_MACSTR_LEN;
 
-                       if (data->event_id == WS_EVENT_PROV_DISC_PBC_REQ) {
+                       if (data->event_id == WS_EVENT_PROV_DISC_PBC_REQ ||
+                               data->event_id == WS_EVENT_PROV_DISC_PBC_RESP) {
                                data->wps_mode = WFD_OEM_WPS_MODE_PBC;
                        } else if (data->event_id == WS_EVENT_PROV_DISC_ENTER_PIN) {
                                data->wps_mode = WFD_OEM_WPS_MODE_KEYPAD;
@@ -1483,6 +1826,8 @@ static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
                                info_str += OEM_PINSTR_LEN +1;
                        }
 
+                       WDP_LOGD("info string left [%s]", info_str ? info_str:"NULL");
+
                        data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
 
                }
@@ -1523,13 +1868,24 @@ static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
                        }
                        data->edata_type = WFD_OEM_EDATA_TYPE_CONN;
                        data->edata = (void*) edata;
-
                }
                break;
        case WS_EVENT_PROV_DISC_FAILURE:
-       case WS_EVENT_GO_NEG_FAILURE:
        case WS_EVENT_WPS_FAIL:         // M_id(msg), error(config_error)
                break;
+       case WS_EVENT_GO_NEG_FAILURE:
+               {
+                       wfd_oem_conn_data_s *edata = NULL;
+                       edata = _convert_msg_to_conn_info(info_str);
+                       if (!edata) {
+                               WDP_LOGE("Failed to convert information string to connection data");
+                               data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
+                               break;
+                       }
+                       data->edata_type = WFD_OEM_EDATA_TYPE_CONN;
+                       data->edata = (void*) edata;
+               }
+               break;
        case WS_EVENT_GROUP_FORMATION_FAILURE:  // No incofmation sring
        case WS_EVENT_GO_NEG_SUCCESS:
        case WS_EVENT_WPS_SUCCESS:
@@ -1541,7 +1897,6 @@ static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
                /* Interface address of peer will come up */
                break;
        case WS_EVENT_CONNECTED:        // intf_addr(to)
-       case WS_EVENT_DISCONNECTED:
                {
                        /* Interface address of connected peer will come up */
                        char *temp_mac = NULL;
@@ -1556,6 +1911,21 @@ static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
                        data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
                }
                break;
+       case WS_EVENT_DISCONNECTED:
+               {
+                       /* Interface address of disconnected peer will come up */
+                       char *temp_mac = NULL;
+                       res = _extract_value_str(info_str, "bssid", &temp_mac);
+                       if (res < 0) {
+                               WDP_LOGE("Failed to extract interface address");
+                               break;
+                       }
+                       _ws_txt_to_mac(temp_mac, data->intf_addr);
+                       if (temp_mac)
+                               free(temp_mac);
+                       data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
+               }
+               break;
        case WS_EVENT_STA_CONNECTED:    // "intf_addr", dev_addr(dev_addr)
        case WS_EVENT_STA_DISCONNECTED:
                {
@@ -1677,22 +2047,59 @@ static int _parsing_event_info(char *ifname, char *msg, wfd_oem_event_s *data)
 
                }
                break;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
        case WS_EVENT_SERV_DISC_RESP:
                {
+                       char mac_addr[OEM_MACSTR_LEN] ={0, };
+                       char *up_indic = NULL;
+                       int len = 0;
+
                        _ws_txt_to_mac(info_str, data->dev_addr);
                        info_str += OEM_MACSTR_LEN;
+                       snprintf(mac_addr, OEM_MACSTR_LEN, MACSTR, MAC2STR(data->dev_addr));
 
-                       WDP_LOGD("service tlv is %s", info_str);
-
-                       if (!strlen(info_str)) {
-                               WDP_LOGD("Nothing to parse anymore");
-                               data->edata_type = WFD_OEM_EDATA_TYPE_NONE;
-                               break;
+                       _extract_word(info_str, &up_indic);
+                       if (up_indic) {
+                               WDP_LOGD("Update indicator: %s", up_indic);
+                               info_str += strlen(up_indic) + 1;
+                               g_free(up_indic);
+                       }
+                       WDP_LOGD("Info string [%s]", info_str);
+
+                       char seglen_str[5] = {0, };
+                       char *segment = NULL;
+                       char *ptr = info_str;
+                       GList *services = NULL;
+                       wfd_oem_new_service_s *new_service = NULL;
+                       int count = 0;
+
+                       while (*ptr != '\0') {
+                               _change_str_order(ptr, 4, 2, seglen_str);
+                               len = strtoul(seglen_str, NULL, 16);
+                               if (len == 0)
+                                       break;
+                               segment = (char*) calloc(1, len*2+1);
+                               memcpy(segment, ptr+4, len*2);
+                               ptr = ptr + 4 + len*2;
+                               res = _ws_segment_to_service(segment, &new_service);
+                               if (res < 0) {
+                                       WDP_LOGE("Failed to convert segment as service instance");
+                                       free(segment);
+                                       segment = NULL;
+                                       continue;
+                               }
+                               services = g_list_append(services, new_service);
+                               count++;
+                               free(segment);
+                               segment = NULL;
                        }
-                       data->edata = (void*)strndup(info_str, strlen(info_str));
-                       data->edata_type = WFD_OEM_EDATA_TYPE_SERVICE;
+                       data->edata_type = WFD_OEM_EDATA_TYPE_NEW_SERVICE;
+                       data->dev_role = count;
+                       data->edata = (void*) services;
                }
                break;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
        default:
                WDP_LOGE("Unknown event");
                break;
@@ -1708,8 +2115,9 @@ static gboolean ws_event_handler(GIOChannel *source,
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s * sd = (ws_sock_data_s*) data;
-       char msg[2048] = {0, };
-       char *param;
+       char msg[1024] = {0, };
+       char *pos = NULL;
+       char *param = NULL;
        int event_id = -1;
        wfd_oem_event_s *event = NULL;
        int res = 0;
@@ -1733,7 +2141,13 @@ static gboolean ws_event_handler(GIOChannel *source,
                return FALSE;
        }
 
-       param = &msg[3];
+       if (!strncmp(msg, "IFNAME", 6)) {
+               pos = strchr(msg, ' ');
+               param = pos+4;
+       } else {
+               param = &msg[3];
+       }
+
        res = _parsing_event_info(sd->ifname, param, event);
        if (res < 0) {
                WDP_LOGE("Failed to parse event string");
@@ -1745,6 +2159,7 @@ static gboolean ws_event_handler(GIOChannel *source,
                // This means event->event_data is NULL
        }
 
+       /* Converting WS event to OEM event */
        switch (event->event_id) {
        case WS_EVENT_DEVICE_FOUND:
                event_id = WFD_OEM_EVENT_PEER_FOUND;
@@ -1759,25 +2174,41 @@ static gboolean ws_event_handler(GIOChannel *source,
                event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
                break;
        case WS_EVENT_PROV_DISC_PBC_RESP:
-               event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
+               if (!memcmp(event->dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
+                       event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
+                       memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
+               } else {
+                       WDP_LOGE("Invalid peer mac address[" MACSTR "]", MAC2STR(event->dev_addr));
+                       goto done;
+               }
                break;
        case WS_EVENT_PROV_DISC_SHOW_PIN:
        case WS_EVENT_PROV_DISC_ENTER_PIN:
-               if (!memcmp(g_pd->pd_addr, event->dev_addr, OEM_MACADDR_LEN))
+               if (!memcmp(event->dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
                        event_id = WFD_OEM_EVENT_PROV_DISC_RESP;
-               else if (!memcmp(g_pd->pd_addr, null_mac, OEM_MACADDR_LEN))
+                       memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
+                       WDP_LOGD("Peer mac address verified");
+               } else if (!memcmp(g_pd_out, null_mac, OEM_MACADDR_LEN)) {
                        event_id = WFD_OEM_EVENT_PROV_DISC_REQ;
-               else
+                       WDP_LOGD("      PD request from peer[" MACSTR "]", MAC2STR(event->dev_addr));
+               } else {
+                       WDP_LOGE("Invalid peer mac address[" MACSTR "]", MAC2STR(event->dev_addr));
                        goto done;
-               memset(g_pd->pd_addr, 0x0, OEM_MACADDR_LEN);
+               }
+
+               break;
+       case WS_EVENT_PROV_DISC_FAILURE:
+               event_id = WFD_OEM_EVENT_PROV_DISC_FAIL;
+               if (!memcmp(event->dev_addr, g_pd_out, OEM_MACADDR_LEN)) {
+                       memset(g_pd_out, 0x0, OEM_MACADDR_LEN);
+                       WDP_LOGD("Peer mac address verified, but PD failed");
+               }
                break;
        case WS_EVENT_GO_NEG_REQUEST:
                event_id = WFD_OEM_EVENT_GO_NEG_REQ;
                break;
        case WS_EVENT_GO_NEG_FAILURE:
                event_id = WFD_OEM_EVENT_GO_NEG_FAIL;
-               _ws_cancel();
-               _ws_flush();
                break;
        case WS_EVENT_GO_NEG_SUCCESS:
                event_id = WFD_OEM_EVENT_GO_NEG_DONE;
@@ -1793,11 +2224,9 @@ static gboolean ws_event_handler(GIOChannel *source,
                // TODO: connect to supplicant via group interface
                break;
        case WS_EVENT_CONNECTED:
-               {
-                       if (!memcmp(event->intf_addr, null_mac, OEM_MACADDR_LEN))
-                               goto done;
-                       event_id = WFD_OEM_EVENT_CONNECTED;
-               }
+               if (!memcmp(event->intf_addr, null_mac, OEM_MACADDR_LEN))
+                       goto done;
+               event_id = WFD_OEM_EVENT_CONNECTED;
                break;
        case WS_EVENT_STA_CONNECTED:
                event_id = WFD_OEM_EVENT_STA_CONNECTED;
@@ -1807,7 +2236,7 @@ static gboolean ws_event_handler(GIOChannel *source,
                res = _connect_to_supplicant(GROUP_IFACE_NAME, &g_pd->group);
                if (res < 0) {
                        WDP_LOGE("Failed to connect to group interface of supplicant");
-                       goto done;
+                       // goto done;
                }
                break;
        case WS_EVENT_GROUP_REMOVED:
@@ -1816,7 +2245,7 @@ static gboolean ws_event_handler(GIOChannel *source,
                        res = _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
                        if (res < 0) {
                                WDP_LOGE("Failed to disconnect from group interface of supplicant");
-                               goto done;
+                               // goto done;
                        }
                        g_pd->group = NULL;
                }
@@ -1828,17 +2257,21 @@ static gboolean ws_event_handler(GIOChannel *source,
                event_id = WFD_OEM_EVENT_INVITATION_RES;
                break;
        case WS_EVENT_DISCONNECTED:
+               if (!memcmp(event->intf_addr, null_mac, OEM_MACADDR_LEN))
+                       goto done;
                event_id = WFD_OEM_EVENT_DISCONNECTED;
                break;
        case WS_EVENT_STA_DISCONNECTED:
                event_id = WFD_OEM_EVENT_STA_DISCONNECTED;
                break;
+       case WS_EVENT_TERMINATING:
+               event_id = WFD_OEM_EVENT_DEACTIVATED;
+               break;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
        case WS_EVENT_SERV_DISC_RESP:
                event_id = WFD_OEM_EVENT_SERV_DISC_RESP;
                break;
-       case WS_EVENT_TERMINATING:
-               event_id = WFD_OEM_EVENT_TERMINATING;
-               break;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
        default:
                WDP_LOGD("Unknown event [%d]", event->event_id);
                goto done;
@@ -1848,8 +2281,14 @@ static gboolean ws_event_handler(GIOChannel *source,
        g_pd->callback(g_pd->user_data, event);
 
 done:
-       if (event->edata)
+       if (event->edata) {
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+               if (event->edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE)
+                       g_list_free((GList*) event->edata);
+               else
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
                free(event->edata);
+       }
        free(event);
 
        __WDP_LOG_FUNC_EXIT__;
@@ -1867,7 +2306,7 @@ static int _ws_reset_plugin(ws_plugin_data_s *pd)
        }
 
        if (pd->activated)
-               ws_deactivate();
+               ws_deactivate(g_pd->concurrent);
 
        free(pd);
 
@@ -1875,21 +2314,60 @@ static int _ws_reset_plugin(ws_plugin_data_s *pd)
        return 0;
 }
 
-int ws_init(wfd_oem_event_cb callback, void *user_data)
-{
-       __WDP_LOG_FUNC_ENTER__;
 
-       if (g_pd)
-               _ws_reset_plugin(g_pd);
+static int __ws_check_net_interface(char* if_name)
+{
+       struct ifreq ifr;
+       int fd;
 
-       errno = 0;
-       g_pd = (ws_plugin_data_s*) calloc(1, sizeof(ws_plugin_data_s));
-       if (!g_pd) {
-               WDP_LOGE("Failed to allocate memory for plugin data. [%s]", strerror(errno));
+       if (if_name == NULL) {
+               WDP_LOGE("Invalid param");
                return -1;
        }
 
-       g_pd->callback = callback;
+       fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+       if (fd < 0) {
+               WDP_LOGE("socket create error: %d", fd);
+               return -2;
+       }
+
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
+       ifr.ifr_name[IFNAMSIZ-1] = '\0';
+
+       if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+               close(fd);
+               WDP_LOGE("ioctl error: SIOCGIFFLAGS: %s", strerror(errno));  // interface is not found..
+               return -3;
+       }
+
+       close(fd);
+
+       if (ifr.ifr_flags & IFF_UP) {
+               WDP_LOGD("%s interface is up", if_name);
+               return 1;
+       } else if (!(ifr.ifr_flags & IFF_UP)) {
+               WDP_LOGD("%s interface is down", if_name);
+               return 0;
+       }
+       return 0;
+}
+
+int ws_init(wfd_oem_event_cb callback, void *user_data)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       if (g_pd)
+               _ws_reset_plugin(g_pd);
+
+       errno = 0;
+       g_pd = (ws_plugin_data_s*) calloc(1, sizeof(ws_plugin_data_s));
+       if (!g_pd) {
+               WDP_LOGE("Failed to allocate memory for plugin data. [%s]", strerror(errno));
+               return -1;
+       }
+
+       g_pd->callback = callback;
        g_pd->user_data = user_data;
        g_pd->initialized = TRUE;
 
@@ -1910,204 +2388,551 @@ int ws_deinit()
        return 0;
 }
 
-int ws_activate()
+static int __ws_p2p_firmware_start(void)
+{
+       GError *error = NULL;
+       GVariant *reply = NULL;
+       GVariant *param = NULL;
+       GDBusConnection *connection = NULL;
+       const char *device = "p2p";
+
+       connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (connection == NULL) {
+               if(error != NULL){
+                       WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
+                                       error->message);
+                       g_error_free(error);
+               }
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       param = g_variant_new("(s)", device);
+
+       reply = g_dbus_connection_call_sync (connection,
+                       NETCONFIG_SERVICE, /* bus name */
+                       NETCONFIG_WIFI_PATH, /* object path */
+                       NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
+                       "Start", /* method name */
+                       param, /* GVariant *params */
+                       NULL, /* reply_type */
+                       G_DBUS_CALL_FLAGS_NONE, /* flags */
+                       NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
+                       NULL, /* cancellable */
+                       &error); /* error */
+
+       if(error != NULL){
+               if(strstr(error->message, ".AlreadyExists") != NULL) {
+                       WDP_LOGD("p2p already enabled");
+                       g_error_free(error);
+
+               } else {
+                       WDP_LOGE("Error! Failed to call net-config method: [%s]",
+                                       error->message);
+                       g_error_free(error);
+                       if(reply)
+                                g_variant_unref(reply);
+                       g_object_unref(connection);
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+       }
+       if(reply)
+                g_variant_unref(reply);
+       g_object_unref(connection);
+       return 0;
+}
+
+static int __ws_p2p_firmware_stop(void)
+{
+       GError *error = NULL;
+       GVariant *reply = NULL;
+       GVariant *param = NULL;
+       GDBusConnection *connection = NULL;
+       const char *device = "p2p";
+
+       connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (connection == NULL) {
+               if(error != NULL){
+                       WDP_LOGE("Error! Failed to connect to the D-BUS daemon: [%s]",
+                                       error->message);
+                       g_error_free(error);
+               }
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       param = g_variant_new("(s)", device);
+
+       reply = g_dbus_connection_call_sync (connection,
+                       NETCONFIG_SERVICE, /* bus name */
+                       NETCONFIG_WIFI_PATH, /* object path */
+                       NETCONFIG_WIFI_INTERFACE ".Firmware", /* interface name */
+                       "Stop", /* method name */
+                       param, /* GVariant *params */
+                       NULL, /* reply_type */
+                       G_DBUS_CALL_FLAGS_NONE, /* flags */
+                       NETCONFIG_DBUS_REPLY_TIMEOUT , /* timeout */
+                       NULL, /* cancellable */
+                       &error); /* error */
+
+       if(error != NULL){
+               if(strstr(error->message, ".AlreadyExists") != NULL) {
+                       WDP_LOGD("p2p already disabled");
+                       g_error_free(error);
+
+               } else {
+                       WDP_LOGE("Error! Failed to call net-config method: [%s]",
+                                       error->message);
+                       g_error_free(error);
+                       if(reply)
+                                g_variant_unref(reply);
+                       g_object_unref(connection);
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+       }
+       if(reply)
+                g_variant_unref(reply);
+       g_object_unref(connection);
+       return 0;
+}
+
+static int __ws_p2p_supplicant_start(void)
+{
+       gboolean rv = FALSE;
+       const char *path = "/usr/sbin/p2p_supp.sh";
+       char *const args[] = { "/usr/sbin/p2p_supp.sh", "start", NULL };
+       char *const envs[] = { NULL };
+
+       rv = _ws_util_execute_file(path, args, envs);
+
+       if (rv != TRUE) {
+               WDP_LOGE("Failed to start p2p_supp.sh");
+               return -1;
+       }
+
+       WDP_LOGI("Successfully started p2p_supp.sh");
+       return 0;
+}
+
+static int __ws_p2p_supplicant_stop(void)
+{
+       gboolean rv = FALSE;
+       const char *path = "/usr/sbin/p2p_supp.sh";
+       char *const args[] = { "/usr/sbin/p2p_supp.sh", "stop", NULL };
+       char *const envs[] = { NULL };
+
+       rv = _ws_util_execute_file(path, args, envs);
+
+       if (rv != TRUE) {
+               WDP_LOGE("Failed to stop p2p_supp.sh");
+               return -1;
+       }
+
+       WDP_LOGI("Successfully stopped p2p_supp.sh");
+       return 0;
+}
+
+#if 0
+static int __ws_p2p_on(void)
+{
+       DBusError error;
+       DBusMessage *reply = NULL;
+       DBusMessage *message = NULL;
+       DBusConnection *connection = NULL;
+
+       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (connection == NULL) {
+               WDP_LOGE("Failed to get system bus");
+               return -EIO;
+       }
+
+       message = dbus_message_new_method_call(NETCONFIG_SERVICE,
+                       NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "LoadP2pDriver");
+       if (message == NULL) {
+               WDP_LOGE("Failed DBus method call");
+               dbus_connection_unref(connection);
+               return -EIO;
+       }
+
+       dbus_error_init(&error);
+
+       reply = dbus_connection_send_with_reply_and_block(connection, message,
+                       NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
+       if (dbus_error_is_set(&error) == TRUE) {
+               if (NULL != strstr(error.message, ".AlreadyExists")) {
+                       // p2p already enabled
+               } else {
+                       WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
+                                       "DBus error [%s: %s]", error.name, error.message);
+
+                       dbus_error_free(&error);
+               }
+
+               dbus_error_free(&error);
+       }
+
+       if (reply != NULL)
+               dbus_message_unref(reply);
+
+       dbus_message_unref(message);
+       dbus_connection_unref(connection);
+
+       return 0;
+}
+
+static int __ws_p2p_off(void)
+{
+       DBusError error;
+       DBusMessage *reply = NULL;
+       DBusMessage *message = NULL;
+       DBusConnection *connection = NULL;
+
+       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (connection == NULL) {
+               WDP_LOGE("Failed to get system bus");
+               return -EIO;
+       }
+
+       message = dbus_message_new_method_call(NETCONFIG_SERVICE,
+                       NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, "RemoveP2pDriver");
+       if (message == NULL) {
+               WDP_LOGE("Failed DBus method call");
+               dbus_connection_unref(connection);
+               return -EIO;
+       }
+
+       dbus_error_init(&error);
+
+       reply = dbus_connection_send_with_reply_and_block(connection, message,
+                       NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
+       if (dbus_error_is_set(&error) == TRUE) {
+               if (NULL != strstr(error.message, ".AlreadyExists")) {
+                       // p2p already disabled
+               } else {
+                       WDP_LOGE("dbus_connection_send_with_reply_and_block() failed. "
+                                       "DBus error [%s: %s]", error.name, error.message);
+
+                       dbus_error_free(&error);
+               }
+
+               dbus_error_free(&error);
+       }
+
+       if (reply != NULL)
+               dbus_message_unref(reply);
+
+       dbus_message_unref(message);
+       dbus_connection_unref(connection);
+
+       return 0;
+}
+#endif
+static int _ws_update_local_dev_addr_from_file()
 {
        __WDP_LOG_FUNC_ENTER__;
-       int global_sock = -1;
+       FILE *fd = NULL;
+       char local_mac[OEM_MACSTR_LEN] = {0, };
+       char *ptr = NULL;
        int res = 0;
-       char cmd[128] = {0, };
-       char reply[1024] = {0, };
 
-       /* load wlan driver and wpa_supplicant */
-       system("/usr/bin/wlan.sh p2p");
-       system("/usr/sbin/p2p_supp.sh start");
+       errno = 0;
+       fd = fopen(DEFAULT_MAC_FILE_PATH, "r");
+       if (!fd) {
+               WDP_LOGE("Failed to open MAC info file (%s)", strerror(errno));
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
 
-       global_sock = _create_ctrl_intf(GLOBAL_INTF_PATH, SUPPL_GLOBAL_INTF_PATH);
-       if (global_sock < SOCK_FD_MIN) {
-               WDP_LOGE("Failed to create global socket");
+       errno = 0;
+       ptr = fgets(local_mac, OEM_MACSTR_LEN, fd);
+       if (!ptr) {
+               WDP_LOGE("Failed to read file or no data read(%s)", strerror(errno));
+               fclose(fd);
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to create global socket. [%d]", global_sock);
+       WDP_SECLOGD("Local MAC address [%s]", ptr);
 
-       res = _ws_send_cmd(global_sock, WS_CMD_INTERFACES, reply, sizeof(reply));
+       res = _ws_txt_to_mac(local_mac, g_pd->local_dev_addr);
        if (res < 0) {
-               WDP_LOGE("Failed to send command to wpa_supplicant");
+               WDP_LOGE("Failed to convert text to MAC address");
+               fclose(fd);
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
 
-       if (!strstr(reply, COMMON_IFACE_NAME)){
-               memset(cmd, 0x0, 128);
-               memset(reply, 0x0, 1024);
+       g_pd->local_dev_addr[0] |= 0x2;
+       WDP_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(g_pd->local_dev_addr));
+
+       fclose(fd);
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+static int _ws_update_local_dev_addr()
+{
+       int res = 0;
+       char reply[96] = {0, };
+       char *mac_str = NULL;
+
+       res = _ws_send_cmd(g_pd->common->ctrl_sock, "status", reply, sizeof(reply));
+       if (res < 0) {
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+               goto failed;
+       }
+
+       res = _extract_value_str(reply, "p2p_device_address", &mac_str);
+       if (res < 0) {
+               WDP_LOGE("Failed to parsing p2p_device_address");
+               goto failed;
+       }
+
+       res = _ws_txt_to_mac(mac_str, g_pd->local_dev_addr);
+       if (res < 0) {
+               WDP_LOGE("Failed to convert MAC string to address");
+               free(mac_str);
+               goto failed;
+       }
+
+       free(mac_str);
+
+       return 0;
+
+failed:
+       res = _ws_update_local_dev_addr_from_file();
+       if (res < 0) {
+               WDP_LOGE("Failed to update local device address from file");
+               return -1;
+       }
+
+       return 1;
+}
+
+int ws_activate(int concurrent)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       int res = 0;
+       int retry_count = 0;
 
-               snprintf(cmd, sizeof(cmd), WS_CMD_INTERFACE_ADD "%s%s",
-                               COMMON_IFACE_NAME, "\t/usr/etc/wifi-direct/p2p_supp.conf\tnl80211\t/var/run/wpa_supplicant");
-               res = _ws_send_cmd(global_sock, cmd, reply, sizeof(reply));
+       while (retry_count < 10) {
+               /* load wlan driver */
+               res = __ws_p2p_firmware_start();
                if (res < 0) {
-                       WDP_LOGE("Failed to send command to wpa_supplicant");
-                       close(global_sock);
-                       system("/usr/sbin/p2p_supp.sh stop");
-                       system("/usr/bin/wlan.sh stop");
-                       __WDP_LOG_FUNC_EXIT__;
+                       WDP_LOGE("Failed to load driver [ret=%d]", res);
                        return -1;
                }
+               WDP_LOGI("P2P firmware started with error %d", res);
 
-               if (strstr(reply, "FAIL")) {
-                       WDP_LOGE("Failed to create %s interface", COMMON_IFACE_NAME);
-                       close(global_sock);
-                       system("/usr/sbin/p2p_supp.sh stop");
-                       system("/usr/bin/wlan.sh stop");
-                       __WDP_LOG_FUNC_EXIT__;
-                       return -1;
+               if (__ws_check_net_interface(COMMON_IFACE_NAME) < 0) {
+                       usleep(150000); // wait for 150ms
+                       retry_count++;
+                       WDP_LOGE("interface is not up: retry, %d", retry_count);
+               } else {
+                       break;
                }
-               WDP_LOGD("Succeeded to create %s interface", COMMON_IFACE_NAME);
        }
-       WDP_LOGD("%s interface exist", COMMON_IFACE_NAME);
+
+       if (retry_count >= 10) {
+               WDP_LOGE("Driver loading is failed", res);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       if (retry_count > 0) {
+               // Give driver marginal time to config net
+               WDP_LOGE("Driver loading is done. Wait marginal time for driver");
+               sleep(1); // 1s
+       }
+
+       g_pd->concurrent = concurrent;
+
+
+       /* load wpa_supplicant */
+       res = __ws_p2p_supplicant_start();
+       if (res == -1) {
+               WDP_LOGE("Failed to start p2p_supplicant [%d: %s]", res, strerror(errno));
+               res = __ws_p2p_firmware_stop();
+               WDP_LOGI("P2P firmware stopped with error %d", res);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
 
        res = _connect_to_supplicant(COMMON_IFACE_NAME, &g_pd->common);
        if (res < 0) {
-               close(global_sock);
-               system("/usr/sbin/p2p_supp.sh stop");
-               system("/usr/bin/wlan.sh stop");
+               res = __ws_p2p_supplicant_stop();
+               WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
+               res = __ws_p2p_firmware_stop();
+               WDP_LOGI("P2P firmware stopped with error %d", res);
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
 
-       g_pd->global_sock = global_sock;
        g_pd->activated = TRUE;
 
+       _ws_update_local_dev_addr();
+
        __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int ws_deactivate()
+int ws_deactivate(int concurrent)
 {
        __WDP_LOG_FUNC_ENTER__;
        char cmd[32] = {0, };
        char reply[1024]={0,};
        int res = 0;
-       char ifname[OEM_IFACE_NAME_LEN];
 
        if (!g_pd->activated) {
                WDP_LOGE("Wi-Fi Direct is not activated");
                return -1;
        }
 
+       ws_stop_scan();
+
+       g_pd->concurrent = concurrent;
+
        if (g_pd->group) {
                _disconnect_from_supplicant(GROUP_IFACE_NAME, g_pd->group);
                g_pd->group = NULL;
        }
 
-       res = _disconnect_from_supplicant("wlan0", g_pd->common);
-       if (res < 0)
-               WDP_LOGE("Failed to disconnect common interface(%s) from supplicant. ", ifname);
-       g_pd->common = NULL;
-
        // terminate wpasupplicant
        snprintf(cmd, sizeof(cmd), WS_CMD_TERMINATE);
-       res = _ws_send_cmd(g_pd->global_sock, cmd, reply, sizeof(reply));
+       res = _ws_send_cmd(g_pd->common->ctrl_sock, cmd, reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
-               system("/usr/sbin/p2p_supp.sh stop");
+               res = __ws_p2p_supplicant_stop();
+               WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
                goto done;
        }
 
        if (!strncmp(reply, "FAIL", 4)) {
-               WDP_LOGE("Failed to terminate wpa_supplicant");
-               system("/usr/sbin/p2p_supp.sh stop");
+               WDP_LOGE( "Failed to terminate wpa_supplicant");
+               res = __ws_p2p_supplicant_stop();
+               WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
+               goto done;
        }
 
-done:
-       unlink(GLOBAL_INTF_PATH);
-       if (g_pd->global_sock >= SOCK_FD_MIN)
-               close(g_pd->global_sock);
-       g_pd->global_sock = -1;
+       res = _disconnect_from_supplicant(COMMON_IFACE_NAME, g_pd->common);
+       if (res < 0) {
+               WDP_LOGE("Failed to disconnect common interface(%s) from supplicant. ",
+                       COMMON_IFACE_NAME);
+       }
+
+       res = __ws_p2p_supplicant_stop();
+       WDP_LOGI("[/usr/sbin/p2p_supp.sh stop] returns %d", res);
 
-       system("/usr/bin/wlan.sh stop");
+done:
+       res = __ws_p2p_firmware_stop();
+       WDP_LOGI("P2P firmware stopped with error %d", res);
        g_pd->activated = FALSE;
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int ws_start_scan(wfd_oem_scan_param_s *param)
+static gboolean _retry_start_scan(gpointer data)
 {
-       __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[32] = {0, };
        char reply[1024] = {0, };
-       char time_str[4] = {0, };
+       static int retry_cnt = 0;
        int res = 0;
+       char *cmd = (char *)data;
 
-       if (!param) {
-               WDP_LOGE("Invalid parameter");
-               return -1;
+       if (NULL == sock || NULL == cmd) {
+               WDP_LOGE("Data is NULL, Retry Scan Failed !!!");
+               goto done;
        }
 
-       if (!sock) {
-               WDP_LOGE("Socket is NULL");
-               return -1;
+       if (WS_SCAN_RETRY_COUNT == retry_cnt) {
+               WDP_LOGE("Maximum Retry Reached. Aborting Scan.");
+               goto done;
        }
 
-       if (param->refresh)
-               _ws_flush();
-
-       if (param->scan_time)
-               snprintf(time_str, 4, " %d", param->scan_time);
-
-       if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND "%s", (param->scan_time > 0) ? time_str : "");
-       else
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_LISTEN);
-
        res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
-               __WDP_LOG_FUNC_EXIT__;
-               return -1;
+               goto done;
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to start scan");
-               __WDP_LOG_FUNC_EXIT__;
-               return -1;
+               WDP_LOGE("Retry Scan Failed, Retry after 100ms...");
+               retry_cnt++;
+               return TRUE;
        }
-       WDP_LOGD("Succeeded to start scan");
 
-       __WDP_LOG_FUNC_EXIT__;
-       return 0;
+       WDP_LOGD("Retry Scan Succeeded.");
+
+done:
+       retry_cnt = 0;
+       if (NULL != cmd) {
+               free(cmd);
+               cmd = NULL;
+       }
+       return FALSE;
 }
 
-int ws_restart_scan(int freq)
+int ws_start_scan(wfd_oem_scan_param_s *param)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[32] = {0, };
+       char cmd[40] = {0, };
        char reply[1024] = {0, };
+       char time_str[4] = {0, };
+       char type_str[20] = {0, };
        int res = 0;
+       char *retry_cmd = NULL;
+
+       if (!param) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
 
-       if (freq)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND " 2 freq=%d", freq);
+       if (param->refresh)
+               _ws_flush();
+
+       if (param->scan_time)
+               snprintf(time_str, 4, " %d", param->scan_time);
+
+       if (param->scan_type == WFD_OEM_SCAN_TYPE_SOCIAL)
+               snprintf(type_str, 20, " type=social");
+       else if (param->scan_type == WFD_OEM_SCAN_TYPE_SPECIFIC &&
+                       param->freq > 0)
+               snprintf(type_str, 20, " freq=%d", param->freq);
+       else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL1)
+               snprintf(type_str, 20, " type=specific1");
+       else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL6)
+               snprintf(type_str, 20, " type=specific6");
+       else if (param->scan_type == WFD_OEM_SCAN_TYPE_CHANNEL11)
+               snprintf(type_str, 20, " type=specific11");
+       else if (param->scan_type == WFD_OEM_SCAN_TYPE_GO_FREQ)
+               snprintf(type_str, 20, " type=frequency");
+
+       if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE)
+               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND "%s%s",
+                                       (param->scan_time > 0) ? time_str : "",
+                                       (param->scan_type) ? type_str : "");
        else
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_FIND " 2");
+               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_LISTEN);
 
        res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
        if (res < 0) {
-                       WDP_LOGE("Failed to send command to wpa_supplicant");
-                       __WDP_LOG_FUNC_EXIT__;
-                       return -1;
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to start scan");
+               WDP_LOGE("Failed to start scan, Retry");
+               retry_cmd = strdup(cmd);
+               /* Add Timeout of 100ms for retry SCAN */
+               g_timeout_add(100, _retry_start_scan, (gpointer) retry_cmd);
                __WDP_LOG_FUNC_EXIT__;
-               return -1;
+               return 0;
        }
        WDP_LOGD("Succeeded to start scan");
 
@@ -2266,15 +3091,14 @@ int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to get peer info [" MACSTR "]", MAC2STR(peer_addr));
+               WDP_LOGD("Failed to get peer info [" MACSECSTR "]", MAC2SECSTR(peer_addr));
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to get peer info [" MACSTR "]", MAC2STR(peer_addr));
+       WDP_LOGD("Succeeded to get peer info [" MACSECSTR "]", MAC2SECSTR(peer_addr));
 
        ws_dev = (wfd_oem_device_s*) calloc(1, sizeof(wfd_oem_device_s));
 
-       // TODO: parsing peer info
        res = _parsing_peer_info(reply, ws_dev);
        if (res < 0) {
                WDP_LOGE("Failed to parsing peer info");
@@ -2302,7 +3126,7 @@ int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int
        }
 
        snprintf(cmd, sizeof(cmd), WS_CMD_P2P_PROV_DISC MACSTR "%s",
-                                                       MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
+                                       MAC2STR(peer_addr), _ws_wps_to_txt(wps_mode));
 
        if (join)
                strncat(cmd, WS_STR_JOIN, 5);
@@ -2315,12 +3139,14 @@ int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to send provision discovery to peer[" MACSTR "]", MAC2STR(peer_addr));
+               WDP_LOGD("Failed to send provision discovery to peer[" MACSECSTR "]",
+                                                               MAC2SECSTR(peer_addr));
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to send provision discovery to peer[" MACSTR "]", MAC2STR(peer_addr));
-       memcpy(g_pd->pd_addr, peer_addr, OEM_MACADDR_LEN);
+       WDP_LOGD("Succeeded to send provision discovery to peer[" MACSECSTR "]",
+                                                               MAC2SECSTR(peer_addr));
+       memcpy(g_pd_out, peer_addr, OEM_MACADDR_LEN);
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
@@ -2331,6 +3157,7 @@ int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
        char cmd[64] = {0, };
+       char freq_str[11] ={0, };
        char reply[1024] = {0, };
        int res = 0;
 
@@ -2361,6 +3188,11 @@ int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
        if (param->conn_flags & WFD_OEM_CONN_TYPE_PERSISTENT)
                strncat(cmd, WS_STR_PERSISTENT, 11);
 
+       if (param->freq > 0) {
+               snprintf(freq_str, sizeof(freq_str), WS_STR_FREQ "%d", param->freq);
+               strncat(cmd, freq_str, sizeof(freq_str));
+       }
+
        WDP_LOGI("Connection command [%s]", cmd);
 
        res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
@@ -2371,11 +3203,11 @@ int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to connect with peer[" MACSTR "]", MAC2STR(peer_addr));
+               WDP_LOGD("Failed to connect with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to send connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
+       WDP_LOGD("Succeeded to send connection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
@@ -2385,11 +3217,23 @@ int ws_disconnect(unsigned char *peer_addr)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[32] = {0, };
+       char cmd[48] = {0, };
        char reply[1024]={0,};
        int res;
 
-       snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_REMOVE "%s", GROUP_IFACE_NAME);
+       if (!peer_addr) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       if (!sock) {
+               WDP_LOGE("Socket is NULL");
+               return -1;
+       }
+
+       WDP_LOGD("Peer address is [" MACSECSTR "]. Disconnect selected peer", MAC2SECSTR(peer_addr));
+
+       snprintf(cmd, sizeof(cmd), WS_CMD_DISCONNECT MACSTR " %s", MAC2STR(peer_addr), GROUP_IFACE_NAME);
        res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -2398,11 +3242,11 @@ int ws_disconnect(unsigned char *peer_addr)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to disconnect with peer[" MACSTR "]", MAC2STR(peer_addr));
+               WDP_LOGD("Failed to disconnect with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to send disconnection command to peer[" MACSTR "]", MAC2STR(peer_addr));
+       WDP_LOGD("Succeeded to send disconnection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
@@ -2412,7 +3256,7 @@ int ws_reject_connection(unsigned char *peer_addr)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[40] = {0, };
+       char cmd[64] = {0, };
        char reply[1024]={0,};
        int res;
 
@@ -2421,7 +3265,7 @@ int ws_reject_connection(unsigned char *peer_addr)
                return -1;
        }
 
-       snprintf(cmd, sizeof(cmd), WS_CMD_P2P_REJECT MACSTR, MAC2STR(peer_addr));
+       snprintf(cmd, sizeof(cmd), WS_CMD_P2P_CONNECT MACSTR "%s userReject", MAC2STR(peer_addr), WS_STR_PBC);
        res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
        if (res < 0) {
                        WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -2430,11 +3274,11 @@ int ws_reject_connection(unsigned char *peer_addr)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to reject connection with peer[" MACSTR "]", MAC2STR(peer_addr));
+               WDP_LOGD("Failed to reject connection with peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to send reject connection command to peer[" MACSTR "]", MAC2STR(peer_addr));
+       WDP_LOGD("Succeeded to send reject connection command to peer[" MACSECSTR "]", MAC2SECSTR(peer_addr));
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
@@ -2482,11 +3326,12 @@ int ws_get_supported_wps_mode()
        return 0;
 }
 
-int ws_create_group(int persistent, int freq)
+int ws_create_group(int persistent, int freq, const char *passphrase)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
        char cmd[44] = {0, };
+       char freq_str[11] = {0, };
        char reply[1024]={0,};
        int res = 0;
 
@@ -2495,12 +3340,24 @@ int ws_create_group(int persistent, int freq)
                return -1;
        }
 
-       if (persistent)
+       if (persistent) {
                snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD WS_STR_PERSISTENT);
-       else
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD WS_STR_FREQ_2G);
+       } else {
+               if (passphrase[0] != '\0') {
+
+                       snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD " passphrase=%s", passphrase);
+
+               }else{
+                       snprintf(cmd, sizeof(cmd), WS_CMD_P2P_GROUP_ADD);
+               }
+       }
 
-       // TODO: add frequency option
+       if (freq > 0) {
+               snprintf(freq_str, sizeof(freq_str), WS_STR_FREQ "%d", freq);
+               strncat(cmd, freq_str, sizeof(freq_str));
+       } else {
+               strncat(cmd, WS_STR_FREQ_2G, 8);
+       }
 
        res = _ws_send_cmd(sock->ctrl_sock, cmd, reply, sizeof(reply));
        if (res < 0) {
@@ -2563,7 +3420,7 @@ int ws_destroy_group(const char *ifname)
 int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
 {
        __WDP_LOG_FUNC_ENTER__;
-       ws_sock_data_s *sock = g_pd->group;
+       ws_sock_data_s *sock = g_pd->common;
        char cmd[128] = {0, };
        char reply[1024]={0,};
        int res = 0;
@@ -2578,7 +3435,8 @@ int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param)
                return -1;
        }
 
-       WDP_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]", MAC2STR(peer_addr), MAC2STR(param->go_dev_addr));
+       WDP_LOGD("Invite: Peer[" MACSECSTR "], GO Addr[" MACSECSTR "]",
+                               MAC2SECSTR(peer_addr), MAC2SECSTR(param->go_dev_addr));
 
        if (param->net_id)
                snprintf(cmd, sizeof(cmd), WS_CMD_P2P_INVITE "persistent=%d peer=" MACSTR " go_dev_addr=" MACSTR,
@@ -2652,7 +3510,7 @@ int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
 int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
 {
        __WDP_LOG_FUNC_ENTER__;
-       ws_sock_data_s *sock = g_pd->common;
+       ws_sock_data_s *sock = g_pd->group;
        char cmd[64] = {0, };
        char reply[1024]={0,};
        int res;
@@ -2695,7 +3553,7 @@ int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
 int ws_wps_cancel()
 {
        __WDP_LOG_FUNC_ENTER__;
-       ws_sock_data_s *sock = g_pd->common;
+       ws_sock_data_s *sock = g_pd->group;
        char reply[1024]={0,};
        int res;
 
@@ -2813,6 +3671,7 @@ int ws_set_dev_type(int pri_dev_type, int sec_dev_type)
 int ws_get_go_intent(int *go_intent)
 {
        __WDP_LOG_FUNC_ENTER__;
+
        ws_sock_data_s *sock = g_pd->common;
        char cmd[80] = {0, };
        char reply[1024]={0,};
@@ -2854,6 +3713,7 @@ int ws_get_go_intent(int *go_intent)
 int ws_set_go_intent(int go_intent)
 {
        __WDP_LOG_FUNC_ENTER__;
+
        ws_sock_data_s *sock = g_pd->common;
        char cmd[80] = {0, };
        char reply[1024]={0,};
@@ -2884,6 +3744,39 @@ int ws_set_go_intent(int go_intent)
        return 0;
 }
 
+int ws_set_country(char *ccode)
+{
+       __WDP_LOG_FUNC_ENTER__;
+       ws_sock_data_s *sock = g_pd->common;
+       char cmd[80] = {0, };
+       char reply[1024]={0,};
+       int res;
+
+       if (!sock) {
+               WDP_LOGE("Socket is NULL");
+               return -1;
+       }
+
+       snprintf(cmd, sizeof(cmd), WS_CMD_SET "country %s", ccode);
+
+       res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
+       if (res < 0) {
+               WDP_LOGE("Failed to send command to wpa_supplicant");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if (strstr(reply, "FAIL")) {
+               WDP_LOGE("Failed to set country");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       WDP_LOGD("Succeeded to set country(%s)", ccode);
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+
 int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
 {
        __WDP_LOG_FUNC_ENTER__;
@@ -2911,7 +3804,7 @@ int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
 
                res = _extract_word(ptr, &tmp_str);
                if (res > 0) {
-                       snprintf(networks[count].ssid, WS_SSID_LEN, tmp_str);
+                       snprintf(networks[count].ssid, WS_SSID_LEN, "%s", tmp_str);
                        free(tmp_str);
                        tmp_str = NULL;
                        ptr += res;
@@ -2952,36 +3845,33 @@ int _parsing_networks(char* buf, ws_network_info_s networks[], int *network_cnt)
        return 0;
 }
 
-int ws_service_add(wfd_oem_service_e service_type, char *data)
+int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[256] = {0, };
+       char cmd[80] = {0, };
        char reply[1024]={0,};
+       ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
+       wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
        int res;
+       int i, cnt;
+
+       if (!groups || !group_count) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
-       if (!data || !strlen(data)) {
-               WDP_LOGE( "Invalid parameter");
-               __WDP_LOG_FUNC_EXIT__;
-               return -1;
-       }
 
-       if (service_type == WFD_OEM_SERVICE_BONJOUR)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_SERVICE_ADD "bonjour %s", data);
-       else if (service_type == WFD_OEM_SERVICE_UPNP)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_SERVICE_ADD "upnp %s", data);
-       else if (service_type ==WFD_OEM_SERVICE_VENDORSPEC)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_SERVICE_ADD "vendor %s", data);
-       else{
-               WDP_LOGE( "Invalid parameter");
-               __WDP_LOG_FUNC_EXIT__;
-               return -1;
-       }
+       memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
 
+       /* Reading lists the configured networks, including stored information for persistent groups.
+       The identifier in this is used with p2p_group_add and p2p_invite to indicate witch persistent
+       group is to be reinvoked. */
+       snprintf(cmd, sizeof(cmd), WS_CMD_LIST_NETWORKS);
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -2990,46 +3880,65 @@ int ws_service_add(wfd_oem_service_e service_type, char *data)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to add service");
+               WDP_LOGE("Failed to get list of networks");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to add service");
+       WDP_LOGD("Succeeded to get list of networks");
+
+       _parsing_networks(reply, networks, &cnt);
+       WDP_LOGD("Persistent Group Count=%d", cnt);
+       if (cnt > WS_MAX_PERSISTENT_COUNT) {
+               WDP_LOGE("Persistent group count exceeded or parsing error");
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       wfd_persistent_groups = (wfd_oem_persistent_group_s*) calloc(1, cnt * sizeof(wfd_oem_persistent_group_s));
+       for(i = 0; i < cnt; i++) {
+               WDP_LOGD("----persistent group [%d]----", i);
+               WDP_LOGD("network_id=%d", networks[i].network_id);
+               WDP_LOGD("ssid=%s", networks[i].ssid);
+               WDP_LOGD("bssid=" MACSECSTR, MAC2SECSTR(networks[i].bssid));
+               WDP_LOGD("flags=%x", networks[i].flags);
+
+               wfd_persistent_groups[i].network_id = networks[i].network_id;
+               strncpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN);
+               wfd_persistent_groups[i].ssid[WS_SSID_LEN] = '\0';
+               memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
+       }
+
+       *group_count = cnt;
+       *groups = wfd_persistent_groups;
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int ws_service_del(wfd_oem_service_e service_type, char *data)
+int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[256] = {0, };
+       char cmd[80] = {0, };
        char reply[1024]={0,};
        int res;
+       int i;
+       ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
+       int network_count;
+
+       if (!ssid || !bssid) {
+               WDP_LOGE("Invalid parameter");
+               return -1;
+       }
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
-       if (!data || !strlen(data)) {
-               WDP_LOGE( "Invalid parameter");
-               __WDP_LOG_FUNC_EXIT__;
-               return 1;
-       }
 
-       if ( service_type == WFD_OEM_SERVICE_BONJOUR)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_SERVICE_DEL "bonjour %s", data);
-       else if (service_type == WFD_OEM_SERVICE_UPNP)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_SERVICE_DEL "upnp %s", data);
-       else if (service_type ==WFD_OEM_SERVICE_VENDORSPEC)
-               snprintf(cmd, sizeof(cmd), WS_CMD_P2P_SERVICE_DEL "vendor %s", data);
-       else{
-               WDP_LOGE( "Invalid parameter");
-               __WDP_LOG_FUNC_EXIT__;
-               return -1;
-       }
+       memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
 
+       strncpy(cmd, WS_CMD_LIST_NETWORKS, sizeof(cmd));
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -3038,74 +3947,61 @@ int ws_service_del(wfd_oem_service_e service_type, char *data)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to delete service");
+               WDP_LOGE("Failed to get list of networks");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to delete service");
+       WDP_LOGD("Succeeded to get list of networks");
 
-       __WDP_LOG_FUNC_EXIT__;
-       return 0;
-}
+       _parsing_networks(reply, networks, &network_count);
 
-static int _ws_query_generation(unsigned char* MAC, wfd_oem_service_e type, char *data, char *buff)
-{
-       __WDP_LOG_FUNC_ENTER__;
-       int res=0;
-       int tlv_len=0;
-       char *query=NULL;
-
-       switch(type){
-       case WFD_OEM_SERVICE_ALL:
-               query=strndup(SERVICE_TYPE_ALL,8);
-       break;
-       case WFD_OEM_SERVICE_BONJOUR:
-               query=strndup(SERVICE_TYPE_BONJOUR,8);
-       break;
-       case WFD_OEM_SERVICE_UPNP:
-               query=strndup(SERVICE_TYPE_UPNP,8);
-       break;
-       case WFD_OEM_SERVICE_VENDORSPEC:
-               query=strndup(SERVICE_TYPE_VENDOR_SPECIFIC,8);
-       break;
-       default:
-               WDP_LOGE( "Invalid parameter");
-               __WDP_LOG_FUNC_EXIT__;
-               return -1;
-       break;
-       }
+       for(i=0;i<network_count;i++) {
+               WDP_LOGD("----persistent group [%d]----", i);
+               WDP_LOGD("network_id=%d", networks[i].network_id);
+               WDP_LOGD("ssid=%s", networks[i].ssid);
+               WDP_LOGD("bssid=" MACSECSTR, MAC2SECSTR(networks[i].bssid));
+               WDP_LOGD("flags=%x", networks[i].flags);
 
-       if(data && (tlv_len = strlen(data)))
-       {
-               if(type == WFD_OEM_SERVICE_UPNP)
-               {
-                       snprintf(buff, 256, WS_CMD_P2P_SERV_DISC_REQ MACSTR " upnp %s", MAC2STR(MAC), data);
-               }else{
+               if (!memcmp(bssid, networks[i].bssid, OEM_MACADDR_LEN) && !strcmp(ssid, networks[i].ssid)) {
 
-                       if(type == WFD_OEM_SERVICE_BONJOUR)
-                               tlv_len = tlv_len/2 + 2;
+                       WDP_LOGD("Persistent group found [%d: %s]", networks[i].network_id, ssid);
 
-                       query[0] = '0' + (char)(tlv_len/16);
-                       if(tlv_len%16 < 10)
-                               query[1] = '0' + (char)(tlv_len%16);
-                       else
-                               query[1] = 'a' + (char)(tlv_len%16) - 10;
-                       snprintf(buff, 256, WS_CMD_P2P_SERV_DISC_REQ MACSTR " %s%s", MAC2STR(MAC), query, data);
+                       memset(cmd, 0x0, sizeof(cmd));
+                       memset(reply, 0x0, sizeof(reply));
+
+                       snprintf(cmd, sizeof(cmd), WS_CMD_REMOVE_NETWORK " %d", networks[i].network_id);
+                       res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
+                       if (res < 0) {
+                               WDP_LOGE("Failed to send command to wpa_supplicant");
+                               __WDP_LOG_FUNC_EXIT__;
+                               return -1;
+                       }
+
+                       if (strstr(reply, "FAIL")) {
+                               WDP_LOGE("Failed to remove persistent group");
+                               __WDP_LOG_FUNC_EXIT__;
+                               return -1;
+                       }
+                       WDP_LOGD("Succeeded to remove persistent group");
+
+                       break;
                }
-       }else{
-               snprintf(buff, 256, WS_CMD_P2P_SERV_DISC_REQ MACSTR " %s", MAC2STR(MAC), query);
        }
-       if(query != NULL)
-               free(query);
+
+       if (i == network_count) {
+               WDP_LOGE("Persistent group not found [%s]", ssid);
+               return -1;
+       }
+
        __WDP_LOG_FUNC_EXIT__;
-       return res;
+       return 0;
 }
 
-int ws_serv_disc_req(unsigned char* MAC, wfd_oem_service_e type, char *data)
+int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[256] = {0, };
+       char cmd[80] = {0, };
        char reply[1024]={0,};
        int res;
 
@@ -3114,13 +4010,7 @@ int ws_serv_disc_req(unsigned char* MAC, wfd_oem_service_e type, char *data)
                return -1;
        }
 
-       res = _ws_query_generation(MAC, type, data, cmd);
-       if (res < 0) {
-               WDP_LOGE("Failed to generate query");
-               __WDP_LOG_FUNC_EXIT__;
-               return -1;
-       }
-
+       snprintf(cmd, sizeof(cmd), WS_CMD_SET "persistent_reconnect %d", reconnect);
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -3129,67 +4019,178 @@ int ws_serv_disc_req(unsigned char* MAC, wfd_oem_service_e type, char *data)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to request service discovery");
+               WDP_LOGE("Failed to register WFDS service");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
+       WDP_LOGD("Succeeded to register WFDS service");
 
-       res = strtol(reply, NULL, 16);
-       WDP_LOGD("Succeeded to request service discovery(%d)", res);
        __WDP_LOG_FUNC_EXIT__;
-       return res;
-
+       return 0;
 }
 
-int ws_serv_disc_cancel(int identifier)
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
        char cmd[80] = {0, };
        char reply[1024]={0,};
        int res;
+       char query[30] = {'0','2','0','0','F','F','0','1'};
+       char mac_str[18] = {0, };
+       wfd_oem_service_s *service = NULL;
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
 
-       snprintf(cmd, sizeof(cmd), WS_CMD_P2P_SERV_DISC_CANCEL " %x", identifier);
+       memset(cmd, 0x00, 80);
+       memset(reply, 0x00, WS_REPLY_LEN);
+
+       query[1] += OEM_SERVICE_TYPE_LEN /2;
+       service = (wfd_oem_service_s*) calloc(1, sizeof(wfd_oem_service_s));
+       if (!service) {
+               WDP_LOGE("Failed to allocate memory for service");
+               return -1;
+       }
+
+       if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
+               mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
+               snprintf(mac_str, OEM_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
+       } else {
+               snprintf(mac_str, OEM_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
+       }
+
+       switch(service_type) {
+               case WFD_OEM_SERVICE_TYPE_ALL:
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_ALL);
+                       strncpy(service->service_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN);
+                       service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
+               break;
+               case WFD_OEM_SERVICE_TYPE_BONJOUR:
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_BONJOUR);
+                       strncpy(service->service_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN);
+                       service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
+               break;
+               case WFD_OEM_SERVICE_TYPE_UPNP:
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, SERV_DISC_REQ_UPNP);
+                       strncpy(service->service_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN);
+                       service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
+               break;
+               case WFD_OEM_SERVICE_TYPE_BT_ADDR:
+                       strncat(query, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, query);
+                       strncpy(service->service_type, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
+                       service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
+                       break;
+               case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
+                       strncat(query, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_REQ " %s %s", mac_str, query);
+                       strncpy(service->service_type, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
+                       service->service_type[OEM_SERVICE_TYPE_LEN] = '\0';
+                       break;
+               default:
+                       WDP_LOGE("Invalid Service type");
+                       __WDP_LOG_FUNC_EXIT__;
+                       if (service)
+                               free(service);
+                       return -1;
+       }
 
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
                __WDP_LOG_FUNC_EXIT__;
+               if (service)
+                       free(service);
                return -1;
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to cancel service discovery");
+               WDP_LOGE("Failed to start service discovery");
                __WDP_LOG_FUNC_EXIT__;
+               if (service)
+                       free(service);
                return -1;
        }
-       WDP_LOGD("Succeeded to cancel service discovery");
+       WDP_LOGD("Succeeded to start service discovery");
+
+       strncpy(service->dev_addr, mac_str, OEM_MACSTR_LEN - 1);
+       service->dev_addr[OEM_MACSTR_LEN - 1] = '\0';
+       WDP_LOGD("query id :[0x%s]",reply);
+       strncpy(service->query_id, reply, OEM_QUERY_ID_LEN);
+       service->query_id[OEM_QUERY_ID_LEN] = '\0';
+
+       res = _check_service_query_exists(service);
+       if(res) {
+               free(service);
+       } else {
+               service_list = g_list_append(service_list, service);
+       }
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
-
 }
 
-static int _ws_wifi_display_enable(int enable)
+int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
        char cmd[80] = {0, };
        char reply[1024]={0,};
        int res;
+       char query_id[OEM_QUERY_ID_LEN + 1] = {0, };
+       char mac_str[18] = {0, };
+       wfd_oem_service_s *data = NULL;
+       char s_type[OEM_SERVICE_TYPE_LEN + 1] ={0, };
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
 
-       snprintf(cmd, sizeof(cmd), WS_CMD_SET WS_STR_WIFI_DISPLAY " %d", enable);
+       memset(cmd, 0x00, 80);
+       memset(reply, 0x00, WS_REPLY_LEN);
+
+       if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
+               mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
+               snprintf(mac_str, OEM_MACSTR_LEN , "%s", SERV_BROADCAST_ADDRESS);
+       } else {
+               snprintf(mac_str, OEM_MACSTR_LEN, MACSTR, MAC2STR(mac_addr));
+       }
+
+       switch(service_type) {
+               case WFD_OEM_SERVICE_TYPE_ALL:
+                       strncpy(s_type, SERV_DISC_REQ_ALL, OEM_SERVICE_TYPE_LEN);
+               break;
+               case WFD_OEM_SERVICE_TYPE_BONJOUR:
+                       strncpy(s_type, SERV_DISC_REQ_BONJOUR, OEM_SERVICE_TYPE_LEN);
+               break;
+               case WFD_OEM_SERVICE_TYPE_UPNP:
+                       strncpy(s_type, SERV_DISC_REQ_UPNP, OEM_SERVICE_TYPE_LEN);
+               break;
+               case WFD_OEM_SERVICE_TYPE_BT_ADDR:
+                       strncpy(s_type, SERVICE_TYPE_BT_ADDR, OEM_SERVICE_TYPE_LEN);
+                       break;
+               case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
+                       strncpy(s_type, SERVICE_TYPE_CONTACT_INFO, OEM_SERVICE_TYPE_LEN);
+                       break;
+               default:
+                       __WDP_LOG_FUNC_EXIT__;
+                       WDP_LOGE("Invalid Service type");
+                       return -1;
+       }
+
+       WDP_LOGD("Cancel service discovery service_type [%d]", service_type);
+       WDP_LOGD("Cancel service discovery s_type [%s]", s_type);
 
+       data = _remove_service_query(s_type, mac_str, query_id);
+       if (NULL == data)
+               return -1;
+
+       snprintf(cmd, sizeof(cmd), WS_CMD_SERV_DISC_CANCEL " %s", query_id);
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -3198,69 +4199,148 @@ static int _ws_wifi_display_enable(int enable)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to enable or disable wifi display");
+               WDP_LOGE("Failed to cancel service discovery");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to enable or disable wifi display");
+       WDP_LOGD("Succeeded to cancel service discovery");
+
+       service_list = g_list_remove(service_list, data);
+       free(data);
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
 
-static int _ws_build_element(int value, int field_length, char* buff)
+int _convert_bonjour_to_hex(char *query, char *rdata, char **hex)
 {
-       __WDP_LOG_FUNC_ENTER__;
+       char hex_key[256] = {0, };;
+       char hex_value[256] = {0, };;
+       char *token = NULL;
+       char *temp = NULL;
+       int len = 0;
+       int tot_len = 0;
        int i = 0;
-       char tmp =0;
+       char temp_str[256] = {0, };
+       char *result_str = NULL;
 
-       if(!field_length)
+       if (!query || !hex) {
+               WDP_LOGE("Invalid parameter");
                return -1;
+       }
 
-       for(i = 1; i <= field_length; i++)
-       {
-               tmp = value >> (field_length - i)*4;
-               tmp = tmp%16;
+       token = strtok_r(query, ".", &temp);
+       while (token) {
+               if (!strcmp(token, "local")) {
+                       WDP_LOGD("Query conversion done");
+                       break;
+               }
+               WDP_LOGD("Token: %s", token);
+               len = strlen(token);
+               sprintf(temp_str, "%02x", len);
+               for (i=0; i<len; i++) {
+                       sprintf(temp_str+i*2+2, "%02x", token[i]);
+               }
+               strncat(hex_key, temp_str, 2+2*len);
+               WDP_LOGD("Converting: %s", hex_key);
+               memset(temp_str, 0x0, 256);
 
-               if(tmp < 10)
-                       buff[i - 1] = '0' + tmp;
-               else
-                       buff[i - 1] = 'a' + tmp -10;
+               token = strtok_r(NULL, ".", &temp);
        }
-       __WDP_LOG_FUNC_EXIT__;
+
+       if (token && strstr(token, "local")) {
+               strncat(hex_key, "c011", 4);
+               strncat(hex_key, "000c", 4);
+               strncat(hex_key, "01", 2);
+       } else {
+               strncat(hex_key, "c011", 4);
+               strncat(hex_key, "0010", 4);
+               strncat(hex_key, "01", 2);
+       }
+
+       if (!rdata || !strlen(rdata)) {
+               WDP_LOGD("RDATA is NULL");
+               strncat(hex_value, "00", 2);
+       } else {
+               token = strtok_r(rdata, ".", &temp);
+               while (token) {
+                       WDP_LOGD("Token: %s", token);
+                       len = strlen(token);
+                       sprintf(temp_str, "%02x", len);
+                       for (i=0; i<len; i++) {
+                               sprintf(temp_str+i*2+2, "%02x", token[i]);
+                       }
+                       strncat(hex_value, temp_str, 2+2*len);
+                       WDP_LOGD("Converting: %s", hex_value);
+                       memset(temp_str, 0x0, 256);
+
+                       token = strtok_r(NULL, ".", &temp);
+               }
+       }
+
+       strncat(hex_value, "c027", 4);
+
+       tot_len = strlen(hex_key) + strlen(hex_value);
+       result_str = (char*) calloc(1, tot_len+2);
+       if (!result_str) {
+               WDP_LOGE("Failed to allocate memory for result string");
+               return -1;
+       }
+       snprintf(result_str, tot_len+2, "%s %s", hex_key, hex_value);
+
+       *hex = result_str;
+
        return 0;
 }
 
-int ws_init_wifi_display(wfd_oem_display_e type, int port, int hdcp)
+int ws_serv_add(wfd_oem_new_service_s *service)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[80] = {0, };
+       char cmd[256] = {0, };
        char reply[1024]={0,};
        int res;
-       char subelem[17] = {0,};
-       unsigned int device_info = 0;
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
 
-       if (_ws_wifi_display_enable(1) != 0) {
-               return -1;
-       }
+       switch (service->protocol) {
+       case WFD_OEM_SERVICE_TYPE_BONJOUR:
+               {
+                       WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR");
+                       WDP_LOGD("Query: %s", service->data.bonjour.query);
+                       WDP_LOGD("RData: %s", service->data.bonjour.rdata);
+                       char *hex = NULL;
+
+                       res = _convert_bonjour_to_hex(service->data.bonjour.query,
+                                                                   service->data.bonjour.rdata,
+                                                                   &hex);
+                       if (res < 0) {
+                               WDP_LOGE("Failed to convert Key string as hex string");
+                               return -1;
+                       }
 
-       device_info = type;
-       device_info+= hdcp<<8;
-       device_info+=1<<4;                                              //for availability bit
+                       WDP_LOGD("Converted Hexadecimal string [%s]", hex);
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_ADD " bonjour %s", hex);
+                       g_free(hex);
 
-       _ws_build_element(6, 4, &subelem[0]);
-       _ws_build_element(device_info, 4, &subelem[4]);
-       _ws_build_element(port, 4, &subelem[8]);
-       _ws_build_element(40, 4, &subelem[12]); //for maximum throughput
+               }
+               break;
+       case WFD_OEM_SERVICE_TYPE_UPNP:
+               {
+                       WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_UPNP");
 
-       snprintf(cmd, sizeof(cmd), WS_CMD_WFD_SUBELEM_SET "%d %s",
-                         WFD_SUBELEM_ID_DEVICE_INFO, subelem);
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_ADD " upnp %s %s",
+                                       service->data.upnp.version, service->data.upnp.service);
+               }
+               break;
+       default:
+               WDP_LOGE("This service type is not supported [%d]", service->protocol);
+               __WDP_LOG_FUNC_EXIT__;
+               return -1;
+       }
 
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
@@ -3270,124 +4350,103 @@ int ws_init_wifi_display(wfd_oem_display_e type, int port, int hdcp)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to set wifi display");
+               WDP_LOGE("Failed to add service");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to initialize wifi display");
-
-       __WDP_LOG_FUNC_EXIT__;
-       return 0;
-}
-
-int ws_deinit_wifi_display(int enable)
-{
-       __WDP_LOG_FUNC_ENTER__;
-
-       if (_ws_wifi_display_enable(0) != 0) {
-               return -1;
-       }
-
-       WDP_LOGD("Succeeded to deinitialize wifi display");
+       WDP_LOGD("Succeeded to add service");
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count)
+int ws_serv_del(wfd_oem_new_service_s *service)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
-       char cmd[80] = {0, };
+       char cmd[256] = {0, };
        char reply[1024]={0,};
-       ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
-       wfd_oem_persistent_group_s *wfd_persistent_groups = NULL;
        int res;
-       int i, cnt;
-
-       if (!groups || !group_count) {
-               WDP_LOGE("Invalid parameter");
-               return -1;
-       }
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
 
-       memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
+       switch (service->protocol) {
+       case WFD_OEM_SERVICE_TYPE_BONJOUR:
+               {
+                       WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_BONJOUR, Data: %s", service);
+                       char *hex_key = NULL;
 
-       /* Reading lists the configured networks, including stored information for persistent groups.
-       The identifier in this is used with p2p_group_add and p2p_invite to indicate witch persistent
-       group is to be reinvoked. */
-       snprintf(cmd, sizeof(cmd), WS_CMD_LIST_NETWORKS);
-       res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
-       if (res < 0) {
-               WDP_LOGE("Failed to send command to wpa_supplicant");
+                       res = _convert_bonjour_to_hex(service->data.bonjour.query, NULL, &hex_key);
+                       if (res != 0) {
+                               WDP_LOGE("Failed to convert Key string as hex string");
+                               return -1;
+                       }
+
+                       WDP_LOGD("Converted Hexadecimal string [%s]", hex_key);
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_DEL " bonjour %s", hex_key);
+                       g_free(hex_key);
+               }
+               break;
+       case WFD_OEM_SERVICE_TYPE_UPNP:
+               {
+                       WDP_LOGD("Service type: WFD_OEM_SERVICE_TYPE_UPNP");
+
+                       snprintf(cmd, sizeof(cmd), WS_CMD_SERVICE_DEL " upnp %s %s",
+                                       service->data.upnp.version, service->data.upnp.service);
+               }
+               break;
+       default:
+               WDP_LOGE("This service type is not supported");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
 
-       if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to get list of networks");
+       res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
+       if (res < 0) {
+               WDP_LOGE("Failed to send command to wpa_supplicant");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to get list of networks");
 
-       _parsing_networks(reply, networks, &cnt);
-       WDP_LOGD("Persistent Group Count=%d", cnt);
-       if (cnt > WS_MAX_PERSISTENT_COUNT) {
-               WDP_LOGE("Persistent group count exceeded or parsing error");
+       if (strstr(reply, "FAIL")) {
+               WDP_LOGE("Failed to add service");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-
-       wfd_persistent_groups = (wfd_oem_persistent_group_s*) calloc(1, cnt * sizeof(wfd_oem_persistent_group_s));
-       for(i = 0; i < cnt; i++) {
-               WDP_LOGD("----persistent group [%d]----", i);
-               WDP_LOGD("network_id=%d", networks[i].network_id);
-               WDP_LOGD("ssid=%s", networks[i].ssid);
-               WDP_LOGD("bssid=" MACSTR, MAC2STR(networks[i].bssid));
-               WDP_LOGD("flags=%x", networks[i].flags);
-
-               wfd_persistent_groups[i].network_id = networks[i].network_id;
-               strncpy(wfd_persistent_groups[i].ssid, networks[i].ssid, WS_SSID_LEN);
-               wfd_persistent_groups[i].ssid[WS_SSID_LEN] = '\0';
-               memcpy(wfd_persistent_groups[i].go_mac_address, networks[i].bssid, WS_MACADDR_LEN);
-       }
-
-       *group_count = cnt;
-       *groups = wfd_persistent_groups;
+       WDP_LOGD("Succeeded to add service");
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
 
-int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int ws_miracast_init(int enable)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
        char cmd[80] = {0, };
        char reply[1024]={0,};
        int res;
-       int i;
-       ws_network_info_s networks[WS_MAX_PERSISTENT_COUNT];
-       int network_count;
 
-       if (!ssid || !bssid) {
-               WDP_LOGE("Invalid parameter");
-               return -1;
-       }
+       unsigned int length = 0x0006;
+       unsigned int dev_info = 0x0110;
+       unsigned int ctrl_port = 0x07E6;
+       unsigned int max_tput = 0x0028;
+       //unsigned int bssid = 0x00;
+       unsigned int cpled_sink_status = 0x00;
+       /* param : enable or disable*/
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
 
-       memset(networks, 0, (sizeof(ws_network_info_s) * WS_MAX_PERSISTENT_COUNT));
+       snprintf(cmd, sizeof(cmd), WS_CMD_SET "wifi_display %d", enable);
 
-       strncpy(cmd, WS_CMD_LIST_NETWORKS, sizeof(cmd));
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -3396,70 +4455,129 @@ int ws_remove_persistent_group(char *ssid, unsigned char *bssid)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to get list of networks");
+               WDP_LOGE("Failed to initialize miracast");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to get list of networks");
+       WDP_LOGD("Succeeded to initialize miracast");
 
-       _parsing_networks(reply, networks, &network_count);
+       if (enable) {
+               /* param : dev_info */
+               memset(cmd, 0x0, 80);
+               memset(reply, 0x0, WS_REPLY_LEN);
 
-       for(i=0;i<network_count;i++) {
-               WDP_LOGD("----persistent group [%d]----", i);
-               WDP_LOGD("network_id=%d", networks[i].network_id);
-               WDP_LOGD("ssid=%s", networks[i].ssid);
-               WDP_LOGD("bssid=" MACSTR, MAC2STR(networks[i].bssid));
-               WDP_LOGD("flags=%x", networks[i].flags);
+               snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x%04x%04x",
+                                                               WFD_SUBELM_ID_DEV_INFO, length, dev_info, ctrl_port, max_tput);
+               res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
+               if (res < 0) {
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
 
-               if (!memcmp(bssid, networks[i].bssid, WS_MACADDR_LEN) && !strcmp(ssid, networks[i].ssid)) {
+               if (strstr(reply, "FAIL")) {
+                       WDP_LOGE("Failed to set miracast parameter(device info)");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+               WDP_LOGD("Succeeded to set miracast parameter(device info)");
 
-                       WDP_LOGD("Persistent group found [%d: %s]", networks[i].network_id, ssid);
+               /* param : Associated BSSID Subelement */
+               memset(cmd, 0x0, 80);
+               memset(reply, 0x0, WS_REPLY_LEN);
 
-                       memset(cmd, 0x0, sizeof(cmd));
-                       memset(reply, 0x0, sizeof(reply));
+               snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%s",
+                                                               WFD_SUBELM_ID_ASSOC_BSSID, WFD_SUBELM_LEN_ASSOC_BSSID, "000000000000");
+               res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
+               if (res < 0) {
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
 
-                       snprintf(cmd, sizeof(cmd), WS_CMD_REMOVE_NETWORK " %d", networks[i].network_id);
-                       res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
-                       if (res < 0) {
-                               WDP_LOGE("Failed to send command to wpa_supplicant");
-                               __WDP_LOG_FUNC_EXIT__;
-                               return -1;
-                       }
+               if (strstr(reply, "FAIL")) {
+                       WDP_LOGE("Failed to set miracast parameter(BSSID subelement)");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+               WDP_LOGD("Succeeded to set miracast parameter(BSSID subelement)");
 
-                       if (strstr(reply, "FAIL")) {
-                               WDP_LOGE("Failed to remove persistent group");
-                               __WDP_LOG_FUNC_EXIT__;
-                               return -1;
-                       }
-                       WDP_LOGD("Succeeded to remove persistent group");
+               /* param : cpled_sink_status */
+               memset(cmd, 0x0, 80);
+               memset(reply, 0x0, WS_REPLY_LEN);
 
-                       break;
+               snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%02x",
+                                                               WFD_SUBELM_ID_CUPLED_SYNC_INFO, 0x01, cpled_sink_status);
+               res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
+               if (res < 0) {
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
                }
-       }
 
-       if (i == network_count) {
-               WDP_LOGE("Persistent group not found [%s]", ssid);
-               return -1;
+               if (strstr(reply, "FAIL")) {
+                       WDP_LOGE("Failed to set miracast parameter(Cuppled sink status)");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+               WDP_LOGD("Succeeded to set miracast parameter(Cuppled sink status)");
+
+
+               /* param : WFD Extended Capability */
+               memset(cmd, 0x0, 80);
+               memset(reply, 0x0, WS_REPLY_LEN);
+
+               snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x",
+                                                               WFD_SUBELM_ID_EXT_CAPAB, 0x02, 0x00);
+               res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
+               if (res < 0) {
+                       WDP_LOGE("Failed to send command to wpa_supplicant");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+
+               if (strstr(reply, "FAIL")) {
+                       WDP_LOGE("Failed to set miracast parameter(Extended Capability)");
+                       __WDP_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+               WDP_LOGD("Succeeded to set miracast parameter(Extended Capability)");
+
        }
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
+int ws_set_display(wfd_oem_display_s *wifi_display)
 {
        __WDP_LOG_FUNC_ENTER__;
        ws_sock_data_s *sock = g_pd->common;
        char cmd[80] = {0, };
        char reply[1024]={0,};
        int res;
+       unsigned int device_info = 0;
 
        if (!sock) {
                WDP_LOGE("Socket is NULL");
                return -1;
        }
 
-       snprintf(cmd, sizeof(cmd), "%s persistent_reconnect %d", WS_CMD_SET, reconnect);
+       WDP_LOGD("Wi-Fi Display type: [%d]", wifi_display->type);
+       WDP_LOGD("Wi-Fi Display avai: [%d]", wifi_display->availablity);
+       WDP_LOGD("Wi-Fi Display hdcp: [%d]", wifi_display->hdcp_support);
+       WDP_LOGD("Wi-Fi Display hdcp: [%d]", wifi_display->port);
+       WDP_LOGD("Wi-Fi Display sync: [%d]", wifi_display->max_tput);
+
+       device_info = wifi_display->type;
+       device_info+= (wifi_display->hdcp_support)<<8;
+       device_info+= (wifi_display->availablity)<<4;                                           //for availability bit
+
+       snprintf(cmd, sizeof(cmd), WS_CMD_SUBELEM_SET "%d %04x%04x%04x%04x",
+                                                       WFD_SUBELM_ID_DEV_INFO, WFD_SUBELEM_LEN_DEV_INFO,
+                                                       device_info, wifi_display->port, wifi_display->max_tput);
+
+       WDP_LOGD("Wi-Fi Display set command: [%s]", cmd);
        res = _ws_send_cmd(sock->ctrl_sock, cmd, (char*) reply, sizeof(reply));
        if (res < 0) {
                WDP_LOGE("Failed to send command to wpa_supplicant");
@@ -3468,11 +4586,23 @@ int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
        }
 
        if (strstr(reply, "FAIL")) {
-               WDP_LOGE("Failed to register WFDS service");
+               WDP_LOGE("Failed to set wifi display");
                __WDP_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDP_LOGD("Succeeded to register WFDS service");
+       WDP_LOGD("Succeeded to set wifi display");
+
+       __WDP_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+int ws_refresh()
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       _ws_cancel();
+       _ws_flush();
 
        __WDP_LOG_FUNC_EXIT__;
        return 0;
diff --git a/plugin/wpasupplicant/emul/CMakeLists.txt b/plugin/wpasupplicant/emul/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..d5a4a1b
--- /dev/null
@@ -0,0 +1,29 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(wifi-direct-plugin-wpasupplicant C)
+
+# Set required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED capi-network-wifi-direct glib-2.0 gio-2.0 dlog)
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/oem)
+INCLUDE_DIRECTORIES(SRCS include)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+SET(SRCS
+       wfd-plugin-wpasupplicant-emul.c
+       )
+
+# library build
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+#SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.1.0)
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME})
+
+# install
+INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib)
diff --git a/plugin/wpasupplicant/emul/include/wfd-plugin-wpasupplicant.h b/plugin/wpasupplicant/emul/include/wfd-plugin-wpasupplicant.h
new file mode 100755 (executable)
index 0000000..cdbff32
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * This file declares wifi direct wpasupplicant plugin functions and structures.
+ *
+ * @file               wfd-plugin-wpasupplicant.h
+ * @author     Gibyoung Kim (lastkgb.kim@samsung.com)
+ * @version    0.7
+ */
+
+#ifndef __WFD_PLUGIN_WPASUPPLICANT_H__
+#define __WFD_PLUGIN_WPASUPPLICANT_H__
+
+#ifdef USE_DLOG
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "WIFI_DIRECT_PLUGIN"
+
+#define WDP_LOGV(format, args...) LOGV(format, ##args)
+#define WDP_LOGD(format, args...) LOGD(format, ##args)
+#define WDP_LOGI(format, args...) LOGI(format, ##args)
+#define WDP_LOGW(format, args...) LOGW(format, ##args)
+#define WDP_LOGE(format, args...) LOGE(format, ##args)
+#define WDP_LOGF(format, args...) LOGF(format, ##args)
+
+#define __WDP_LOG_FUNC_ENTER__ LOGD("Enter")
+#define __WDP_LOG_FUNC_EXIT__ LOGD("Quit")
+
+#define WDP_SECLOGI(format, args...) SECURE_LOG(LOG_INFO, LOG_TAG, format, ##args)
+#define WDP_SECLOGD(format, args...) SECURE_LOG(LOG_DEBUG, LOG_TAG, format, ##args)
+
+#else /* USE_DLOG */
+
+#define WDP_LOGV(format, args...)
+#define WDP_LOGD(format, args...)
+#define WDP_LOGI(format, args...)
+#define WDP_LOGW(format, args...)
+#define WDP_LOGE(format, args...)
+#define WDP_LOGF(format, args...)
+
+#define __WDP_LOG_FUNC_ENTER__
+#define __WDP_LOG_FUNC_EXIT__
+
+#define WDP_SECLOGI(format, args...)
+#define WDP_SECLOGD(format, args...)
+
+#endif /* USE_DLOG */
+
+typedef struct {
+       int initialized;        // check whether plugin is initialized or not. block init function if initialized
+       int activated;
+       int concurrent;
+       int global_sock;
+       ws_sock_data_s *common;
+       ws_sock_data_s *group;
+       unsigned char local_dev_addr[WS_MACADDR_LEN];
+       wfd_oem_event_cb callback;
+       void *user_data;
+} ws_plugin_data_s;
+
+int ws_init(wfd_oem_event_cb callback, void *user_data);
+int ws_deinit();
+int ws_activate(int concurrent);
+int ws_deactivate(int concurrent);
+int ws_start_scan(wfd_oem_scan_param_s *param);
+int ws_restart_scan(int freq);
+int ws_stop_scan();
+int ws_get_visibility(int *visibility);
+int ws_set_visibility(int visibility);
+int ws_get_scan_result(GList **peers, int *peer_count);
+int ws_get_peer_info(unsigned char *peer_addr, wfd_oem_device_s **peer);
+int ws_prov_disc_req(unsigned char *peer_addr, wfd_oem_wps_mode_e wps_mode, int join);
+int ws_connect(unsigned char *peer_addr, wfd_oem_conn_param_s *param);
+int ws_disconnect(unsigned char *peer_addr);
+int ws_reject_connection(unsigned char *peer_addr);
+int ws_cancel_connection(unsigned char *peer_addr);
+int ws_get_connected_peers(GList **peers, int *peer_count);
+int ws_get_pin(char *pin);
+int ws_set_pin(char *pin);
+int ws_get_supported_wps_mode();
+int ws_create_group(int persistent, int freq, const char *passphrase);
+int ws_destroy_group(const char *ifname);
+int ws_invite(unsigned char *peer_addr, wfd_oem_invite_param_s *param);
+int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin);
+int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin);
+int ws_wps_cancel();
+int ws_get_dev_name(char *dev_name);
+int ws_set_dev_name(char *dev_name);
+int ws_get_dev_mac(char *dev_mac);
+int ws_get_dev_type(int *pri_dev_type, int *sec_dev_type);
+int ws_set_dev_type(int pri_dev_type, int sec_dev_type);
+int ws_get_go_intent(int *go_intent);
+int ws_set_go_intent(int go_intent);
+int ws_set_country(char *ccode);
+
+int ws_get_persistent_groups(wfd_oem_persistent_group_s **groups, int *group_count);
+int ws_remove_persistent_group(char *ssid, unsigned char *bssid);
+int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect);
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+int ws_start_service_discovery(unsigned char *mac_addr, int service_type);
+int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type);
+
+int ws_serv_add(wfd_oem_new_service_s *service);
+int ws_serv_del(wfd_oem_new_service_s *service);
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int ws_miracast_init(int enable);
+int ws_set_display(wfd_oem_display_s *wifi_display);
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+int ws_refresh();
+
+#endif /* __WFD_PLUGIN_WPASUPPLICANT_H__ */
@@ -11,6 +11,7 @@
 #include "wifi-direct-oem.h"
 #include "wfd-plugin-wpasupplicant.h"
 
+
 static wfd_oem_ops_s supplicant_ops = {
        .init = ws_init,
        .deinit = ws_deinit,
@@ -30,6 +31,7 @@ static wfd_oem_ops_s supplicant_ops = {
        .disconnect = ws_disconnect,
        .reject_connection = ws_reject_connection,
        .cancel_connection = ws_cancel_connection,
+
        .get_connected_peers = ws_get_connected_peers,
        .get_pin = ws_get_pin,
        .set_pin = ws_set_pin,
@@ -39,6 +41,8 @@ static wfd_oem_ops_s supplicant_ops = {
        .destroy_group = ws_destroy_group,
        .invite = ws_invite,
        .wps_start = ws_wps_start,
+       .enrollee_start = ws_enrollee_start,
+       .wps_cancel = ws_wps_cancel,
 
        .get_dev_name = ws_get_dev_name,
        .set_dev_name = ws_set_dev_name,
@@ -50,13 +54,25 @@ static wfd_oem_ops_s supplicant_ops = {
        .get_persistent_groups = ws_get_persistent_groups,
        .remove_persistent_group = ws_remove_persistent_group,
        .set_persistent_reconnect = ws_set_persistent_reconnect,
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       .start_service_discovery = ws_start_service_discovery,
+       .cancel_service_discovery = ws_cancel_service_discovery,
+
+       .serv_add = ws_serv_add,
+       .serv_del = ws_serv_del,
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       .miracast_init = ws_miracast_init,
+       .set_display = ws_set_disply,
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
        };
 
 static ws_plugin_data_s *g_pd;
 
-int wfd_plugin_load( struct wfd_oem_ops_s **ops)
+int wfd_plugin_load(wfd_oem_ops_s **ops)
 {
-
        return -1;
 }
 
@@ -76,7 +92,7 @@ int ws_deinit()
        return -1;
 }
 
-int ws_activate()
+int ws_activate(int concurrent)
 {
        __WDP_LOG_FUNC_ENTER__;
 
@@ -84,7 +100,7 @@ int ws_activate()
        return -1;
 }
 
-int ws_deactivate()
+int ws_deactivate(int concurrent)
 {
        __WDP_LOG_FUNC_ENTER__;
 
@@ -245,6 +261,30 @@ int ws_wps_start(unsigned char *peer_addr, int wps_mode, const char *pin)
        return -1;
 }
 
+int ws_enrollee_start(unsigned char *peer_addr, int wps_mode, const char *pin)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return -1;
+}
+
+int ws_wps_cancel()
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return -1;
+}
+
+int ws_set_static_ip(unsigned char *ip_addr)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXIT__;
+       return -1;
+}
+
 int ws_get_dev_name(char *dev_name)
 {
        __WDP_LOG_FUNC_ENTER__;
@@ -324,3 +364,56 @@ int ws_set_persistent_reconnect(unsigned char *bssid, int reconnect)
        __WDP_LOG_FUNC_EXIT__;
        return -1;
 }
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+
+int ws_start_service_discovery(unsigned char *mac_addr, int service_type)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXUT__;
+       return -1;
+}
+
+int ws_cancel_service_discovery(unsigned char *mac_addr, int service_type);
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXUT__;
+       return -1;
+}
+
+int ws_serv_add(wfd_oem_new_service_s *service)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXUT__;
+       return -1;
+}
+
+int ws_serv_del(wfd_oem_new_service_s *service)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXUT__;
+       return -1;
+}
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int ws_miracast_init(int enable)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXUT__;
+       return -1;
+}
+
+int ws_set_wifi_display(wfd_oem_display_s *wifi_display)
+{
+       __WDP_LOG_FUNC_ENTER__;
+
+       __WDP_LOG_FUNC_EXUT__;
+       return -1;
+}
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
old mode 100644 (file)
new mode 100755 (executable)
index d05aba1..f3b11e1
@@ -40,8 +40,9 @@
 #include <vconf.h>
 
 #include <wifi-direct.h>
-#include <wifi-direct-internal.h>
+//#include <security-server/security-server.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-oem.h"
 #include "wifi-direct-session.h"
 #include "wifi-direct-state.h"
 #include "wifi-direct-peer.h"
 
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+#include "wifi-direct-service.h"
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
 
 static int _wfd_deregister_client(void *data, int client_id);
 static gboolean wfd_client_process_request(GIOChannel *source,
                                                                        GIOCondition condition,
                                                                        gpointer user_data);
-
-
+#if 0
+#if !defined TIZEN_TV
+static int _wfd_check_client_privilege(int client_sock, int cmd);
+#endif
+#endif
 char *wfd_server_print_cmd(wifi_direct_cmd_e cmd)
 {
        switch (cmd)
@@ -74,6 +82,8 @@ char *wfd_server_print_cmd(wifi_direct_cmd_e cmd)
                return "WIFI_DIRECT_CMD_DEACTIVATE";
        case WIFI_DIRECT_CMD_START_DISCOVERY:
                return "WIFI_DIRECT_CMD_START_DISCOVERY";
+       case WIFI_DIRECT_CMD_START_DISCOVERY_SPECIFIC_CHANNEL:
+               return "WIFI_DIRECT_CMD_START_DISCOVERY_SPECIFIC_CHANNEL";
        case WIFI_DIRECT_CMD_CANCEL_DISCOVERY:
                return "WIFI_DIRECT_CMD_CANCEL_DISCOVERY";
        case WIFI_DIRECT_CMD_GET_DISCOVERY_RESULT:
@@ -114,10 +124,6 @@ char *wfd_server_print_cmd(wifi_direct_cmd_e cmd)
                return "WIFI_DIRECT_CMD_GET_WPS_PIN";
        case WIFI_DIRECT_CMD_GENERATE_WPS_PIN:
                return "WIFI_DIRECT_CMD_GENERATE_WPS_PIN";
-       case WIFI_DIRECT_CMD_GET_INCOMMING_PEER_INFO:
-               return "WIFI_DIRECT_CMD_GET_INCOMMING_PEER_INFO";
-       case WIFI_DIRECT_CMD_GET_PASSPHRASE:
-               return "WIFI_DIRECT_CMD_GET_PASSPHRASE";
        case WIFI_DIRECT_CMD_SET_WPA:
                return "WIFI_DIRECT_CMD_SET_WPA";
        case WIFI_DIRECT_CMD_GET_SUPPORTED_WPS_MODE:
@@ -139,8 +145,8 @@ char *wfd_server_print_cmd(wifi_direct_cmd_e cmd)
                return "WIFI_DIRECT_CMD_SET_GO_INTENT";
        case WIFI_DIRECT_CMD_GET_GO_INTENT:
                return "WIFI_DIRECT_CMD_GET_GO_INTENT";
-       case WIFI_DIRECT_CMD_GET_DEVICE_MAC:
-               return "WIFI_DIRECT_CMD_GET_DEVICE_MAC";
+       case WIFI_DIRECT_CMD_GET_MAC_ADDR:
+               return "WIFI_DIRECT_CMD_GET_MAC_ADDR";
        case WIFI_DIRECT_CMD_IS_AUTONOMOUS_GROUP:
                return "WIFI_DIRECT_CMD_IS_AUTONOMOUS_GROUP";
        case WIFI_DIRECT_CMD_SET_MAX_CLIENT:
@@ -175,28 +181,54 @@ char *wfd_server_print_cmd(wifi_direct_cmd_e cmd)
                return "WIFI_DIRECT_CMD_SET_DEVICE_NAME";
        case WIFI_DIRECT_CMD_SET_OEM_LOGLEVEL:
                return "WIFI_DIRECT_CMD_SET_OEM_LOGLEVEL";
-       case WIFI_DIRECT_CMD_SERVICE_ADD:
-               return "WIFI_DIRECT_CMD_SERVICE_ADD";
-       case WIFI_DIRECT_CMD_SERVICE_DEL:
-               return "WIFI_DIRECT_CMD_SERVICE_DEL";
-       case WIFI_DIRECT_CMD_SERV_DISC_REQ:
-               return "WIFI_DIRECT_CMD_SERV_DISC_REQ";
-       case WIFI_DIRECT_CMD_SERV_DISC_CANCEL:
-               return "WIFI_DIRECT_CMD_SERV_DISC_CANCEL";
-       case WIFI_DIRECT_CMD_INIT_WIFI_DISPLAY:
-               return "WIFI_DIRECT_CMD_INIT_WIFI_DISPLAY";
-       case WIFI_DIRECT_CMD_DEINIT_WIFI_DISPLAY:
-               return "WIFI_DIRECT_CMD_DEINIT_WIFI_DISPLAY";
-       case WIFI_DIRECT_CMD_GET_DISPLAY_PORT:
-               return "WIFI_DIRECT_CMD_GET_DISPLAY_PORT";
-       case WIFI_DIRECT_CMD_GET_DISPLAY_TYPE:
-               return "WIFI_DIRECT_CMD_GET_DISPLAY_TYPE";
-       case WIFI_DIRECT_CMD_GET_ACCESS_LIST:
-               return"WIFI_DIRECT_CMD_GET_ACCESS_LIST";
-       case WIFI_DIRECT_CMD_ADD_TO_ACCESS_LIST:
-               return "WIFI_DIRECT_CMD_ADD_TO_ACCESS_LIST";
-       case WIFI_DIRECT_CMD_DEL_FROM_ACCESS_LIST:
-               return "WIFI_DIRECT_CMD_DEL_FROM_ACCESS_LIST";
+       case WIFI_DIRECT_CMD_GET_PEER_INFO:
+               return "WIFI_DIRECT_CMD_GET_PEER_INFO";
+
+       case WIFI_DIRECT_CMD_SET_PASSPHRASE:
+               return "WIFI_DIRECT_CMD_SET_PASSPHRASE";
+       case WIFI_DIRECT_CMD_GET_PASSPHRASE:
+               return "WIFI_DIRECT_CMD_GET_PASSPHRASE";
+       case WIFI_DIRECT_CMD_SET_AUTOCONNECTION_PEER:
+               return "WIFI_DIRECT_CMD_SET_AUTOCONNECTION_PEER";
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       case WIFI_DIRECT_CMD_REGISTER_LOCAL_SERVICE:
+               return "WIFI_DIRECT_CMD_REGISTER_LOCAL_SERVICE";
+       case WIFI_DIRECT_CMD_DEREGISTER_LOCAL_SERVICE:
+               return "WIFI_DIRECT_CMD_DEREGISTER_LOCAL_SERVICE";
+       case WIFI_DIRECT_CMD_START_SERVICE_DISCOVERY:
+               return "WIFI_DIRECT_CMD_START_SERVICE_DISCOVERY";
+       case WIFI_DIRECT_CMD_CANCEL_SERVICE_DISCOVERY:
+               return "WIFI_DIRECT_CMD_CANCEL_SERVICE_DISCOVERY";
+       case WIFI_DIRECT_CMD_REGISTER_SERVICE:
+               return "WIFI_DIRECT_CMD_REGISTER_SERVICE";
+       case WIFI_DIRECT_CMD_DEREGISTER_SERVICE:
+               return "WIFI_DIRECT_CMD_DEREGISTER_SERVICE";
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       case WIFI_DIRECT_CMD_INIT_MIRACAST:
+               return "WIFI_DIRECT_CMD_INIT_MIRACAST";
+       case WIFI_DIRECT_CMD_INIT_DISPLAY:
+               return "WIFI_DIRECT_CMD_INIT_DISPLAY";
+       case WIFI_DIRECT_CMD_DEINIT_DISPLAY:
+               return "WIFI_DIRECT_CMD_DEINIT_DISPLAY";
+       case WIFI_DIRECT_CMD_SET_DISPLAY:
+               return "WIFI_DIRECT_CMD_SET_DISPLAY";
+       case WIFI_DIRECT_CMD_SET_DISPLAY_AVAILABILITY:
+               return "WIFI_DIRECT_CMD_SET_DISPLAY_AVAILABILITY";
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_TYPE:
+               return "WIFI_DIRECT_CMD_GET_PEER_DISPLAY_TYPE";
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_AVAILABILITY:
+               return "WIFI_DIRECT_CMD_GET_PEER_DISPLAY_AVAILABILITY";
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_HDCP:
+               return "WIFI_DIRECT_CMD_GET_PEER_DISPLAY_HDCP";
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_PORT:
+               return "WIFI_DIRECT_CMD_GET_PEER_DISPLAY_PORT";
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_THROUGHPUT:
+               return "WIFI_DIRECT_CMD_GET_PEER_DISPLAY_THROUGHPUT";
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
        default:
                return "WIFI_DIRECT_CMD_INVALID";
 
@@ -423,10 +455,24 @@ static int _wfd_register_client(void *data, int sock)
                        res = WIFI_DIRECT_ERROR_NOT_PERMITTED; // WIFI_DIRECT_ERROR_ALREADY_EXIST
                        goto send_response;
                }
-
-               client = (wfd_client_s*) calloc(1, sizeof(wfd_client_s));
+/*FixMe: Tizen TV Plardorm return the "ACCESS DENIED" error
+Ignore the check for now*/
+#if 0
+#if !defined TIZEN_TV
+               if (_wfd_check_client_privilege(sock, req.cmd) != WIFI_DIRECT_ERROR_NONE) {
+                       rsp.result = WIFI_DIRECT_ERROR_AUTH_FAILED;
+                       goto done;
+               }
+#endif
+#endif
+               client = (wfd_client_s*) g_try_malloc0(sizeof(wfd_client_s));
+               if (!client) {
+                       WDS_LOGE("Failed to allocate memory");
+                       return -1;
+               }
                client->client_id = sock;
                client->ssock = sock;
+               client->asock = WFD_CLIENT_PENDING_SOCKET;
 
                GIOChannel *gio = NULL;
                gio = g_io_channel_unix_new(sock);
@@ -448,6 +494,16 @@ static int _wfd_register_client(void *data, int sock)
                        goto done;
                }
 
+       /*FixMe: Tizen TV Plardorm return the "ACCESS DENIED" error
+       Ignore the check for now*/
+#if 0
+#if !defined TIZEN_TV
+               if (_wfd_check_client_privilege(sock, req.cmd) != WIFI_DIRECT_ERROR_NONE) {
+                       res = WIFI_DIRECT_ERROR_AUTH_FAILED;
+                       goto done;
+               }
+#endif
+#endif
                client->asock = sock;
                WDS_LOGD("Async socket[%d] for New client[%d] added.", sock, client->client_id);
                goto done;
@@ -506,6 +562,12 @@ static int _wfd_deregister_client(void *data, int client_id)
                WDS_LOGE("Failed to find client[%d]", client_id);
                return -1;
        }
+
+       if (client->asock == WFD_CLIENT_PENDING_SOCKET) {
+               WDS_LOGE("This client[%d] is initializing(pending)...", client->client_id);
+               return 1;
+       }
+
        manager->clients = g_list_remove(manager->clients, client);
        manager->client_count--;
        WDS_LOGD("Client [%d] is removed. %d client left", client->client_id, manager->client_count);
@@ -519,8 +581,7 @@ static int _wfd_deregister_client(void *data, int client_id)
        g_idle_add((GSourceFunc) _wfd_remove_event_source, (gpointer) client->gsource_id);
        client->gsource_id = 0;
 
-       if (client)
-               free(client);
+       g_free(client);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -663,7 +724,6 @@ int wfd_client_handler_deinit(wfd_manager_s *manager)
        GList *temp = NULL;
        wfd_client_s *client = NULL;
 
-       // TODO: remove event source watching GIOChannel
        if (manager->serv_sock >= SOCK_FD_MIN)
                close(manager->serv_sock);
        manager->serv_sock = -1;
@@ -673,25 +733,148 @@ int wfd_client_handler_deinit(wfd_manager_s *manager)
        temp = g_list_first(manager->clients);
        while(temp) {
                client = temp->data;
-               if (client->ssock >= SOCK_FD_MIN)
-                       close(client->ssock);
-               client->ssock = -1;
-               if (client->asock >= SOCK_FD_MIN)
-                       close(client->asock);
-               client->asock = -1;
-               g_source_remove(client->gsource_id);
-               client->gsource_id = 0;
-               free(client);
+               if(client != NULL) {
+                       if (client->ssock >= SOCK_FD_MIN)
+                               close(client->ssock);
+                       client->ssock = -1;
+                       if (client->asock >= SOCK_FD_MIN)
+                               close(client->asock);
+                       client->asock = -1;
+                       g_source_remove(client->gsource_id);
+                       client->gsource_id = 0;
+                       g_free(client);
+               }
                temp = g_list_next(temp);
        }
-       g_list_free(manager->clients);
+
+       if (manager->clients) {
+               g_list_free(manager->clients);
+               manager->clients = NULL;
+       }
 
        manager->client_count = 0;
        manager->clients = NULL;
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
+#if 0
+#if !defined TIZEN_TV
+static int _wfd_check_client_privilege(int client_sock, int cmd)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       int ret = SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
 
+       switch (cmd) {
+       case WIFI_DIRECT_CMD_ACTIVATE:
+       case WIFI_DIRECT_CMD_DEACTIVATE:
+       case WIFI_DIRECT_CMD_CONNECT:
+       case WIFI_DIRECT_CMD_CANCEL_CONNECT:
+       case WIFI_DIRECT_CMD_CANCEL_CONNECTION:
+       case WIFI_DIRECT_CMD_SEND_CONNECT_REQ:
+       case WIFI_DIRECT_CMD_REJECT_CONNECTION:
+       case WIFI_DIRECT_CMD_DISCONNECT:
+       case WIFI_DIRECT_CMD_DISCONNECT_ALL:
+       case WIFI_DIRECT_CMD_ACTIVATE_PUSHBUTTON:
+       case WIFI_DIRECT_CMD_CREATE_GROUP:
+       case WIFI_DIRECT_CMD_DESTROY_GROUP:
+       case WIFI_DIRECT_CMD_ACTIVATE_PERSISTENT_GROUP:
+       case WIFI_DIRECT_CMD_DEACTIVATE_PERSISTENT_GROUP:
+       case WIFI_DIRECT_CMD_REMOVE_PERSISTENT_GROUP:
+       case WIFI_DIRECT_CMD_SET_GO_INTENT:
+       case WIFI_DIRECT_CMD_GENERATE_WPS_PIN:
+       case WIFI_DIRECT_CMD_SET_WPS_PIN:
+       case WIFI_DIRECT_CMD_SET_DEVICE_NAME:
+       case WIFI_DIRECT_CMD_SET_SSID:
+       case WIFI_DIRECT_CMD_SET_MAX_CLIENT:
+       case WIFI_DIRECT_CMD_SET_PASSPHRASE:
+       case WIFI_DIRECT_CMD_SET_AUTOCONNECTION_PEER:
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       case WIFI_DIRECT_CMD_INIT_MIRACAST:
+
+       case WIFI_DIRECT_CMD_INIT_DISPLAY:
+       case WIFI_DIRECT_CMD_DEINIT_DISPLAY:
+       case WIFI_DIRECT_CMD_SET_DISPLAY:
+       case WIFI_DIRECT_CMD_SET_DISPLAY_AVAILABILITY:
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       case WIFI_DIRECT_CMD_REGISTER_LOCAL_SERVICE:
+       case WIFI_DIRECT_CMD_DEREGISTER_LOCAL_SERVICE:
+       case WIFI_DIRECT_CMD_REGISTER_SERVICE:
+       case WIFI_DIRECT_CMD_DEREGISTER_SERVICE:
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+               ret = security_server_check_privilege_by_sockfd(client_sock, "wifi-direct::admin", "rw");
+               break;
+       case WIFI_DIRECT_CMD_START_DISCOVERY:
+       case WIFI_DIRECT_CMD_START_DISCOVERY_SPECIFIC_CHANNEL:
+       case WIFI_DIRECT_CMD_CANCEL_DISCOVERY:
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       case WIFI_DIRECT_CMD_START_SERVICE_DISCOVERY:
+       case WIFI_DIRECT_CMD_CANCEL_SERVICE_DISCOVERY:
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+               ret = security_server_check_privilege_by_sockfd(client_sock, "wifi-direct::discover", "w");
+               break;
+       case WIFI_DIRECT_CMD_REGISTER:
+       case WIFI_DIRECT_CMD_DEREGISTER:
+       case WIFI_DIRECT_CMD_INIT_ASYNC_SOCKET:
+       case WIFI_DIRECT_CMD_GET_LINK_STATUS:
+       case WIFI_DIRECT_CMD_GET_DEVICE_NAME:
+       case WIFI_DIRECT_CMD_GET_SSID:
+       case WIFI_DIRECT_CMD_GET_OPERATING_CHANNEL:
+       case WIFI_DIRECT_CMD_GET_GO_INTENT:
+       case WIFI_DIRECT_CMD_GET_MAX_CLIENT:
+       case WIFI_DIRECT_CMD_GET_IP_ADDR:
+       case WIFI_DIRECT_CMD_GET_MAC_ADDR:
+       case WIFI_DIRECT_CMD_GET_SUPPORTED_WPS_MODE:
+       case WIFI_DIRECT_CMD_GET_REQ_WPS_MODE:
+       case WIFI_DIRECT_CMD_GET_LOCAL_WPS_MODE:
+       case WIFI_DIRECT_CMD_GET_WPS_PIN:
+       case WIFI_DIRECT_CMD_GET_DISCOVERY_RESULT:
+       case WIFI_DIRECT_CMD_GET_CONNECTED_PEERS_INFO:
+       case WIFI_DIRECT_CMD_GET_PERSISTENT_GROUP_INFO:
+       case WIFI_DIRECT_CMD_IS_DISCOVERABLE:
+       case WIFI_DIRECT_CMD_IS_LISTENING_ONLY:
+       case WIFI_DIRECT_CMD_IS_GROUPOWNER:
+       case WIFI_DIRECT_CMD_IS_AUTONOMOUS_GROUP:
+       case WIFI_DIRECT_CMD_IS_AUTOCONNECTION_MODE:
+       case WIFI_DIRECT_CMD_IS_PERSISTENT_GROUP:
+       case WIFI_DIRECT_CMD_GET_PEER_INFO:
+       case WIFI_DIRECT_CMD_GET_PASSPHRASE:
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_TYPE:
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_AVAILABILITY:
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_HDCP:
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_PORT:
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_THROUGHPUT:
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+        ret = security_server_check_privilege_by_sockfd(client_sock, "wifi-direct::info", "r");
+               break;
+       case WIFI_DIRECT_CMD_SET_REQ_WPS_MODE:
+        ret = security_server_check_privilege_by_sockfd(client_sock, "wifi-direct::info", "rw");
+               break;
+       case WIFI_DIRECT_CMD_SET_AUTOCONNECTION_MODE:
+        ret = security_server_check_privilege_by_sockfd(client_sock, "wifi-direct::native", "rw");
+               break;
+       default:
+               WDS_LOGE("Unknown command[%d]", cmd);
+               break;
+       }
+
+       if(ret == SECURITY_SERVER_API_SUCCESS) {
+               WDS_LOGD("Security Server: API Access Validation Success");
+               return WIFI_DIRECT_ERROR_NONE;
+       } else if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
+               WDS_LOGE("Access denied to client id [%d]", client_sock);
+               return WIFI_DIRECT_ERROR_PERMISSION_DENIED;
+       } else {
+               WDS_LOGE("Security Server, exception[%d]", ret);
+               return WIFI_DIRECT_ERROR_AUTH_FAILED;
+       }
+}
+#endif
+#endif
 static gboolean wfd_client_process_request(GIOChannel *source,
                                                                        GIOCondition condition,
                                                                        gpointer user_data)
@@ -724,12 +907,21 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                WDS_LOGE("Client socket busy");
                return TRUE;
        }
-       WDS_LOGD("Client request [%d:%s], %d bytes read from socket[%d]", req.cmd, wfd_server_print_cmd(req.cmd), res, sock);
+       WDS_LOGI("Client request [%d:%s], %d bytes read from socket[%d]", req.cmd, wfd_server_print_cmd(req.cmd), res, sock);
 
        rsp.cmd = req.cmd;
        rsp.client_id = req.client_id;
        rsp.result = WIFI_DIRECT_ERROR_NONE;
-
+#if 0
+#if !defined TIZEN_TV
+       /*FixMe: Tizen TV Plardorm return the "ACCESS DENIED" error
+       Ignore the check for now*/
+       if (_wfd_check_client_privilege(sock, req.cmd) != WIFI_DIRECT_ERROR_NONE) {
+               rsp.result = WIFI_DIRECT_ERROR_AUTH_FAILED;
+               goto send_response;
+       }
+#endif
+#endif
        switch (req.cmd) {
        case WIFI_DIRECT_CMD_DEREGISTER:        // manager
                _wfd_send_to_client(sock, (char*) &rsp, sizeof(rsp));
@@ -758,25 +950,10 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        return FALSE;
                }
 
-               noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+               noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                noti->event = WIFI_DIRECT_CLI_EVENT_ACTIVATION;
                noti->error = wfd_manager_activate(manager);
-               res = wfd_client_send_event(manager, noti);
-               if (res < 0) {
-                       WDS_LOGE("Failed to send Notification to client");
-                       free(noti);
-                       __WDS_LOG_FUNC_EXIT__;
-                       return FALSE;
-               }
-               WDS_LOGD("Succeeded to send Notification[%d] to client", noti->event);
-
-               if (noti->error == WIFI_DIRECT_ERROR_NONE) {
-                       wfd_manager_local_config_set(manager);
-                       wfd_util_start_wifi_direct_popup();
-               }
-               free(noti);
-
-               goto done;
+               goto send_notification;
                break;
        case WIFI_DIRECT_CMD_DEACTIVATE:        // manager (event)
                if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
@@ -791,34 +968,10 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        return FALSE;
                }
 
-               noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+               noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                noti->event = WIFI_DIRECT_CLI_EVENT_DEACTIVATION;
                noti->error = wfd_manager_deactivate(manager);
-               res = wfd_client_send_event(manager, noti);
-               if (res < 0) {
-                       WDS_LOGE("Failed to send Notification to client");
-                       free(noti);
-                       __WDS_LOG_FUNC_EXIT__;
-                       return FALSE;
-               }
-               WDS_LOGD("Succeeded to send Notification[%d] to client", noti->event);
-               free(noti);
-               wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
-               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
-
-               wfd_destroy_group(manager, GROUP_IFNAME);
-               wfd_destroy_session(manager);
-               wfd_manager_init_service(manager->local);
-               wfd_manager_init_query(manager);
-               if(manager->local->wifi_display)
-               {
-                       free(manager->local->wifi_display);
-                       manager->local->wifi_display = NULL;
-               }
-               wfd_peer_clear_all(manager);
-               WDS_LOGD("peer count[%d], peers[%d]", manager->peer_count, manager->peers);
-               wfd_local_reset_data(manager);
-               goto done;
+               goto send_notification;
                break;
        case WIFI_DIRECT_CMD_GET_LINK_STATUS:
                rsp.param1 = manager->state;
@@ -853,7 +1006,7 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
                        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        if (req.data.int1) {
                                noti->event = WIFI_DIRECT_CLI_EVENT_DISCOVER_START_LISTEN_ONLY;
                                manager->scan_mode = WFD_SCAN_MODE_PASSIVE;
@@ -864,6 +1017,60 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        noti->error = WIFI_DIRECT_ERROR_NONE;
                }
                break;
+       case WIFI_DIRECT_CMD_START_DISCOVERY_SPECIFIC_CHANNEL:
+               {
+                       if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
+                                       manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
+                                       manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
+                               WDS_LOGE("Wi-Fi Direct is not available status for scanning.");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+
+                       wfd_oem_scan_param_s param;
+                       memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
+                       param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
+                       param.scan_time = req.data.int1;        // timeout
+                       int channel = req.data.int2;    // channel
+
+                       if (channel == WIFI_DIRECT_DISCOVERY_FULL_SCAN) {
+                               param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
+                       } else if (channel == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL) {
+                               param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
+                       } else if (channel == WIFI_DIRECT_DISCOVERY_CHANNEL1) {
+                               param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL1;
+                               param.freq = 2412;
+                       } else if (channel == WIFI_DIRECT_DISCOVERY_CHANNEL6) {
+                               param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL6;
+                               param.freq = 2437;
+                       } else if (channel == WIFI_DIRECT_DISCOVERY_CHANNEL11) {
+                               param.scan_type = WFD_OEM_SCAN_TYPE_CHANNEL11;
+                               param.freq = 2462;
+                       } else {
+                               param.scan_type = WFD_OEM_SCAN_TYPE_SPECIFIC;
+                               param.freq = wfd_util_channel_to_freq(channel);
+                       }
+
+                       WDS_LOGD("timeout[%d], frequency[%d] ", param.scan_time, param.freq);
+                       res = wfd_oem_start_scan(manager->oem_ops, &param);
+                       if (res < 0) {
+                               WDS_LOGE("Failed to start specific scan");
+                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                               break;
+                       }
+                       WDS_LOGE("Succeeded to start specific scan");
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_DISCOVERING);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DISCOVERING);
+
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
+                       if (channel == WIFI_DIRECT_DISCOVERY_FULL_SCAN)
+                               noti->event = WIFI_DIRECT_CLI_EVENT_DISCOVER_START;
+                       else
+                               noti->event = WIFI_DIRECT_CLI_EVENT_DISCOVER_START_SEARCH_LISTEN;
+                       noti->error = WIFI_DIRECT_ERROR_NONE;
+                       manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
+               }
+               break;
        case WIFI_DIRECT_CMD_CANCEL_DISCOVERY:
                if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
                                manager->state != WIFI_DIRECT_STATE_DISCOVERING) {
@@ -879,7 +1086,7 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                }
                WDS_LOGE("Succeeded to stop scan");
 
-               noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+               noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                noti->event = WIFI_DIRECT_CLI_EVENT_DISCOVER_END;
                noti->error = WIFI_DIRECT_ERROR_NONE;
                if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
@@ -919,13 +1126,13 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                        manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
                                        manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
                                rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                               break;
+                               goto send_response;
                        }
 
                        wfd_group_s *group = (wfd_group_s*) manager->group;
                        if (group && group->member_count >= manager->max_station) {
                                rsp.result = WIFI_DIRECT_ERROR_TOO_MANY_CLIENT;
-                               break;
+                               goto send_response;
                        }
 
                        res = _wfd_send_to_client(sock, (char*) &rsp, sizeof(rsp));
@@ -936,24 +1143,26 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                return FALSE;
                        }
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
                        res = wfd_manager_connect(manager, req.data.mac_addr);
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        if (res < 0) {
-                               WDS_LOGE("Failed to connet with peer " MACSTR, MAC2STR(req.data.mac_addr));
                                noti->event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
                                noti->error = WIFI_DIRECT_ERROR_OPERATION_FAILED;
-                               snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        } else {
                                noti->event = WIFI_DIRECT_CLI_EVENT_CONNECTION_START;
                                noti->error = WIFI_DIRECT_ERROR_NONE;
-                               snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        }
+                       g_snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        goto send_notification;
                }
                break;
        case WIFI_DIRECT_CMD_SEND_CONNECT_REQ:
                {
-                       // TODO: check state
+                       if (manager->state != WIFI_DIRECT_STATE_CONNECTING) {
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               goto send_response;
+                       }
+
                        wfd_group_s *group = (wfd_group_s*) manager->group;
                        if (group && group->member_count >= manager->max_station) {
                                rsp.result = WIFI_DIRECT_ERROR_TOO_MANY_CLIENT;
@@ -968,24 +1177,52 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                return FALSE;
                        }
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
                        res = wfd_manager_accept_connection(manager, req.data.mac_addr);
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        if (res < 0) {
-                               WDS_LOGE("Failed to connet with peer " MACSTR, MAC2STR(req.data.mac_addr));
                                noti->event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
                                noti->error = WIFI_DIRECT_ERROR_OPERATION_FAILED;
-                               snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        } else {
                                noti->event = WIFI_DIRECT_CLI_EVENT_CONNECTION_START;
                                noti->error = WIFI_DIRECT_ERROR_NONE;
-                               snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        }
+                       g_snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
+                       goto send_notification;
+               }
+               break;
+       case WIFI_DIRECT_CMD_CANCEL_CONNECT:    // deprecated
+               {
+                       wfd_session_s *session = (wfd_session_s*) manager->session;
+                       res = _wfd_send_to_client(sock, (char*) &rsp, sizeof(rsp));
+                       if (res < 0) {
+                               WDS_LOGE("Failed to send response to client");
+                               _wfd_deregister_client(manager, req.client_id);
+                               __WDS_LOG_FUNC_EXIT__;
+                               return FALSE;
+                       }
+
+                       res = wfd_oem_cancel_connection(manager->oem_ops, NULL);
+                       if (res < 0)
+                               WDS_LOGE("Failed to cancel connection");
+
+                       res = wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
+                       if (res < 0)
+                               WDS_LOGE("Failed to destroy group");
+
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
+                       noti->event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
+                       noti->error = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                       if (session)
+                               g_snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(session->peer->dev_addr));
                        goto send_notification;
                }
                break;
        case WIFI_DIRECT_CMD_CANCEL_CONNECTION:
                {
-                       if (!manager->session || manager->state != WIFI_DIRECT_STATE_CONNECTING) {
+                       if (!manager->session && manager->state != WIFI_DIRECT_STATE_CONNECTING) {
                                WDS_LOGE("It's not CONNECTING state");
                                rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
                                break;
@@ -1003,10 +1240,10 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        if (res < 0)
                                WDS_LOGE("Failed to cancel connection");
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        noti->event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
                        noti->error = WIFI_DIRECT_ERROR_CONNECTION_CANCELED;
-                       snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
+                       g_snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        goto send_notification;
                }
                break;
@@ -1037,22 +1274,39 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        res = wfd_manager_reject_connection(manager, req.data.mac_addr);
                        if (res < 0) {
                                WDS_LOGE("Failed to reject connection");
-                               // TODO: check whether set state and break
+                               // TODO: check whether to set state and break
                        }
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        noti->event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
                        noti->error = WIFI_DIRECT_ERROR_CONNECTION_CANCELED;
-                       snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
+                       g_snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        goto send_notification;
                }
                break;
        case WIFI_DIRECT_CMD_DISCONNECT:        // group, session
                {
                        if (!manager->group || manager->state < WIFI_DIRECT_STATE_CONNECTED) {
-                               WDS_LOGE("It's not permitted with this state [%d]", manager->state);
-                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                               break;
+                               if (WIFI_DIRECT_STATE_DISCOVERING == manager->state) {
+                                       res = wfd_oem_stop_scan(manager->oem_ops);
+                                       if (res < 0) {
+                                               WDS_LOGE("Failed to stop scan");
+                                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                                               break;
+                                       }
+                                       WDS_LOGI("Succeeded to stop scan");
+                                       if (WFD_DEV_ROLE_GO == manager->local->dev_role) {
+                                               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+                                               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+                                       } else {
+                                               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+                                               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+                                       }
+                               } else {
+                                       WDS_LOGE("It's not permitted with this state [%d]", manager->state);
+                                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                                       break;
+                               }
                        }
 
                        res = _wfd_send_to_client(sock, (char*) &rsp, sizeof(rsp));
@@ -1063,19 +1317,36 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                return FALSE;
                        }
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        noti->event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
                        noti->error = wfd_manager_disconnect(manager, req.data.mac_addr);
-                       snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
+                       g_snprintf(noti->param1, MACSTR_LEN, MACSTR, MAC2STR(req.data.mac_addr));
                        goto send_notification;
                }
                break;
        case WIFI_DIRECT_CMD_DISCONNECT_ALL:
                {
                        if (!manager->group || manager->state < WIFI_DIRECT_STATE_CONNECTED) {
-                               WDS_LOGD("It's not connected state [%d]", manager->state);
-                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                               break;
+                               if (WIFI_DIRECT_STATE_DISCOVERING == manager->state) {
+                                       res = wfd_oem_stop_scan(manager->oem_ops);
+                                       if (res < 0) {
+                                               WDS_LOGE("Failed to stop scan");
+                                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                                               break;
+                                       }
+                                       WDS_LOGI("Succeeded to stop scan");
+                                       if (WFD_DEV_ROLE_GO == manager->local->dev_role) {
+                                               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+                                               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+                                       } else {
+                                               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+                                               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+                                       }
+                               } else {
+                                       WDS_LOGE("It's not permitted with this state [%d]", manager->state);
+                                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                                       break;
+                               }
                        }
 
                        res = _wfd_send_to_client(sock, (char*) &rsp, sizeof(rsp));
@@ -1086,7 +1357,7 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                return FALSE;
                        }
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        noti->event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
                        noti->error = wfd_manager_disconnect_all(manager);
                        goto send_notification;
@@ -1118,18 +1389,12 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        WDS_LOGD("extra_rsp length [%d], extra_rsp [%x]", rsp.data_length, extra_rsp);
                }
                break;
-       case WIFI_DIRECT_CMD_GET_IP_ADDR:       // group
-               res = wfd_local_get_ip_addr(rsp.param2);
-               if (res < 0) {
-                       WDS_LOGE("Failed to get local IP address");
-                       rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
-               }
-               break;
        case WIFI_DIRECT_CMD_CREATE_GROUP:      // group
                {
+                       int persistent = 0;
                        wfd_group_s *group = manager->group;
                        if (group || manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
-                               WDS_LOGE("Group already exist");
+                               WDS_LOGE("Group already exist or not a proper state");
                                rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
                                break;
                        }
@@ -1144,12 +1409,16 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        manager->group = group;
                        WDS_LOGD("Succeeded to create pending group");
 
-                       res = wfd_oem_create_group(manager->oem_ops, 0, 0);
+                       persistent = (manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT);
+
+                       res = wfd_oem_create_group(manager->oem_ops, persistent, 0, manager->local->passphrase);
                        if (res < 0) {
                                WDS_LOGE("Failed to create group");
                                wfd_destroy_group(manager, GROUP_IFNAME);
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                        }
+
+                       memset(manager->local->passphrase, 0x0, PASSPHRASE_LEN);
                }
                break;
        case WIFI_DIRECT_CMD_DESTROY_GROUP:
@@ -1175,7 +1444,7 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
                        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
 
-                       noti = (wifi_direct_client_noti_s*) calloc(1, sizeof(wifi_direct_client_noti_s));
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
                        noti->event = WIFI_DIRECT_CLI_EVENT_GROUP_DESTROY_RSP;
                        noti->error = WIFI_DIRECT_ERROR_NONE;
                }
@@ -1231,7 +1500,7 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        int persistent_group_count = 0;
                        wfd_persistent_group_info_s *plist;
 
-                       res = wfd_oem_get_persistent_groups(manager->oem_ops, &plist, &persistent_group_count);
+                       res = wfd_oem_get_persistent_groups(manager->oem_ops, (wfd_oem_persistent_group_s**) &plist, &persistent_group_count);
                        if (res < 0) {
                                WDS_LOGE("Error!! wfd_oem_get_persistent_group_info() failed..");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
@@ -1246,29 +1515,13 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                }
                break;
        case WIFI_DIRECT_CMD_ACTIVATE_PERSISTENT_GROUP:
-               if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
-                       WDS_LOGE("Wi-Fi Direct is not activated.");
-                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                       break;
-               }
-
-               res = wfd_oem_set_persistent_reconnect(manager->oem_ops, NULL, TRUE);
-               if (res < 0) {
-                       WDS_LOGE("Failed to activate persistent group");
-                       rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               {
+                       manager->local->group_flags |= WFD_GROUP_FLAG_PERSISTENT;
                }
                break;
        case WIFI_DIRECT_CMD_DEACTIVATE_PERSISTENT_GROUP:
-               if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
-                       WDS_LOGE("Wi-Fi Direct is not activated.");
-                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                       break;
-               }
-
-               res = wfd_oem_set_persistent_reconnect(manager->oem_ops, NULL, FALSE);
-               if (res < 0) {
-                       WDS_LOGE("Failed to activate persistent group");
-                       rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               {
+                       manager->local->group_flags &= ~(WFD_GROUP_FLAG_PERSISTENT);
                }
                break;
        case WIFI_DIRECT_CMD_REMOVE_PERSISTENT_GROUP:   // group
@@ -1292,6 +1545,7 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                return TRUE;
                        }
                        WDS_LOGD("Remove persistent group [%s]", persistent_group.ssid);
+                       WDS_LOGD("Remove persistent group [" MACSTR "]", MAC2STR(persistent_group.go_mac_address));
 
                        res = wfd_oem_remove_persistent_group(manager->oem_ops,
                                                                        persistent_group.ssid, persistent_group.go_mac_address);
@@ -1327,17 +1581,30 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        }
                }
                break;
-       case WIFI_DIRECT_CMD_GET_DEVICE_MAC:    // manager (sync)
-               {
-                       unsigned char mac[MACADDR_LEN] = {0, };
-                       res = wfd_local_get_dev_mac(mac);
-                       if (res < 0) {
-                               WDS_LOGE("Failed to get device mac");
-                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
-                               break;
-                       }
-                       memcpy(rsp.param2, mac, sizeof(mac));
+       case WIFI_DIRECT_CMD_GET_MAC_ADDR:      // manager (sync)
+
+               res = wfd_local_get_dev_mac(rsp.param2);
+               if (res < 0) {
+                       WDS_LOGE("Failed to get device mac");
+                       rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                       break;
+               }
+               break;
+       case WIFI_DIRECT_CMD_GET_IP_ADDR:       // group
+               if (manager->state < WIFI_DIRECT_STATE_CONNECTED) {
+                       WDS_LOGE("Device is not connected yet");
+                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       break;
                }
+
+               unsigned char ip_addr[IPADDR_LEN] = {0,};
+
+               res = wfd_util_get_local_ip(ip_addr);
+               if (res < 0) {
+                       WDS_LOGE("Failed to get local IP address");
+                       rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+               }
+               g_snprintf(rsp.param2, IPSTR_LEN, IPSTR, IP2STR(ip_addr));
                break;
        case WIFI_DIRECT_CMD_GET_GO_INTENT:     // manager (sync)
                res = wfd_manager_get_go_intent(&rsp.param1);
@@ -1429,26 +1696,10 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                        rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                }
                break;
-       case WIFI_DIRECT_CMD_GET_PASSPHRASE:
-               {
-                       wfd_group_s *group = manager->group;
-                       if (!group) {
-                               WDS_LOGE("Group not exist");
-                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                               break;
-                       }
-                       if (group->role == WFD_DEV_ROLE_GC) {
-                               WDS_LOGE("Device is not GO");
-                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                               break;
-                       }
-                       snprintf(rsp.param2, PASSPHRASE_LEN, "%s", group->pass);
-               }
-               break;
        case WIFI_DIRECT_CMD_GET_WPS_PIN:       // session
                {
                        wfd_session_s *session = (wfd_session_s*) manager->session;
-                       if (!session) {
+                       if (!session || manager->auto_pin[0] != 0) {
                                WDS_LOGE("Session not exist");
                                rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
                                break;
@@ -1459,21 +1710,20 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                                break;
                        }
-                       snprintf(rsp.param2, sizeof(rsp.param2), "%s", session->wps_pin);
+                       g_snprintf(rsp.param2, sizeof(rsp.param2), "%s", session->wps_pin);
                }
                break;
        case WIFI_DIRECT_CMD_SET_WPS_PIN:       // session
                {
-                       char pin[PINSTR_LEN+1] = {0, };
+                       char *pin = NULL;
                        wfd_session_s *session = (wfd_session_s*) manager->session;
                        if (!session) {
                                WDS_LOGE("Session not exist");
-                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
-                               _wfd_read_from_client(sock, pin, PINSTR_LEN);
-                               break;
+                               pin = manager->auto_pin;
+                       } else {
+                               pin = session->wps_pin;
                        }
-
-                       res = _wfd_read_from_client(sock, session->wps_pin, PINSTR_LEN);
+                       res = _wfd_read_from_client(sock, pin, PINSTR_LEN);
                        if (res == -2) {
                                WDS_LOGE("Client socket Hanged up");
                                _wfd_deregister_client(manager, sock);
@@ -1482,180 +1732,412 @@ static gboolean wfd_client_process_request(GIOChannel *source,
                                WDS_LOGE("Failed to read socket [%d]", sock);
                                return TRUE;
                        }
-                       session->wps_pin[PINSTR_LEN] = '\0';
-                       WDS_LOGD("PIN string [%s]", session->wps_pin);
+                       pin[PINSTR_LEN] = '\0';
+                       WDS_LOGD("PIN string [%s]", pin);
                }
                break;
        case WIFI_DIRECT_CMD_GENERATE_WPS_PIN:  // manager
                // TODO: implement in plugin
                break;
-       case WIFI_DIRECT_CMD_SERVICE_ADD:
-               {
-                       char *buff = NULL;
 
-                       buff = (char *)calloc(sizeof(char), req.cmd_data_len);
-                       res = _wfd_read_from_client(sock, buff, req.cmd_data_len);
-                       if (res < 0) {
-                               WDS_LOGE("Failed to get service data");
+
+       case WIFI_DIRECT_CMD_GET_PEER_INFO:
+               {
+                       wfd_discovery_entry_s *peer = NULL;
+                       int res = 0;
+                       res = wfd_manager_get_peer_info(manager,req.data.mac_addr, &peer);
+                       if (res < 0 || !peer) {
+                               WDS_LOGE("Failed to get peer info");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
-                               free(buff);
+                               if(peer)
+                                       free(peer);
                                break;
                        }
+                       rsp.result = WIFI_DIRECT_ERROR_NONE;
 
-                       res = wfd_manager_service_add(manager, req.data.int1, buff);
-                       if (res < 0) {
-                               WDS_LOGE("Failed to add service");
-                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                       rsp.data_length = sizeof(wfd_discovery_entry_s);
+                       extra_rsp = (char*) peer;
+                       WDS_LOGD("extra_rsp length [%d], extra_rsp [%x]", rsp.data_length, extra_rsp);
+               }
+               break;
+       case WIFI_DIRECT_CMD_SET_PASSPHRASE:
+               {
+                       char passphrase[PASSPHRASE_LEN + 1] = {0,};
+                       wfd_group_s *group = manager->group;
+                       if (group) {
+                               WDS_LOGE("Group already exists");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               _wfd_read_from_client(sock, passphrase, PASSPHRASE_LEN);
+                               break;
                        }
 
-                       free(buff);
+                       res = _wfd_read_from_client(sock, manager->local->passphrase, PASSPHRASE_LEN);
+                       if (res == -2) {
+                               WDS_LOGE("Client socket Hanged up");
+                               _wfd_deregister_client(manager, sock);
+                               return FALSE;
+                       } else if (res == -1) {
+                               WDS_LOGE("Failed to read socket [%d]", sock);
+                               return TRUE;
+                       }
+                       manager->local->passphrase[PASSPHRASE_LEN] = '\0';
+                       WDS_LOGD("Passphrase string [%s]", manager->local->passphrase);
+               }
+               break;
+       case WIFI_DIRECT_CMD_GET_PASSPHRASE:
+               {
+                       wfd_group_s *group = manager->group;
+                       if (!group) {
+                               WDS_LOGE("Group not exist");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+                       if (group->role == WFD_DEV_ROLE_GC) {
+                               WDS_LOGE("Device is not GO");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+                       g_strlcpy(rsp.param2, group->passphrase, PASSPHRASE_LEN + 1);
+                       WDS_LOGD("group->pass : [%s]", group->passphrase);
                }
                break;
-       case WIFI_DIRECT_CMD_SERVICE_DEL:
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       case WIFI_DIRECT_CMD_REGISTER_SERVICE:
                {
-                       char *buff = NULL;
+                       int service_type = req.data.int1;
+                       char *info_str = NULL;
 
-                       buff = (char *)calloc(sizeof(char),req.cmd_data_len);
-                       res = _wfd_read_from_client(sock, buff, req.cmd_data_len);
+                       info_str = (char*) g_try_malloc0(req.cmd_data_len);
+                       if (!info_str) {
+                               WDS_LOGE("Failed to allocate memory for info string");
+                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                               break;
+                       }
+
+                       res = _wfd_read_from_client(sock, info_str, req.cmd_data_len);
                        if (res < 0) {
-                               WDS_LOGE("Failed to get service data");
+                               WDS_LOGE("Failed to read from socket");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
-                               free(buff);
+                               g_free(info_str);
                                break;
                        }
+                       info_str[req.cmd_data_len] = '\0';
+                       WDS_LOGD("Register service [%d: %s]", service_type, info_str);
 
-                       res = wfd_manager_service_del(manager, req.data.int1, buff);
+                       if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                               WDS_LOGE("Wi-Fi Direct is not activated.");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               g_free(info_str);
+                               break;
+                       }
+
+                       res = wfd_service_add(&(manager->local->services), service_type, info_str, &rsp.param1);
                        if (res < 0) {
-                               WDS_LOGE("Failed to delete service");
+                               WDS_LOGE("Failed to add service");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                        }
 
-                       free(buff);
+                       g_free(info_str);
                }
                break;
-       case WIFI_DIRECT_CMD_SERV_DISC_REQ:
+
+       case WIFI_DIRECT_CMD_DEREGISTER_SERVICE:
                {
-                       char *buff = NULL;
-
-                       if(req.cmd_data_len != 0)
-                       {
-                               buff = (char*)calloc(sizeof(char),req.cmd_data_len);
-                               res = _wfd_read_from_client(sock, buff, req.cmd_data_len);
-                               if (res < 0) {
-                                       WDS_LOGE("Failed to get service data");
-                                       rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
-                                       free(buff);
-                                       break;
-                               }
+                       int service_id = req.data.int1;
+
+                       if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                               WDS_LOGE("Wi-Fi Direct is not activated.");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
                        }
 
-                       res = wfd_manager_serv_disc_req(manager,req.data.mac_addr, req.data.int1, buff);
+                       res = wfd_service_del(manager->local->services, service_id);
                        if (res < 0) {
-                               WDS_LOGE("Failed to requset service discovery");
+                               WDS_LOGE("Failed to delete service");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                        }
-                       rsp.param1 = res;
-
-                       if(buff != NULL)
-                               free(buff);
                }
                break;
-       case WIFI_DIRECT_CMD_SERV_DISC_CANCEL:
+
+       case WIFI_DIRECT_CMD_START_SERVICE_DISCOVERY:
                {
-                       res = wfd_manager_serv_disc_cancel(manager, req.data.int1);
+                       if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                               WDS_LOGE("Wi-Fi Direct is not activated.");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+
+                       int service_type = req.data.int1;
+                       WDS_LOGD("Service type [%d]", service_type);
+
+                       res = wfd_oem_start_service_discovery(manager->oem_ops, req.data.mac_addr, service_type);
                        if (res < 0) {
-                               WDS_LOGE("Failed to delete service cancel");
+                               WDS_LOGE("Failed to start service discovery");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                        }
+
+                       noti = (wifi_direct_client_noti_s*) g_try_malloc0(sizeof(wifi_direct_client_noti_s));
+                       noti->event = WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_STARTED;
+                       noti->error = WIFI_DIRECT_ERROR_NONE;
                }
                break;
-       case WIFI_DIRECT_CMD_INIT_WIFI_DISPLAY:
+
+       case WIFI_DIRECT_CMD_CANCEL_SERVICE_DISCOVERY:
                {
-                       int hdcp;
+                       int service_type;
 
-                       res = _wfd_read_from_client(sock, (char *)&hdcp, req.cmd_data_len);
-                       if (res < 0) {
-                               WDS_LOGE("Failed to get hdcp data");
-                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                       if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                               WDS_LOGE("Wi-Fi Direct is not activated.");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
                                break;
                        }
-                       res = wfd_manager_init_wifi_display(req.data.int1, req.data.int2, hdcp);
+
+                       service_type = req.data.int1;
+                       WDS_LOGD("Service type [%d]", service_type);
+
+                       res = wfd_oem_cancel_service_discovery(manager->oem_ops, req.data.mac_addr, service_type);
                        if (res < 0) {
-                               WDS_LOGE("Failed to initialize wifi display");
+                               WDS_LOGE("Failed to cancel service discovery");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                        }
                }
                break;
-       case WIFI_DIRECT_CMD_DEINIT_WIFI_DISPLAY:
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       case WIFI_DIRECT_CMD_INIT_MIRACAST:
                {
-                       res = wfd_manager_deinit_wifi_display();
+                       if (manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                               WDS_LOGE("Wi-Fi Direct is not activated.");
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+
+                       int miracast_enable = req.data.int1;
+                       WDS_LOGD("Miracast enable [%d]", miracast_enable);
+
+                       res = wfd_oem_miracast_init(manager->oem_ops, miracast_enable);
                        if (res < 0) {
-                               WDS_LOGE("Failed to deinitialize wifi display");
+                               WDS_LOGE("Failed to initialize miracast");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+
+                       } else {
+
+                               if(miracast_enable) {
+                                       manager->local->display.type = WIFI_DISPLAY_DEFAULT_TYPE;
+                                       manager->local->display.port = WIFI_DISPLAY_DEFAULT_PORT;
+                                       manager->local->display.availablity = WIFI_DISPLAY_DEFAULT_AVAIL;
+                                       manager->local->display.hdcp_support = WIFI_DISPLAY_DEFAULT_HDCP;
+                                       manager->local->display.max_tput = WIFI_DISPLAY_DEFAULT_TPUT;
+                               } else {
+                                       memset(&(manager->local->display), 0x0, sizeof(wfd_display_type_e));
+                               }
+#if 0
+                               int screen_mirroring_status;
+                               if (vconf_get_int(VCONFKEY_SCREEN_MIRRORING_STATE, &screen_mirroring_status) < 0)
+                                       WDS_LOGE("Failed to get vconf VCONFKEY_SCREEN_MIRRORING_STATE\n");
+                               WDS_LOGD("screen_mirroring_status: %d\n", screen_mirroring_status);
+
+                               if (miracast_enable == TRUE) {
+
+                                       /* set go intent 14 so that can be Group Owner. value 15 can cause connection fail when nego with peer has 15 go intent value.  */
+                                       res = wfd_manager_set_go_intent(14);
+                                       if (res < 0)
+                                               WDS_LOGE("Failed to set GO intent");
+
+                                       /* set vconf of Screen Mirroring state. This is necessary to avoid 5 min. auto-deactivation in case of applications using Screen Mirroring. */
+                                       if(screen_mirroring_status < VCONFKEY_SCREEN_MIRRORING_ACTIVATED)
+                                       {
+                                               if (vconf_set_int(VCONFKEY_SCREEN_MIRRORING_STATE, VCONFKEY_SCREEN_MIRRORING_ACTIVATED) < 0)
+                                                       WDS_LOGE("Failed to get vconf VCONFKEY_SCREEN_MIRRORING_STATE\n");
+                                       }
+
+                               } else {
+
+                                       /* set go intent to default value */
+                                       res = wfd_manager_set_go_intent(7);
+                                       if (res < 0)
+                                               WDS_LOGE("Failed to set GO intent");
+
+                                       /* set vconf of Screen Mirroring state. This is necessary in case of applications using Screen Mirroring. */
+                                       if(screen_mirroring_status < VCONFKEY_SCREEN_MIRRORING_CONNECTED)
+                                       {
+                                               if (vconf_set_int(VCONFKEY_SCREEN_MIRRORING_STATE, VCONFKEY_SCREEN_MIRRORING_DEACTIVATED) < 0)
+                                                       WDS_LOGE("Failed to get vconf VCONFKEY_SCREEN_MIRRORING_STATE\n");
+                                       }
+                               }
+#endif
                        }
                }
                break;
-       case WIFI_DIRECT_CMD_GET_DISPLAY_PORT:
+       case WIFI_DIRECT_CMD_INIT_DISPLAY:
                {
-                       res = wfd_local_get_display_port(&rsp.param1);
+                       if(manager->state < WIFI_DIRECT_STATE_ACTIVATED || manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+
+                       wfd_device_s * device = manager->local;
+
+                       res = wfd_oem_miracast_init(manager->oem_ops, true);
                        if (res < 0) {
-                               WDS_LOGE("Failed to get local wifi display port");
+                               WDS_LOGE("Failed to initialize display");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                       } else {
+                               device->display.type = WIFI_DISPLAY_DEFAULT_TYPE;
+                               device->display.port = WIFI_DISPLAY_DEFAULT_PORT;
+                               device->display.availablity = WIFI_DISPLAY_DEFAULT_AVAIL;
+                               device->display.hdcp_support = WIFI_DISPLAY_DEFAULT_HDCP;
+                               device->display.max_tput = WIFI_DISPLAY_DEFAULT_TPUT;
                        }
                }
                break;
-       case WIFI_DIRECT_CMD_GET_DISPLAY_TYPE:
+       case WIFI_DIRECT_CMD_DEINIT_DISPLAY:
                {
-                       res = wfd_local_get_display_type((wifi_direct_display_type_e *)&rsp.param1);
+                       if(manager->state < WIFI_DIRECT_STATE_ACTIVATED || manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+
+                       wfd_device_s * device = manager->local;
+
+                       res = wfd_oem_miracast_init(manager->oem_ops, false);
                        if (res < 0) {
-                               WDS_LOGE("Failed to get local wifi display type");
+                               WDS_LOGE("Failed to deinitialize display");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+
                        }
+                       memset(&(device->display), 0x0, sizeof(wfd_display_type_e));
                }
                break;
-       case WIFI_DIRECT_CMD_GET_ACCESS_LIST:
+       case WIFI_DIRECT_CMD_SET_DISPLAY:
                {
-                       wfd_access_list_info_s *devices = NULL;
-                       int device_cnt = 0;
-                       device_cnt = wfd_manager_get_access_list(manager, &devices);
-                       WDS_LOGD("device in access list count [%d], access list [%x]", device_cnt, devices);
-                       if (device_cnt < 0) {
-                               WDS_LOGE("Failed to get access list");
-                               rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                       if(manager->state < WIFI_DIRECT_STATE_ACTIVATED || manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
                                break;
                        }
-                       rsp.param1 = device_cnt;
-                       rsp.result = WIFI_DIRECT_ERROR_NONE;
 
-                       rsp.data_length = device_cnt * sizeof(wfd_access_list_info_s);
-                       extra_rsp = (char*) devices;
-                       WDS_LOGD("extra_rsp length [%d], extra_rsp [%x]", rsp.data_length, extra_rsp);
-               }
-               break;
-       case WIFI_DIRECT_CMD_ADD_TO_ACCESS_LIST:
-               {
-                       wfd_device_s *peer = NULL;
-                       peer = wfd_peer_find_by_addr(manager, req.data.mac_addr);
-                       if(peer)
-                               res = wfd_manager_add_to_access_list(manager, peer, req.data.int1);
-                       else
-                               res = -1;
+                       int type = req.data.int1;       // type
+                       int port = req.data.int2;       // port
+                       int hdcp = req.data.int3;       // hdcp
 
+                       res = wfd_manager_set_display_device(type, port, hdcp);
                        if (res < 0) {
-                               WDS_LOGE("Failed to add device to list");
+                               WDS_LOGE("Failed to set display device settings");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
                        }
                }
                break;
-       case WIFI_DIRECT_CMD_DEL_FROM_ACCESS_LIST:
+       case WIFI_DIRECT_CMD_SET_DISPLAY_AVAILABILITY:
                {
-                       res = wfd_manager_del_from_access_list(manager, req.data.mac_addr);
+                       if(manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                               rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                               break;
+                       }
+                       res = wfd_manager_set_session_availability(req.data.int1);
                        if (res < 0) {
-                               WDS_LOGE("Failed to delete device from list");
+                               WDS_LOGE("Failed to set session availability");
                                rsp.result = WIFI_DIRECT_ERROR_OPERATION_FAILED;
+                               break;
                        }
                }
                break;
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_TYPE:
+       {
+               if(manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       break;
+               }
+
+               wfd_device_s *peer = NULL;
+
+               peer = wfd_manager_get_peer_by_addr(manager, req.data.mac_addr);
+               if(peer) {
+                       rsp.param1 = peer->display.type;
+               } else {
+                       WDS_LOGE("Failed to get peer");
+                       rsp.result = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                       break;
+               }
+       }
+       break;
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_AVAILABILITY:
+       {
+               if(manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       break;
+               }
+
+               wfd_device_s *peer = NULL;
+
+               peer = wfd_manager_get_peer_by_addr(manager, req.data.mac_addr);
+               if(peer) {
+                       rsp.param1 = peer->display.availablity;
+               } else {
+                       WDS_LOGE("Failed to get peer");
+                       rsp.result = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                       break;
+               }
+       }
+       break;
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_HDCP:
+       {
+               if(manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       break;
+               }
+
+               wfd_device_s *peer = NULL;
+
+               peer = wfd_manager_get_peer_by_addr(manager, req.data.mac_addr);
+               if(peer) {
+                       rsp.param1 = peer->display.hdcp_support;
+               } else {
+                       WDS_LOGE("Failed to get peer");
+                       rsp.result = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                       break;
+               }
+       }
+       break;
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_PORT:
+       {
+               if(manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       break;
+               }
+
+               wfd_device_s *peer = NULL;
+
+               peer = wfd_manager_get_peer_by_addr(manager, req.data.mac_addr);
+               if(peer) {
+                       rsp.param1 = peer->display.port;
+               } else {
+                       WDS_LOGE("Failed to get peer");
+                       rsp.result = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                       break;
+               }
+       }
+       break;
+       case WIFI_DIRECT_CMD_GET_PEER_DISPLAY_THROUGHPUT:
+       {
+               if(manager->state < WIFI_DIRECT_STATE_ACTIVATED) {
+                       rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       break;
+               }
+
+               wfd_device_s *peer = NULL;
+
+               peer = wfd_manager_get_peer_by_addr(manager, req.data.mac_addr);
+               if(peer) {
+                       rsp.param1 = peer->display.max_tput;
+               } else {
+                       WDS_LOGE("Failed to get peer");
+                       rsp.result = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                       break;
+               }
+       }
+       break;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
        default:
                WDS_LOGE("Unknown command[%d]", req.cmd);
                rsp.result = WIFI_DIRECT_ERROR_NOT_PERMITTED;
@@ -1666,8 +2148,8 @@ send_response:
        res = _wfd_send_to_client(sock, (char*) &rsp, sizeof(rsp));
        if (res < 0) {
                WDS_LOGE("Failed to send response to client");
-               if (noti)
-                       free(noti);
+               g_free(extra_rsp);
+               g_free(noti);
                _wfd_deregister_client(manager, req.client_id);
                __WDS_LOG_FUNC_EXIT__;
                return FALSE;
@@ -1677,15 +2159,14 @@ send_response:
                res = _wfd_send_to_client(sock, (char*) extra_rsp, rsp.data_length);
                if (res < 0) {
                        WDS_LOGE("Failed to send extra response data to client");
-                       free(extra_rsp);
-                       if (noti)
-                               free(noti);
+                       g_free(extra_rsp);
+                       g_free(noti);
                        _wfd_deregister_client(manager, req.client_id);
                        __WDS_LOG_FUNC_EXIT__;
                        return FALSE;
                }
-               if (extra_rsp)
-                       free(extra_rsp);
+               g_free(extra_rsp);
+               extra_rsp = NULL;
        }
 
 send_notification:
@@ -1693,16 +2174,17 @@ send_notification:
                res = wfd_client_send_event(manager, noti);
                if (res < 0) {
                        WDS_LOGE("Failed to send Notification to client");
-                       free(noti);
+                       g_free(extra_rsp);
+                       g_free(noti);
                        __WDS_LOG_FUNC_EXIT__;
                        return FALSE;
                }
                WDS_LOGD("Succeeded to send Notification[%d] to client", noti->event);
-               free(noti);
+               g_free(noti);
        }
 
 done:
-
+       g_free(extra_rsp);
        __WDS_LOG_FUNC_EXIT__;
        return TRUE;
 }
index 28a4228..abbc253 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <poll.h>
-#include <time.h>
 #include <unistd.h>
+#include <time.h>
 #include <errno.h>
 
 #include <glib.h>
 
-#include <wifi-direct-internal.h>
+#include <wifi-direct.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-oem.h"
 #include "wifi-direct-peer.h"
 #include "wifi-direct-util.h"
 
 
-static int _wfd_event_check_socket(int sock)
-{
-       struct pollfd p_fd;
-       int res = 0;
-
-       p_fd.fd = sock;
-       p_fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL;
-       res = poll((struct pollfd *) &p_fd, 1, 1);
-
-       if (res < 0) {
-               WDS_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
-               return -1;
-       } else if (res == 0) {
-               WDS_LOGD( "poll timeout. socket is busy\n");
-               return 1;
-       } else {
-
-               if (p_fd.revents & POLLERR) {
-                       WDS_LOGE("Error! POLLERR from socket[%d]", sock);
-                       return -1;
-               } else if (p_fd.revents & POLLHUP) {
-                       WDS_LOGE("Error! POLLHUP from socket[%d]", sock);
-                       return -1;
-               } else if (p_fd.revents & POLLNVAL) {
-                       WDS_LOGE("Error! POLLNVAL from socket[%d]", sock);
-                       return -1;
-               } else if (p_fd.revents & POLLIN) {
-                       WDS_LOGD("POLLIN from socket [%d]", sock);
-                       return 0;
-               } else if (p_fd.revents & POLLOUT) {
-                       WDS_LOGD("POLLOUT from socket [%d]", sock);
-                       return 0;
-               }
-       }
-
-       WDS_LOGD("Unknown poll event [%d]", p_fd.revents);
-       return -1;
-}
-
-static int _wfd_event_send_to_client(int sock, char *data, int data_len)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       int wbytes = 0;
-       int left_len = data_len;
-       char *ptr = data;
-       int res = 0;
-
-       if (sock < SOCK_FD_MIN || !data || data_len < 0) {
-               WDS_LOGE("Invalid parameter");
-               __WDS_LOG_FUNC_EXIT__;
-               return -1;
-       }
-
-       res = _wfd_event_check_socket(sock);
-       if (res < 0) {
-               WDS_LOGE("Socket error");
-               return -1;
-       } else if (res > 0) {
-               WDS_LOGE("Socket is busy");
-               return -2;
-       }
-
-       errno = 0;
-       while (left_len) {
-               wbytes = write(sock, ptr, left_len);
-               if (wbytes <= 0) {
-                       WDS_LOGE("Failed to write data into socket[%d]. [%s]", sock, strerror(errno));
-                       break;
-               }else if (wbytes < left_len) {
-                       WDS_LOGD("%d bytes left. Continue sending...", left_len - wbytes);
-                       left_len -= wbytes;
-                       ptr += wbytes;
-               } else if (wbytes == left_len) {
-                       WDS_LOGD("Succeeded to write data[%d bytes] into socket [%d]", wbytes, sock);
-                       left_len = 0;
-               } else {
-                       WDS_LOGE("Unknown error occurred. [%s]", strerror(errno));
-                       break;
-               }
-       }
-
-       __WDS_LOG_FUNC_EXIT__;
-       if (left_len)
-               return -1;
-       else
-               return 0;
-}
-
 static int _wfd_event_update_peer(wfd_manager_s *manager, wfd_oem_dev_data_s *data)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -154,226 +67,64 @@ static int _wfd_event_update_peer(wfd_manager_s *manager, wfd_oem_dev_data_s *da
                }
        } else {
                if (strcmp(peer->dev_name, data->name)) {
-                       strncpy(peer->dev_name, data->name, DEV_NAME_LEN);
-                       peer->dev_name[DEV_NAME_LEN] = '\0';
-                       WDS_LOGD("Device name is changed [" MACSTR ": %s]", MAC2STR(peer->dev_addr), peer->dev_name);
+                       g_strlcpy(peer->dev_name, data->name, DEV_NAME_LEN + 1);
+                       WDS_LOGD("Device name is changed [" MACSECSTR ": %s]",
+                                       MAC2SECSTR(peer->dev_addr), peer->dev_name);
                }
        }
+#ifndef CTRL_IFACE_DBUS
        memcpy(peer->intf_addr, data->p2p_intf_addr, MACADDR_LEN);
+#endif /* CTRL_IFACE_DBUS */
        peer->pri_dev_type = data->pri_dev_type;
        peer->sec_dev_type = data->sec_dev_type;
        peer->config_methods = data->config_methods;
        peer->dev_flags = data->dev_flags;
        peer->group_flags = data->group_flags;
        peer->dev_role = data->dev_role;
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       memcpy(&(peer->display), &(data->display), sizeof(wfd_display_s));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
-       if(!peer->wifi_display)
-               peer->wifi_display = calloc(1, sizeof(wfd_display_info_s));
-       memcpy(peer->wifi_display, &data->wifi_display, sizeof(wfd_display_info_s));
-
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+       wfd_util_get_current_time(&peer->time);
+#else
        struct timeval tval;
        gettimeofday(&tval, NULL);
        peer->time = tval.tv_sec;
-
+#endif
        WDS_LOGI("Update time [%s - %ld]", peer->dev_name, peer->time);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
-static int hex2num(const char c)
-{
-       if (c >= '0' && c <= '9')
-               return c - '0';
-       if (c >= 'a' && c <= 'f')
-               return c - 'a' + 10;
-       if (c >= 'A' && c <= 'F')
-               return c - 'A' + 10;
-       return -1;
-}
-
-static int hex2byte(const char *hex)
-{
-       int a, b;
-       a = hex2num(*hex++);
-       if (a < 0)
-               return -1;
-       b = hex2num(*hex++);
-       if (b < 0)
-               return -1;
-       return (a << 4) | b;
-}
-
-int hexstr2bin(const char *hex, int len, char *buf)
-{
-       int i;
-       int a;
-       const char *ipos = hex;
-       char *opos = buf;
-
-       for (i = 0; i < len; i++) {
-               a = hex2byte(ipos);
-               if (a < 0)
-                       return -1;
-               *opos++ = a;
-               ipos += 2;
-       }
-       return 0;
-}
-
-static int _wfd_get_stlv_len(const char* value)
+ gboolean _wfd_connection_retry(gpointer *data)
 {
-       int a, b;
-       a = hex2byte(value +2);
-       b = hex2byte(value);
-
-       if( a >= 0 && b >= 0)
-               return ( a << 8) | b;
-       else
-               return -1;
-}
-
-static int _wfd_service_add(wfd_device_s *device, wifi_direct_service_type_e type, char *data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_service_s *service = NULL;
-       GList *temp = NULL;
-       int res = 0;
-
-       temp = g_list_first(device->services);
-       while (temp) {
-               service = temp->data;
-
-               if(type == service->service_type &&
-                               !strcmp(data, service->service_string))
-               {
-                       WDS_LOGD("Service found");
-                       break;
-               }
-               temp = g_list_next(temp);
-               service = NULL;
+       wfd_session_s *session = (wfd_session_s*) data;
+       if (!session) {
+               WDS_LOGE("Session is NULL");
+               return G_SOURCE_REMOVE;
        }
 
-       if (service) {
-               WDS_LOGE("service already exist");
-               free(data);
-               __WDS_LOG_FUNC_EXIT__;
-               return res;
-       }
-       service = (wfd_service_s*) calloc(1, sizeof(wfd_service_s));
-       service->service_string = data;
-       service->service_str_length = strlen(data);
-       service->service_type = type;
-       device->services = g_list_prepend(device->services, service);
-
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-static int _wfd_update_service(wfd_device_s *peer, char * data, wifi_direct_service_type_e  type, int length)
-{
-       wfd_service_s * service;
-       int res = 0;
-       char *temp = NULL;
-       char *ptr = NULL;
-
-       if (!peer || !data) {
-               WDS_LOGE("Invalid parameter");
-               return -1;
-       }
-       switch (type)
-       {
-               case WIFI_DIRECT_SERVICE_BONJOUR:
-               {
-                       temp = strndup(data, length*2);
-                       res = _wfd_service_add(peer, type, temp);
+       switch (session->state) {
+               case SESSION_STATE_STARTED:
+                       WDS_LOGD("PD again");
+                       wfd_session_start(session);
                        break;
-               }
-               case WIFI_DIRECT_SERVICE_UPNP:
-               {
-                       temp = calloc(1, length);
-                       hexstr2bin(data +2, length - 1, temp);
-                       temp[length - 1] = '\0';
-
-                       ptr = strtok(temp, ",");
-
-                       while(ptr != NULL)
-                       {
-                               res = _wfd_service_add(peer, type, strndup(ptr, strlen(ptr)));
-                               ptr = strtok(NULL, ",");
-                       }
-
-                       if(temp)
-                               free(temp);
+               case SESSION_STATE_GO_NEG:
+                       WDS_LOGD("Negotiation again");
+                       wfd_session_connect(session);
                        break;
-               }
-               case WIFI_DIRECT_SERVICE_VENDORSPEC:
-               {
-                       temp = calloc(1, length + 1);
-                       hexstr2bin(data, length, temp);
-                       temp[length] = '\0';
-
-                       res = _wfd_service_add(peer, type, temp);
+               case SESSION_STATE_WPS:
+                       WDS_LOGD("WPS again");
+                       wfd_session_wps(session);
                        break;
-               }
                default:
-               {
-                       res = -1;
+                       WDS_LOGE("Invalid session state [%d]", session->state);
                        break;
-               }
        }
-       return res;
-}
 
-static int _wfd_event_update_service(wfd_manager_s *manager, wfd_device_s *peer, char *data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       int res = 0;
-       int s_len = 0;
-       char *pos = data;
-       char *end = NULL;
-       wifi_direct_service_type_e  service_tlv_type;
-       int status = 0;
-
-       if (!peer || !data) {
-               WDS_LOGE("Invalid parameter");
-               return -1;
-       }
-       end = data + strlen(data);
-
-       while(pos <= end -10){// This is raw data that is not passed any exception handling ex> length, value, ...
-
-               s_len = _wfd_get_stlv_len(pos);
-               pos += 4;
-               if (pos + s_len*2 > end || s_len < 3) {
-                       WDS_LOGD("Unexpected Response Data or length: %d", s_len);
-                       break;
-               }
-
-               service_tlv_type = hex2byte(pos);
-               if (service_tlv_type < 0) {
-                       WDS_LOGD("Unexpected Response service type: %d", service_tlv_type);
-                       pos+=(s_len)*2;
-                       continue;
-               }else if (service_tlv_type == 255)
-                       service_tlv_type = WIFI_DIRECT_SERVICE_VENDORSPEC;
-
-               pos += 4;
-               status = hex2byte(pos);
-               pos += 2;
-
-               if (status == 0)
-               {
-                       res = _wfd_update_service(peer, pos, service_tlv_type, s_len -3);
-                       if (res != 0) {
-                               WDS_LOGE("Invalid type");
-                       }
-               } else
-                       WDS_LOGD("Service Reaponse TLV status is not vaild status: %d", status);
-               pos+=(s_len-3)*2;
-       }
-       __WDS_LOG_FUNC_EXIT__;
-       return 0;
+       return G_SOURCE_REMOVE;
 }
 
 int wfd_process_event(void *user_data, void *data)
@@ -388,15 +139,37 @@ int wfd_process_event(void *user_data, void *data)
                return -1;
        }
 
-       WDS_LOGD("Event[%d] from " MACSTR, event->event_id, MAC2STR(event->dev_addr));
+       WDS_LOGD("Event[%d] from " MACSECSTR, event->event_id, MAC2SECSTR(event->dev_addr));
 
        switch (event->event_id) {
        case WFD_OEM_EVENT_DEACTIVATED:
+       {
+               // TODO: notify app
+               wifi_direct_client_noti_s noti;
+               memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
+               noti.event = WIFI_DIRECT_CLI_EVENT_DEACTIVATION;
+               noti.error = WIFI_DIRECT_ERROR_NONE;
+               wfd_client_send_event(manager, &noti);
+
+               // TODO: remove group, session, all peers
+               wfd_destroy_group(manager, GROUP_IFNAME);
+               wfd_destroy_session(manager);
+               wfd_peer_clear_all(manager);
+               wfd_local_reset_data(manager);
+
+               wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
                manager->req_wps_mode = WFD_WPS_MODE_PBC;
-               break;
+       }
+       break;
        case WFD_OEM_EVENT_PEER_FOUND:
        {
                wfd_oem_dev_data_s *edata = (wfd_oem_dev_data_s*) event->edata;
+               if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
+                       WDS_LOGE("Invalid event data");
+                       break;
+               }
+
                res = _wfd_event_update_peer(manager, edata);
                if (res < 0) {
                        WDS_LOGE("Failed to update peer data");
@@ -408,6 +181,7 @@ int wfd_process_event(void *user_data, void *data)
                                manager->state != WIFI_DIRECT_STATE_DISCONNECTING) {
                        wifi_direct_client_noti_s noti;
                        memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
+                       snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(edata->p2p_dev_addr));
                        noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_FOUND_PEERS;
                        noti.error = WIFI_DIRECT_ERROR_NONE;
                        wfd_client_send_event(manager, &noti);
@@ -417,14 +191,19 @@ int wfd_process_event(void *user_data, void *data)
        case WFD_OEM_EVENT_PROV_DISC_REQ:
        case WFD_OEM_EVENT_PROV_DISC_RESP:
        {
-               wfd_group_s *group = (wfd_group_s*) manager->group;
-               if ((group && group->member_count >= manager->max_station) ||
-                               (wfd_manager_access_control(manager, event->dev_addr) == WFD_DEV_DENIED)) {
-                       WDS_LOGD("Provision discovery is not granted");
+               wfd_device_s *peer = NULL;
+#ifdef CTRL_IFACE_DBUS
+               wfd_oem_dev_data_s *edata = (wfd_oem_dev_data_s*) event->edata;
+               if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
+                       WDS_LOGE("Invalid event data");
                        break;
                }
 
-               wfd_device_s *peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
+               res = _wfd_event_update_peer(manager, edata);
+               peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
+               peer->state = WFD_PEER_STATE_CONNECTING;
+#else /* CTRL_IFACE_DBUS */
+               peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
                if (!peer) {
                        WDS_LOGD("Porv_disc from unknown peer. Add new peer");
                        peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
@@ -436,7 +215,7 @@ int wfd_process_event(void *user_data, void *data)
                        wfd_update_peer(manager, peer);
                }
                wfd_update_peer_time(manager, event->dev_addr);
-
+#endif /* CTRL_IFACE_DBUS */
                res = wfd_session_process_event(manager, event);
                if (res < 0) {
                        WDS_LOGE("Failed to process event of session");
@@ -462,6 +241,11 @@ int wfd_process_event(void *user_data, void *data)
                        break;
                }
 
+               if (manager->scan_mode == WFD_SCAN_MODE_PASSIVE) {
+                       WDS_LOGE("During passive scan, Discover Finished event will not notified");
+                       break;
+               }
+
                if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
                        wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
                        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
@@ -480,12 +264,6 @@ int wfd_process_event(void *user_data, void *data)
        break;
        case WFD_OEM_EVENT_INVITATION_REQ:
        {
-               wfd_dev_connection_flag_e flag = 0;
-               flag = wfd_manager_access_control(manager, event->dev_addr);
-               if (flag == WFD_DEV_DENIED) {
-                       WDS_LOGD("Invitation request is not granted");
-                       break;
-               }
                wfd_device_s *peer = NULL;
                wfd_session_s *session = NULL;
                wfd_oem_invite_data_s *edata = (wfd_oem_invite_data_s*) event->edata;
@@ -513,29 +291,100 @@ int wfd_process_event(void *user_data, void *data)
                wfd_session_timer(session, 1);
 
                wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
-               if(flag == WFD_DEV_UNKNOWN)
-               {
-                       WDS_LOGD("device is not in access/deny list");
+
+               wifi_direct_client_noti_s noti;
+               memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
+               noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
+               noti.error = WIFI_DIRECT_ERROR_NONE;
+               snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
+               wfd_client_send_event(manager, &noti);
+       }
+       break;
+       case WFD_OEM_EVENT_GO_NEG_REQ:
+       {
+               wfd_session_s *session = (wfd_session_s*) manager->session;
+#ifdef CTRL_IFACE_DBUS
+               wfd_oem_dev_data_s *edata = (wfd_oem_dev_data_s*) event->edata;
+               if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
+                       WDS_LOGE("Invalid event data");
+                       break;
+               }
+
+               res = _wfd_event_update_peer(manager, edata);
+               if (res < 0) {
+                       WDS_LOGE("Failed to update peer data");
+                       break;
+               }
+#else /* CTRL_IFACE_DBUS */
+               wfd_device_s *peer = NULL;
+               wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
+
+               if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_CONN) {
+                       WDS_LOGE("Invalid connection event data");
+                       break;
+               }
+
+               peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
+               if (!peer) {
+                       WDS_LOGD("Invitation from unknown peer. Add new peer");
+                       peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
+                       if (!peer) {
+                               WDS_LOGE("Failed to add peer for invitation");
+                               break;
+                       }
+               }
+
+               if (edata->wps_mode == 0)
+                       edata->wps_mode = 1;
+#endif /* CTRL_IFACE_DBUS */
+               if (!session) {
+                       session = wfd_create_session(manager, event->dev_addr,
+#ifdef CTRL_IFACE_DBUS
+                                                       event->wps_mode, SESSION_DIRECTION_INCOMING);
+#else /* CTRL_IFACE_DBUS */
+                                                       edata->wps_mode, SESSION_DIRECTION_INCOMING);
+#endif /* CTRL_IFACE_DBUS */
+                       if (!session) {
+                               WDS_LOGE("Failed to create session");
+                               return -1;
+                       }
+                       session->type = SESSION_TYPE_NORMAL;
+                       session->state = SESSION_STATE_GO_NEG;
+                       wfd_session_timer(session, 1);
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
+
                        wifi_direct_client_noti_s noti;
                        memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
-                       noti.event = WIFI_DIRECT_CLI_EVENT_INVITATION_REQ;
+                       noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
                        noti.error = WIFI_DIRECT_ERROR_NONE;
-                       snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
+                       g_snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
                        wfd_client_send_event(manager, &noti);
-               }else {
-                       WDS_LOGD("device is allowed");
-                       wfd_session_start(session);
+               } else {
+                       wfd_session_process_event(manager, event);
                }
        }
        break;
-       case WFD_OEM_EVENT_GO_NEG_REQ:
+       case WFD_OEM_EVENT_GO_NEG_DONE:
+#ifdef CTRL_IFACE_DBUS
        {
-               if (wfd_manager_access_control(manager, event->dev_addr) == WFD_DEV_DENIED) {
-                       WDS_LOGD("GO negotiation is not granted");
+               wfd_session_s *session = (wfd_session_s*) manager->session;
+               wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
+               wfd_device_s *peer = NULL;
+
+               if (event == NULL || edata == NULL) {
+                       WDS_LOGE("Invalid event data");
                        break;
                }
+
+               if(session && session->peer) {
+                       peer = session->peer;
+                       memcpy(peer->intf_addr, edata->peer_intf_addr, MACADDR_LEN);
+               }
+               manager->local->dev_role = event->dev_role;
+               wfd_session_process_event(manager, event);
        }
-       case WFD_OEM_EVENT_GO_NEG_DONE:
+       break;
+#endif /* CTRL_IFACE_DBUS */
        case WFD_OEM_EVENT_WPS_DONE:
                wfd_session_process_event(manager, event);
        break;
@@ -548,21 +397,16 @@ int wfd_process_event(void *user_data, void *data)
                        break;
                }
 
-               if(wfd_manager_find_connected_peer(manager, event->intf_addr)) {
-                       WDS_LOGD("Ignore this event");
-                       break;
-               }
-
                wfd_session_s *session = (wfd_session_s*) manager->session;
                if (!session) {
-                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]",
-                                                                               MAC2STR(event->dev_addr));
+                       WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
+                                                                               MAC2SECSTR(event->dev_addr));
                        wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
                        wfd_destroy_group(manager, GROUP_IFNAME);
                        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
                        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
                        break;
-               } 
+               }
 
                wfd_device_s *peer = wfd_session_get_peer(session);
                if (!peer) {
@@ -582,20 +426,26 @@ int wfd_process_event(void *user_data, void *data)
                wfd_group_add_member(group, peer->dev_addr);
 
                session->state = SESSION_STATE_COMPLETED;
+#ifndef CTRL_IFACE_DBUS
                memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
+#endif /* CTRL_IFACE_DBUS */
                peer->state = WFD_PEER_STATE_CONNECTED;
 
                if (event->event_id == WFD_OEM_EVENT_STA_CONNECTED) {   // GO
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+
                        wifi_direct_client_noti_s noti;
                        memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
                        noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
                        noti.error = WIFI_DIRECT_ERROR_NONE;
                        snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
                        wfd_client_send_event(manager, &noti);
+#ifdef CTRL_IFACE_DBUS
+                       wfd_update_peer(manager, peer);
+#endif /* CTRL_IFACE_DBUS */
 
                        wfd_util_dhcps_wait_ip_leased(peer);
-                       wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
-                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
                        wfd_destroy_session(manager);
                }
        }
@@ -610,7 +460,16 @@ int wfd_process_event(void *user_data, void *data)
                wifi_direct_client_noti_s noti;
                memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
 
+               if (!group) {
+                       WDS_LOGE("Group not found");
+                       break;
+               }
+
+#ifdef CTRL_IFACE_DBUS
+               peer = wfd_group_find_member_by_addr(group, event->dev_addr);
+#else /* CTRL_IFACE_DBUS */
                peer = wfd_group_find_member_by_addr(group, event->intf_addr);
+#endif /* DBUS_IFACE */
                if (!peer) {
                        WDS_LOGE("Failed to find connected peer");
                        peer = wfd_session_get_peer(session);
@@ -629,7 +488,7 @@ int wfd_process_event(void *user_data, void *data)
                        else
                                noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_IND;
                        noti.error = WIFI_DIRECT_ERROR_NONE;
-                       snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+                       g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
                        /* If there is no member, GO should be destroyed */
                        if (!group->member_count) {
                                wfd_oem_destroy_group(manager->oem_ops, group->ifname);
@@ -638,14 +497,24 @@ int wfd_process_event(void *user_data, void *data)
                } else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
                        noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
                        noti.error = WIFI_DIRECT_ERROR_NONE;
-                       snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+                       g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
                } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
-                                       /* Some devices(GO) send disconnection message before connection completed.
-                                        * This message should be ignored when device is not GO */
-                                       manager->local->dev_role == WFD_DEV_ROLE_GO) {
-                       noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
-                       noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
-                       snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+                               /* Some devices(GO) send disconnection message before connection completed.
+                                * This message should be ignored when device is not GO */
+                               manager->local->dev_role == WFD_DEV_ROLE_GO) {
+                       if (WFD_PEER_STATE_CONNECTED == peer->state) {
+                               WDS_LOGD("Peer is already Connected !!!");
+                               noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
+                               noti.error = WIFI_DIRECT_ERROR_NONE;
+                       } else if (WFD_PEER_STATE_CONNECTING == peer->state) {
+                               WDS_LOGD("Peer is Connecting...");
+                               noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
+                               noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
+                       } else {
+                               WDS_LOGE("Unexpected Peer State. Ignore it");
+                               break;
+                       }
+                       g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
                } else {
                        WDS_LOGE("Unexpected event. Ignore it");
                        break;
@@ -665,8 +534,18 @@ int wfd_process_event(void *user_data, void *data)
        break;
        case WFD_OEM_EVENT_GROUP_CREATED:
        {
-               wfd_oem_group_data_s *edata = event->edata;
                wfd_group_s *group = (wfd_group_s*) manager->group;
+#ifdef CTRL_IFACE_DBUS
+               if(event->dev_role == WFD_DEV_ROLE_GC && !group) {
+
+                       group = wfd_create_pending_group(manager, event->intf_addr);
+                       if (!group) {
+                               WDS_LOGE("Failed to create pending group");
+                               break;
+                       }
+                       manager->group = group;
+               }
+#endif /* CTRL_IFACE_DBUS */
 
                if (!group) {
                        if (!manager->session) {
@@ -675,7 +554,7 @@ int wfd_process_event(void *user_data, void *data)
                                break;
                        }
 
-                       group = wfd_create_group(manager, event->ifname, event->dev_role, edata->go_dev_addr);
+                       group = wfd_create_group(manager, event);
                        if (!group) {
                                WDS_LOGE("Failed to create group");
                                break;
@@ -688,25 +567,19 @@ int wfd_process_event(void *user_data, void *data)
                        }
 
                        if (group->pending) {
-                               wfd_group_complete(manager, event->ifname, event->dev_role, edata->go_dev_addr);
+                               wfd_group_complete(manager, event);
                        } else {
                                WDS_LOGE("Unexpected event. Group already exist");
                                break;
                        }
                }
 
-               strncpy(group->ssid, edata->ssid, DEV_NAME_LEN);
-               group->ssid[DEV_NAME_LEN-1] = '\0';
-               strncpy(group->pass,edata->pass, PASSPHRASE_LEN);
-               group->pass[PASSPHRASE_LEN] = '\0';
-               group->freq = edata->freq;
-               manager->group = group;
-               manager->local->dev_role = event->dev_role;
-
                wifi_direct_client_noti_s noti;
                memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
                if (group->role == WFD_DEV_ROLE_GC) {
+#ifndef CTRL_IFACE_DBUS
                        wfd_destroy_session(manager);
+#endif /* CTRL_IFACE_DBUS */
                        wfd_peer_clear_all(manager);
                } else {
                        if (group->flags & WFD_GROUP_FLAG_AUTONOMOUS) {
@@ -729,7 +602,8 @@ int wfd_process_event(void *user_data, void *data)
                        noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
                        noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
                        unsigned char *peer_addr = wfd_session_get_peer_addr(manager->session);
-                       snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+                       if(peer_addr != NULL)
+                               g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
                } else if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
                        noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_DESTROY_RSP;
                        noti.error = WIFI_DIRECT_ERROR_NONE;
@@ -746,8 +620,52 @@ int wfd_process_event(void *user_data, void *data)
                manager->local->dev_role = WFD_DEV_ROLE_NONE;
        }
        break;
-       case WFD_OEM_EVENT_PROV_DISC_FAIL:
        case WFD_OEM_EVENT_GO_NEG_FAIL:
+       {
+               wfd_session_s *session = (wfd_session_s*) manager->session;
+               if (!session) {
+                       WDS_LOGE("Unexpected event. Session not exist");
+                       break;
+               }
+
+               unsigned char *peer_addr = wfd_session_get_peer_addr(session);
+               if (!peer_addr) {
+                       WDS_LOGE("Session do not has peer");
+                       break;
+               }
+
+               if (event->event_id == WFD_OEM_EVENT_GO_NEG_FAIL) {
+                       wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
+                       if (edata && edata->status < 0 && session->connecting_120) {
+                               if (session->retry_gsrc) {
+                                       g_source_remove(session->retry_gsrc);
+                                       session->retry_gsrc = 0;
+                               }
+                               session->retry_gsrc = g_idle_add((GSourceFunc) _wfd_connection_retry, session);
+                               WDS_LOGD("Connection will be retried");
+                               break;
+                       }
+               }
+
+               wifi_direct_client_noti_s noti;
+               memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
+               noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
+               noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
+               snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+               wfd_client_send_event(manager, &noti);
+
+               if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+               } else {
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+               }
+
+               wfd_destroy_session(manager);
+       }
+       break;
+       case WFD_OEM_EVENT_PROV_DISC_FAIL:
        case WFD_OEM_EVENT_WPS_FAIL:
        case WFD_OEM_EVENT_KEY_NEG_FAIL:
        {
@@ -763,6 +681,19 @@ int wfd_process_event(void *user_data, void *data)
                        break;
                }
 
+               if (event->event_id == WFD_OEM_EVENT_GO_NEG_FAIL) {
+                       wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
+                       if (edata && edata->status < 0 && session->connecting_120) {
+                               if (session->retry_gsrc) {
+                                       g_source_remove(session->retry_gsrc);
+                                       session->retry_gsrc = 0;
+                               }
+                               session->retry_gsrc = g_idle_add((GSourceFunc) _wfd_connection_retry, session);
+                               WDS_LOGD("Connection will be retried");
+                               break;
+                       }
+               }
+
                wifi_direct_client_noti_s noti;
                memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
                noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
@@ -780,6 +711,8 @@ int wfd_process_event(void *user_data, void *data)
 
                wfd_destroy_session(manager);
 
+               wfd_oem_refresh(manager->oem_ops);
+#if 0
                /* After connection failed, scan again */
                wfd_oem_scan_param_s param;
                memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
@@ -788,27 +721,77 @@ int wfd_process_event(void *user_data, void *data)
                param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
                wfd_oem_start_scan(manager->oem_ops, &param);
                manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
+#endif
        }
        break;
+
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
        case WFD_OEM_EVENT_SERV_DISC_RESP:
        {
-               wfd_device_s *peer = NULL;
-               if(event->edata_type != WFD_OEM_EDATA_TYPE_SERVICE)
-               {
-                       WDS_LOGD("There is no service to register");
-                       break;
-               }
-               peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
-               if (!peer) {
-                       WDS_LOGD("serv_disc_resp from unknown peer. Discard it");
-                       break;
-               }
-               res = _wfd_event_update_service(manager, peer, (char*) event->edata);
-               if (res < 0) {
-                       WDS_LOGE("Failed to update peer service data");
+               wifi_direct_client_noti_s noti;
+               wfd_update_peer_time(manager, event->dev_addr);
+
+               if (event->edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE) {
+                       wfd_oem_new_service_s *service = NULL;;
+                       GList *temp = NULL;
+                       GList *services = (GList*) event->edata;
+                       int count = 0;
+
+                       WDS_LOGD("%d service data found", event->dev_role);
+
+                       temp = g_list_first(services);
+                       while(temp && count < event->dev_role) {
+                               service = (wfd_oem_new_service_s*) temp->data;
+                               memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
+                               noti.event = WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FOUND;
+                               noti.type = service->protocol;
+                               if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
+                                       g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
+                                       g_snprintf(noti.param2, 256, "%s|%s", service->data.bonjour.query, service->data.bonjour.rdata);
+                                       WDS_LOGD("Found service: [%d: %s] - [" MACSECSTR "]", service->protocol,
+                                                               service->data.bonjour.query, MAC2SECSTR(event->dev_addr));
+                               } else if (service->protocol == WFD_OEM_SERVICE_TYPE_BT_ADDR) {
+                                       g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
+                                       g_snprintf(noti.param2, MACSTR_LEN, "%s", service->data.vendor.data2);
+                                       WDS_LOGD("Found service: [%d: %s] - [" MACSECSTR "]", service->protocol,
+                                                               service->data.vendor.data2, MAC2SECSTR(event->dev_addr));
+                               } else {
+                                       WDS_LOGD("Found service is not supported");
+                                       goto next;
+                               }
+                               wfd_client_send_event(manager, &noti);
+next:
+                               temp = g_list_next(temp);
+                               service = NULL;
+                               count++;
+                       }
+               } else if (event->edata_type == WFD_OEM_EDATA_TYPE_SERVICE) {
+                       wfd_oem_service_data_s *edata = (wfd_oem_service_data_s*) event->edata;
+
+                       memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
+                       noti.event = WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FOUND;
+                       if(!edata) {
+                               noti.type = -1;
+                       } else {
+                               noti.type = edata->type;
+                               g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
+                               switch(edata->type) {
+                                       case WFD_OEM_SERVICE_TYPE_BT_ADDR:
+                                               g_snprintf(noti.param2, MACSTR_LEN, MACSTR, MAC2STR(edata->data));
+                                               break;
+                                       case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
+                                               g_snprintf(noti.param2, MACSTR_LEN, "%s", edata->value);
+                                               break;
+                                       default:
+                                               WDS_LOGE("Unknown type [type ID: %d]", edata->type);
+                               }
+                       }
+                       wfd_client_send_event(manager, &noti);
                }
        }
        break;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
        default:
                WDS_LOGE("Unknown event [event ID: %d]", event->event_id);
        break;
index 1ac096b..ea92764 100644 (file)
 
 #include <glib.h>
 
-#include <wifi-direct-internal.h>
+#include <wifi-direct.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
+#include "wifi-direct-state.h"
 #include "wifi-direct-peer.h"
 #include "wifi-direct-oem.h"
 #include "wifi-direct-group.h"
 #include "wifi-direct-client.h"
 
 // Check the group instance which has same interface name, before using this function
-wfd_group_s *wfd_create_group(void *data, char *ifname, int role, unsigned char *go_dev_addr)
+wfd_group_s *wfd_create_group(void *data, wfd_oem_event_s *group_info)
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_group_s *group = NULL;
        wfd_manager_s *manager = (wfd_manager_s*) data;
+       wfd_oem_group_data_s *edata = (wfd_oem_group_data_s *)group_info->edata;
 
-       if (!manager || !ifname || !go_dev_addr) {
+       if (!manager || !group_info || !edata) {
                WDS_LOGE("Invalid parameter");
                __WDS_LOG_FUNC_EXIT__;
                return NULL;
@@ -69,12 +72,20 @@ wfd_group_s *wfd_create_group(void *data, char *ifname, int role, unsigned char
                return NULL;
        }
 
-       memcpy(group->ifname, ifname, IFACE_NAME_LEN);
+       memcpy(group->ifname, group_info->ifname, IFACE_NAME_LEN);
        group->ifname[IFACE_NAME_LEN] = '\0';
-       group->role = role;
-       memcpy(group->go_dev_addr, go_dev_addr, MACADDR_LEN);
+       group->role = group_info->dev_role;
+       memcpy(group->go_dev_addr, edata->go_dev_addr, MACADDR_LEN);
        group->pending = 0;
 
+       g_strlcpy(group->ssid, edata->ssid, DEV_NAME_LEN + 1);
+       g_strlcpy(group->passphrase, edata->pass, PASSPHRASE_LEN +1);
+       memset(manager->local->passphrase, 0x0, PASSPHRASE_LEN +1);
+       group->freq = edata->freq;
+
+       manager->group = group;
+       manager->local->dev_role = group_info->dev_role;
+
        wfd_util_dhcps_start();
        WDS_LOGD("Role is Group Owner. DHCP Server started");
 
@@ -103,7 +114,7 @@ wfd_group_s *wfd_create_pending_group(void *data, unsigned char * bssid)
        }
 
        errno = 0;
-       group = (wfd_group_s*) calloc(1, sizeof(wfd_group_s));
+       group = (wfd_group_s*) g_try_malloc0(sizeof(wfd_group_s));
        if (!group) {
                WDS_LOGE("Failed to allocate memory for group. [%s]", strerror(errno));
                __WDS_LOG_FUNC_EXIT__;
@@ -117,14 +128,16 @@ wfd_group_s *wfd_create_pending_group(void *data, unsigned char * bssid)
        return group;
 }
 
-int wfd_group_complete(void *data, char *ifname, int role, unsigned char *go_dev_addr)
+int wfd_group_complete(void *data, wfd_oem_event_s *group_info)
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_manager_s *manager = (wfd_manager_s*) data;
+       wfd_oem_group_data_s *edata = (wfd_oem_group_data_s *)group_info->edata;
+       wfd_session_s *session = NULL;
        wfd_group_s *group = NULL;
        wfd_device_s *peer = NULL;
 
-       if (!manager || !ifname || !go_dev_addr) {
+       if (!manager || !group_info || !edata) {
                WDS_LOGE("Invalid parameter");
                __WDS_LOG_FUNC_EXIT__;
                return -1;
@@ -142,21 +155,38 @@ int wfd_group_complete(void *data, char *ifname, int role, unsigned char *go_dev
                return -1;
        }
 
-       memcpy(group->ifname, ifname, IFACE_NAME_LEN);
-       group->ifname[IFACE_NAME_LEN] = '\0';
-       group->role = role;
-       memcpy(group->go_dev_addr, go_dev_addr, MACADDR_LEN);
+       g_strlcpy(group->ifname, group_info->ifname, IFACE_NAME_LEN + 1);
+       group->role = group_info->dev_role;
+       memcpy(group->go_dev_addr, edata->go_dev_addr, MACADDR_LEN);
        group->pending = 0;
 
-       peer = wfd_session_get_peer(manager->session);
+       g_strlcpy(group->ssid, edata->ssid, DEV_NAME_LEN + 1);
+       g_strlcpy(group->passphrase, edata->pass, PASSPHRASE_LEN +1);
+       memset(manager->local->passphrase, 0x0, PASSPHRASE_LEN +1);
+       group->freq = edata->freq;
+
+       manager->local->dev_role = group_info->dev_role;
+
+       session = manager->session;
+       peer = wfd_session_get_peer(session);
        if (!peer && !(group->flags & WFD_GROUP_FLAG_AUTONOMOUS)) {
-               WDS_LOGE("Failed to find peer by device address[" MACSTR "]", go_dev_addr);
+               WDS_LOGD("Failed to find peer by device address[" MACSECSTR "]",
+                                               MAC2SECSTR(edata->go_dev_addr));
                return -1;
        }
+
        if (group->role == WFD_DEV_ROLE_GO) {
                wfd_util_dhcps_start();
                WDS_LOGD("Role is Group Owner. DHCP Server started");
        } else {
+#ifdef CTRL_IFACE_DBUS
+               WDS_LOGD("Role is Group Client.complete session and add peer to member");
+               memcpy(peer->intf_addr, group->go_dev_addr, MACADDR_LEN);
+               wfd_group_add_member(group, peer->dev_addr);
+               session->state = SESSION_STATE_COMPLETED;
+               /* memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN); */
+               peer->state = WFD_PEER_STATE_CONNECTED;
+#endif /* CTRL_IFACE_DBUS */
                wfd_util_dhcpc_start(peer);
        }
 
@@ -191,30 +221,31 @@ int wfd_destroy_group(void *data, char *ifname)
                wfd_util_dhcps_stop();
        else
                wfd_util_dhcpc_stop();
+       memset(manager->local->ip_addr, 0x0, IPADDR_LEN);
 
        temp = g_list_first(group->members);
        while(temp && count < group->member_count) {
                member = temp->data;
-               WDS_LOGD("%dth member[%s] freed", count, member->dev_name);
-               if (member)     // Temporary. Sometimes manager crashed
-               {
-                       wfd_manager_init_service(member);
-                       if(member->wifi_display)
-                               free(member->wifi_display);
-                       free(member);
-               }
+               WDS_LOGD("%dth member[%s] will be removed", count, member->dev_name);
+               g_free(member);
+               member = NULL;
                temp = g_list_next(temp);
                count++;
        }
-       g_list_free(group->members);
 
-       free(group);
+       if (group->members) {
+               g_list_free(group->members);
+               group->members = NULL;
+       }
+
+       g_free(group);
 
        manager->local->dev_role = WFD_DEV_ROLE_NONE;
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
+#if 0
 int wfd_group_get_channel(wfd_group_s *group)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -228,6 +259,7 @@ int wfd_group_get_channel(wfd_group_s *group)
        __WDS_LOG_FUNC_EXIT__;
        return group->freq;
 }
+#endif
 
 int wfd_group_is_autonomous(wfd_group_s *group)
 {
@@ -243,6 +275,7 @@ int wfd_group_is_autonomous(wfd_group_s *group)
        return group->flags & WFD_GROUP_FLAG_AUTONOMOUS;;
 }
 
+#if 0
 int wfd_group_get_members()
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -272,6 +305,7 @@ int wfd_group_get_flags(wfd_group_s *group)
        __WDS_LOG_FUNC_EXIT__;
        return group->flags;
 }
+#endif
 
 wfd_device_s *wfd_group_find_member_by_addr(wfd_group_s *group, unsigned char *addr)
 {
@@ -299,7 +333,6 @@ wfd_device_s *wfd_group_find_member_by_addr(wfd_group_s *group, unsigned char *a
                        WDS_LOGD("Member found");
                        break;
                }
-next:
                temp = g_list_next(temp);
                member = NULL;
        }
@@ -360,13 +393,14 @@ int wfd_group_remove_member(wfd_group_s *group, unsigned char *addr)
 
        member = wfd_group_find_member_by_addr(group, addr);
        if (!member) {
-               WDS_LOGE("Member not found [MAC: " MACSTR "]", addr);
+               WDS_LOGD("Member not found [MAC: " MACSECSTR "]",
+                                               MAC2SECSTR(addr));
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
 
        group->members = g_list_remove(group->members, member);
-       free(member);
+       g_free(member);
        group->member_count--;
 
        __WDS_LOG_FUNC_EXIT__;
index 67b903d..7ed6e17 100644 (file)
 
 #include <glib.h>
 #include <glib-object.h>
-
 #include <wifi-direct.h>
-#include <wifi-direct-internal.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-oem.h"
 #include "wifi-direct-session.h"
@@ -93,7 +92,7 @@ static int _wfd_local_init_device(wfd_manager_s *manager)
        }
 
        errno = 0;
-       local = (wfd_device_s*) calloc(1, sizeof(wfd_device_s));
+       local = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
        if (!local) {
                WDS_LOGE("Failed to allocate memory for local device [%s]", strerror(errno));
                return -1;
@@ -102,8 +101,7 @@ static int _wfd_local_init_device(wfd_manager_s *manager)
        res = wfd_util_get_phone_name(local->dev_name);
        if (res < 0) {
                WDS_LOGE("Failed to get phone name of local device. Use default device name");
-               strncpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN);
-               local->dev_name[DEV_NAME_LEN] = '\0';
+               g_strlcpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN + 1);
        }
        WDS_LOGD("Local Device name [%s]", local->dev_name);
        wfd_util_set_dev_name_notification();
@@ -112,12 +110,18 @@ static int _wfd_local_init_device(wfd_manager_s *manager)
        if (res < 0) {
                WDS_LOGE("Failed to get local device MAC address");
        }
+
        memcpy(local->intf_addr, local->dev_addr, MACADDR_LEN);
        local->intf_addr[4] ^= 0x80;
-       WDS_LOGD("Local Interface MAC address [" MACSTR "]", MAC2STR(local->intf_addr));
+       WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
+                                       MAC2SECSTR(local->intf_addr));
 
        local->config_methods = WFD_WPS_MODE_PBC | WFD_WPS_MODE_DISPLAY | WFD_WPS_MODE_KEYPAD;
        local->wps_mode = WFD_WPS_MODE_PBC;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       local->services = NULL;
+       local->service_count = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
        // TODO: initialize other local device datas
        manager->local = local;
 
@@ -136,8 +140,8 @@ static int _wfd_local_deinit_device(wfd_manager_s *manager)
 
        wfd_util_unset_dev_name_notification();
 
-       if (manager->local)
-               free(manager->local);
+       // TODO: free member of local device
+       g_free(manager->local);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -146,12 +150,21 @@ static int _wfd_local_deinit_device(wfd_manager_s *manager)
 int wfd_local_reset_data(wfd_manager_s *manager)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s *local = manager->local;
+       wfd_device_s *local = NULL;
 
+       if (!manager) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       local = manager->local;
        /* init local device data */
        local->dev_role = WFD_DEV_ROLE_NONE;
        local->wps_mode = WFD_WPS_MODE_PBC;
        memset(local->go_dev_addr, 0x0, MACADDR_LEN);
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       memset(&(local->display), 0x0, sizeof(wfd_display_s));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
        memset(local->ip_addr, 0x0, IPADDR_LEN);
 
        __WDS_LOG_FUNC_EXIT__;
@@ -169,8 +182,7 @@ int wfd_local_get_dev_name(char *dev_name)
                return -1;
        }
 
-       strncpy(dev_name, local->dev_name, DEV_NAME_LEN);
-       dev_name[DEV_NAME_LEN-1] = '\0';
+       g_strlcpy(dev_name, local->dev_name, DEV_NAME_LEN + 1);
        WDS_LOGD("Local device name [%s]", dev_name);
 
        __WDS_LOG_FUNC_EXIT__;
@@ -188,27 +200,21 @@ int wfd_local_set_dev_name(char *dev_name)
                return -1;
        }
 
-       strncpy(local->dev_name, dev_name, DEV_NAME_LEN);
-       local->dev_name[DEV_NAME_LEN-1] = '\0';
+       g_strlcpy(local->dev_name, dev_name, DEV_NAME_LEN + 1);
 
        if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED) {
                wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
-
-               wfd_oem_scan_param_s param;
-               param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
-               param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
-               param.scan_time = 5;
-               param.refresh = TRUE;
-               wfd_oem_start_scan(g_manager->oem_ops, &param);
-               g_manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
-               WDS_LOGD("Device name changed. Active scan started");
+               WDS_LOGD("Device name changed.");
+       }
+       else {
+               WDS_LOGE("Device name can't changed: state is %d",g_manager->state);
        }
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int wfd_local_get_dev_mac(unsigned char *dev_mac)
+int wfd_local_get_dev_mac(char *dev_mac)
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_device_s *local = g_manager->local;
@@ -219,13 +225,14 @@ int wfd_local_get_dev_mac(unsigned char *dev_mac)
                return -1;
        }
 
-       memcpy(dev_mac, local->dev_addr, MACADDR_LEN);
-       WDS_LOGD("Local device MAC address [" MACSTR "]", MAC2STR(dev_mac));
+       g_snprintf(dev_mac, MACSTR_LEN, MACSTR, MAC2STR(local->dev_addr));
+       WDS_SECLOGD("Local device MAC address [%s]", dev_mac);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
+#if 0
 int wfd_local_get_intf_mac(unsigned char *intf_mac)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -237,12 +244,13 @@ int wfd_local_get_intf_mac(unsigned char *intf_mac)
                return -1;
        }
 
-       memcpy(intf_mac, local->intf_addr, MACADDR_LEN);
-       WDS_LOGD("Local interface MAC address [" MACSTR "]", MAC2STR(intf_mac));
+       g_snprintf(intf_mac, MACSTR_LEN, MACSTR, MAC2STR(local->intf_addr));
+       WDS_SECLOGD("Local interface MAC address [%s]", intf_mac);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif
 
 int wfd_local_get_ip_addr(char *ip_str)
 {
@@ -256,7 +264,7 @@ int wfd_local_get_ip_addr(char *ip_str)
        }
 
        snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(local->ip_addr));
-       WDS_LOGD("Local IP address [" IPSTR "]", IP2STR(local->ip_addr));
+       WDS_SECLOGD("Local IP address [" IPSECSTR "]", IP2SECSTR(local->ip_addr));
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -298,6 +306,7 @@ int wfd_local_get_wps_mode(int *wps_mode)
        return 0;
 }
 
+#if 0
 int wfd_local_set_wps_mode(int wps_mode)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -315,6 +324,7 @@ int wfd_local_set_wps_mode(int wps_mode)
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif
 
 int wfd_manager_get_go_intent(int *go_intent)
 {
@@ -472,64 +482,32 @@ int wfd_manager_local_config_set(wfd_manager_s *manager)
 
        local->wps_mode = WFD_WPS_MODE_PBC;
        WDS_LOGD("Device name set as %s", local->dev_name);
-       wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
-       wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
-       wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
-
-       return WIFI_DIRECT_ERROR_NONE;
-}
-
-int wfd_local_get_display_port(int *port)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s *local = g_manager->local;
-
-       if (!port) {
-               WDS_LOGE("Invalid parameter");
-               __WDS_LOG_FUNC_EXIT__;
-               return -1;
-       }
-
-       if (!local->wifi_display) {
-               WDS_LOGE("wifi display is not registered");
-               __WDS_LOG_FUNC_EXIT__;
-               return -1;
+       res = wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
+       if (res < 0) {
+               WDS_LOGE("Failed to set device name");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
-       *port = local->wifi_display->ctrl_port;
-       WDS_LOGD("Local display port [%d]", *port);
-
-       __WDS_LOG_FUNC_EXIT__;
-       return 0;
-}
-
-int wfd_local_get_display_type(wifi_direct_display_type_e *type)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s *local = g_manager->local;
-
-       if (!type) {
-               WDS_LOGE("Invalid parameter");
-               __WDS_LOG_FUNC_EXIT__;
-               return -1;
+       res = wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
+       if (res < 0) {
+               WDS_LOGE("Failed to set device type");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
-       if (!local->wifi_display) {
-               WDS_LOGE("wifi display is not registered");
-               __WDS_LOG_FUNC_EXIT__;
-               return -1;
+       res = wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
+       if (res < 0) {
+               WDS_LOGE("Failed to set go intent");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
 
-       *type = local->wifi_display->type;
-       WDS_LOGD("Local display type [%d]", *type);
-
-       __WDS_LOG_FUNC_EXIT__;
-       return 0;
+       return WIFI_DIRECT_ERROR_NONE;
 }
 
 int wfd_manager_activate(wfd_manager_s *manager)
 {
        __WDS_LOG_FUNC_ENTER__;
+       int concurrent = 0;
+       int prev_state = 0;
        int res = 0;
 
        if (!manager) {
@@ -542,12 +520,21 @@ int wfd_manager_activate(wfd_manager_s *manager)
                return 1;
        }
 
+       wfd_state_get(manager, &prev_state);
        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
 
-       res = wfd_oem_activate(manager->oem_ops);
+#if 0 /* No need to check wifi state. Net-config will check and proceed driver loading */
+       concurrent = wfd_util_check_wifi_state();
+       if (concurrent < 0) {
+               WDS_LOGE("Failed to get wifi state");
+               concurrent = 0;
+       }
+#endif
+
+       res = wfd_oem_activate(manager->oem_ops, concurrent);
        if (res < 0) {
                WDS_LOGE("Failed to activate");
-               wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
+               wfd_state_set(manager, prev_state);
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
        WDS_LOGE("Succeeded to activate");
@@ -555,6 +542,21 @@ int wfd_manager_activate(wfd_manager_s *manager)
        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
 
+       wfd_manager_local_config_set(manager);
+       wfd_util_set_country();
+
+       wfd_util_start_wifi_direct_popup();
+
+       res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
+       if (res < 0) {
+               WDS_LOGE("Failed to get local device MAC address");
+       }
+
+       memcpy(manager->local->intf_addr, manager->local->dev_addr, MACADDR_LEN);
+       manager->local->intf_addr[4] ^= 0x80;
+       WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
+                                       MAC2SECSTR(manager->local->intf_addr));
+
        __WDS_LOG_FUNC_EXIT__;
        return WIFI_DIRECT_ERROR_NONE;
 }
@@ -562,6 +564,8 @@ int wfd_manager_activate(wfd_manager_s *manager)
 int wfd_manager_deactivate(wfd_manager_s *manager)
 {
        __WDS_LOG_FUNC_ENTER__;
+       int concurrent = 0;
+       int prev_state = 0;
        int res = 0;
 
        if (!manager) {
@@ -574,13 +578,29 @@ int wfd_manager_deactivate(wfd_manager_s *manager)
                return WIFI_DIRECT_ERROR_NOT_PERMITTED;
        }
 
+       wfd_state_get(manager, &prev_state);
        wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
 
-       res = wfd_oem_deactivate(manager->oem_ops);
+       concurrent = wfd_util_check_wifi_state();
+       if (concurrent < 0) {
+               WDS_LOGE("Failed to get wifi state");
+               concurrent = 0;
+       }
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       res = wfd_oem_miracast_init(manager->oem_ops, false);
+       if (res < 0)
+               WDS_LOGE("Failed to initialize miracast");
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       res = wfd_oem_destroy_group(manager->oem_ops, "p2p-wlan0-0");
+       if (res < 0)
+               WDS_LOGE("Failed to destroy group before deactivation");
+
+       res = wfd_oem_deactivate(manager->oem_ops, concurrent);
        if (res < 0) {
                WDS_LOGE("Failed to deactivate");
-               // TODO: check state setting is correct
-               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+               wfd_state_set(manager, prev_state);
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
        WDS_LOGE("Succeeded to deactivate");
@@ -590,6 +610,11 @@ int wfd_manager_deactivate(wfd_manager_s *manager)
 
        manager->req_wps_mode = WFD_WPS_MODE_PBC;
 
+       wfd_destroy_group(manager, GROUP_IFNAME);
+       wfd_destroy_session(manager);
+       wfd_peer_clear_all(manager);
+       wfd_local_reset_data(manager);
+
        __WDS_LOG_FUNC_EXIT__;
        return WIFI_DIRECT_ERROR_NONE;
 }
@@ -607,7 +632,7 @@ int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
 
        session = (wfd_session_s*) manager->session;
        if (session && session->type != SESSION_TYPE_INVITE) {
-               WDS_LOGE("Session already exist or not an invitaion session");
+               WDS_LOGE("Session already exist and it's not an invitation session");
                return WIFI_DIRECT_ERROR_NOT_PERMITTED;
        }
 
@@ -620,16 +645,11 @@ int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
                }
        }
 
-       if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->type != SESSION_TYPE_INVITE) {
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
+                       session->type != SESSION_TYPE_INVITE) {
                session->type = SESSION_TYPE_INVITE;
                res = wfd_session_invite(session);
        } else {
-               /* joining to group or starting connection with PD */
-               /* In case of invitation session PD should be started
-                * peer->dev_role == WFD_DEV_ROLE_GO
-                * session->direction == SESSION_DIRECTION_INCOMING
-                * session->invitation == TRUE;
-                */
                res = wfd_session_start(session);
        }
        if (res < 0) {
@@ -670,29 +690,42 @@ int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_ad
        // TODO: check peer_addr with session's peer_addr
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
-               /* Peer want to join my group(Peer sent PD) */
                WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
                res = wfd_session_wps(session);
        } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
-               /* FIX ME: When Enter PIN or Display event comes up from supplicant
-                * manager send Connection WPS Req event to client.
-                * So, application use accept_connection API.
-                * This is odd situation. We need new client event such as WPS_KEYPAD/WPS_DISPLAY for application.
-                * We can correct alien code below with new client event */
-               if (session->direction == SESSION_DIRECTION_OUTGOING) {
-                       WDS_LOGD("Peer device is GO, WPS_Enrollee will be started");
-                       wfd_session_wps(manager->session);
+               WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");
+               if (session->type == SESSION_TYPE_INVITE) {
+                       if (session->state == SESSION_STATE_CREATED) {
+                               WDS_LOGD("Invitation session. PD will be started");
+                               res = wfd_session_start(session);
+                       } else {
+                               WDS_LOGD("Invitation session. Join will be started");
+                               res = wfd_session_join(session);
+                       }
                } else {
-                       WDS_LOGD("Peer device is GO, so Prov_Disc will be started");
-                       wfd_session_start(session);
+                       if (manager->autoconnection && (manager->auto_pin[0] != 0))
+                               g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
+
+                       WDS_LOGD("Peer device is GO, so WPS will be started");
+                       res = wfd_session_connect(session);
                }
        } else {
-               /* Prov_disc_req received. GO Negotiation will be started */
-               WDS_LOGD("My device is Device, so Negotiation will be started");
-               res = wfd_session_connect(session);
+               /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
+               /* Otherwise, GO Nego is sometimes failed. */
+               if (manager->autoconnection == FALSE) {
+                       WDS_LOGD("My device is Device, so Negotiation will be started");
+                       res = wfd_session_connect(session);
+               }
        }
        if (res < 0) {
                WDS_LOGE("Failed to start session");
+               if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+               } else {
+                       wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+                       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+               }
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
        }
        wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
@@ -705,7 +738,6 @@ int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_ad
 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_session_s *session = NULL;
        wfd_group_s *group = NULL;
        int res = 0;
 
@@ -764,12 +796,10 @@ int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_ad
                return WIFI_DIRECT_ERROR_NOT_PERMITTED;
        }
 
-       if (manager->local->dev_role == WFD_DEV_ROLE_NONE) {
-               res = wfd_oem_reject_connection(manager->oem_ops, peer_addr);
-               if (res < 0) {
-                       WDS_LOGE("Failed to reject connection");
-                       // TODO: check whether set state and break
-               }
+       res = wfd_session_reject(session, peer_addr);
+       if (res < 0) {
+               WDS_LOGE("Failed to reject connection");
+               // TODO: check whether set state and break
        }
        wfd_destroy_session(manager);
 
@@ -818,7 +848,12 @@ int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
        wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+#ifdef CTRL_IFACE_DBUS
+               /* dbus using device address to identify the peer */
+               res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr);
+#else /* CTRL_IFACE_DBUS */
                res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr);
+#endif /* CTRL_IFACE_DBUS */
        } else {
                res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
        }
@@ -907,92 +942,109 @@ failed:
        return res;
 }
 
-static int _wfd_manager_service_copy(char* dst, GList* services, int dst_length)
+int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_service_s *service = NULL;
-       GList *temp = NULL;
-       char* ptr = dst;
-       int length = dst_length;
+       wfd_device_s *peer_dev = NULL;
+       wfd_discovery_entry_s *peer_info;
+       wfd_oem_device_s *oem_dev = NULL;
        int res = 0;
 
-       temp = g_list_first(services);
-       while (temp) {
-
-               service = temp->data;
-               if(length < service->service_str_length + 4)
-               {
-                       WDS_LOGD("There is not enough space to reserve service list");
-                       break;
-               }
-
-               memcpy(ptr, service->service_string, service->service_str_length);
-               ptr+=service->service_str_length;
-               strncpy(ptr," ,\n",3);
-               ptr+=3;
-               length = length - service->service_str_length - 3;
-
-               temp = g_list_next(temp);
-       }
-       *ptr='\0';
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_manager_get_access_list(wfd_manager_s *manager, wfd_access_list_info_s **access_list_data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       GList *temp = NULL;
-       wfd_access_list_info_s *device = NULL;
-       wfd_access_list_info_s *devices = NULL;
-       int device_count = 0;
-       int count = 0;
-       int res = 0;
-
-       if (!manager || !access_list_data) {
+       if (!manager || !addr) {
                WDS_LOGE("Invalid parameter");
                return -1;
        }
 
-       device_count = g_list_length(manager->access_list);
-       if (device_count < 0)
-               return -1;
-       else if (device_count == 0)
-               return 0;
+       unsigned long time = 0;
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+       wfd_util_get_current_time(&time);
+#else
+       struct timeval tval;
+       gettimeofday(&tval, NULL);
+       time = tval.tv_sec;
+#endif
+       WDS_LOGI("Current time [%ld]", time);
 
-       errno = 0;
-       devices = (wfd_access_list_info_s*) calloc(device_count, sizeof(wfd_access_list_info_s));
-       if (!devices) {
-               WDS_LOGF("Failed to allocate memory for access list. [%s]", strerror(errno));
+       res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
+       if (res < 0 || !oem_dev) {
+               WDS_LOGE("Failed to get peer information");
                return -1;
        }
 
-       temp = g_list_first(manager->access_list);
-       while (temp && count < device_count) {
-               device = temp->data;
-               if (!device)
-                       goto next;
+       peer_dev = wfd_peer_find_by_addr(manager, addr);
+       if(!peer_dev) {
+               peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
+               if (!peer_dev) {
+                       WDS_LOGE("Failed to allocate memory for peer device. [%s]", strerror(errno));
+                       free(oem_dev);
+                       return -1;
+               }
+               memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
+               manager->peers = g_list_prepend(manager->peers, peer_dev);
+               manager->peer_count++;
+               peer_dev->time = time;
+               WDS_LOGD("peer_count[%d]", manager->peer_count);
+       } else {
+               if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
+                       WDS_LOGE("Too old age to update peer");
+                       free(oem_dev);
+                       return -1;
+               }
+       }
 
-               strncpy(devices[count].device_name, device->device_name, DEV_NAME_LEN);
-               devices[count].device_name[DEV_NAME_LEN] = '\0';
-               memcpy(devices[count].mac_address, device->mac_address, MACADDR_LEN);
-               devices[count].allowed = device->allowed;
+       g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
+       memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
+       memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
+       peer_dev->dev_role = oem_dev->dev_role;
+       peer_dev->config_methods = oem_dev->config_methods;
+       peer_dev->pri_dev_type = oem_dev->pri_dev_type;
+       peer_dev->sec_dev_type = oem_dev->sec_dev_type;
+       peer_dev->dev_flags = oem_dev->dev_flags;
+       peer_dev->group_flags = oem_dev->group_flags;
+       peer_dev->wps_mode =  oem_dev->wps_mode;
 
-               count++;
-               WDS_LOGD("%dth device in list [%s]", count, device->device_name);
-next:
-               temp = g_list_next(temp);
-               device = NULL;
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       peer_dev->time = time;
+       peer_dev->channel = oem_dev->channel;
+
+       free(oem_dev);
+
+       peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
+       if (!(peer_info)) {
+               WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
+               return -1;
        }
-       WDS_LOGD("%d devices converted", count);
-       WDS_LOGD("Final device count is %d", device_count);
 
-       *access_list_data = devices;
+       g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
+       memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
+       memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
+       peer_info->channel = peer_dev->channel;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+       peer_info->services = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+       peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
+       peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
+       peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
+       peer_info->wps_device_pwd_id = 0;
+       peer_info->wps_cfg_methods = peer_dev->config_methods;
+       peer_info->category = peer_dev->pri_dev_type;
+       peer_info->subcategory = peer_dev->sec_dev_type;
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       if (peer_dev->display.availablity && peer_dev->display.port)
+               peer_info->is_wfd_device = 1;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+       *peer = peer_info;
 
        __WDS_LOG_FUNC_EXIT__;
-       return count;
+       return res;
 }
 
+
 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -1009,21 +1061,26 @@ int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_
        }
 
        unsigned long time = 0;
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+       wfd_util_get_current_time(&time);
+#else
        struct timeval tval;
        gettimeofday(&tval, NULL);
        time = tval.tv_sec;
+#endif
        WDS_LOGI("Current time [%ld]", time);
 
        peer_count = manager->peer_count;
+       WDS_LOGI("peer count [%ld]", peer_count);
        if (peer_count < 0)
                return -1;
        else if (peer_count == 0)
                return 0;
 
        errno = 0;
-       peers = (wfd_discovery_entry_s*) calloc(peer_count, sizeof(wfd_discovery_entry_s));
+       peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
        if (!peers) {
-               WDS_LOGF("Failed to allocate memory for peer data. [%s]", strerror(errno));
+               WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
                return -1;
        }
 
@@ -1032,7 +1089,7 @@ int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_
                peer = temp->data;
                if (!peer)
                        goto next;
-               if (peer->time + 4 < time) {
+               if (peer->time + 8 < time) {
                        WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
                        res = wfd_update_peer(manager, peer);
                        if (res < 0) {
@@ -1040,20 +1097,19 @@ int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_
                                temp = g_list_next(temp);
                                manager->peers = g_list_remove(manager->peers, peer);
                                manager->peer_count--;
-                               wfd_manager_init_service(peer);
-                               if(peer->wifi_display)
-                                       free(peer->wifi_display);
-                               free(peer);
+                               g_free(peer);
                                peer = NULL;
                                continue;
                        }
                }
 
-               strncpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN);
-               peers[count].device_name[DEV_NAME_LEN] = '\0';
+               g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
                memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
                memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
                peers[count].channel = peer->channel;
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+               peers[count].services = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
                peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
                peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
                peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
@@ -1061,10 +1117,11 @@ int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_
                peers[count].wps_cfg_methods = peer->config_methods;
                peers[count].category = peer->pri_dev_type;
                peers[count].subcategory = peer->sec_dev_type;
-               _wfd_manager_service_copy(peers[count].services, peer->services, 1024);
-               if(peer->wifi_display)
-                       peers[count].is_wfd_device = peer->wifi_display->availability;
 
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+               if (peer->display.availablity && peer->display.port)
+                       peers[count].is_wfd_device = 1;
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
                count++;
                WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
 next:
@@ -1108,7 +1165,7 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
        }
 
        errno = 0;
-       peers = (wfd_connected_peer_info_s*) calloc(peer_count, sizeof(wfd_connected_peer_info_s));
+       peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
        if (!peers) {
                WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", strerror(errno));
                return -1;
@@ -1118,8 +1175,7 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
        while (temp && count < group->member_count) {
                peer = temp->data;
                {
-                       strncpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN);
-                       peers[count].device_name[DEV_NAME_LEN] = '\0';
+                       g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
                        memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
                        memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
                        memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
@@ -1127,7 +1183,16 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
                        peers[count].subcategory = peer->sec_dev_type;
                        peers[count].channel = peer->channel;
                        peers[count].is_p2p = 1;
-                       _wfd_manager_service_copy(peers[count].services, peer->services, 1024);
+#ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
+                       peers[count].services = 0;
+#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+                       if (peer->display.availablity && peer->display.port)
+                               peers[count].is_wfd_device = 1;
+
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
                        WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
                        count++;
                }
@@ -1142,6 +1207,7 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
        return count;
 }
 
+#if 0
 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -1157,27 +1223,7 @@ wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned c
        __WDS_LOG_FUNC_EXIT__;
        return peer;
 }
-
-wfd_device_s *wfd_manager_get_current_peer(wfd_manager_s *manager)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_session_s *session = NULL;
-
-       if (!manager) {
-               WDS_LOGE("Invalid parameter");
-               __WDS_LOG_FUNC_EXIT__;
-               return NULL;
-       }
-
-       session = manager->session;
-       if (session && session->peer) {
-               __WDS_LOG_FUNC_EXIT__;
-               return session->peer;
-       }
-
-       __WDS_LOG_FUNC_EXIT__;
-       return NULL;
-}
+#endif
 
 int wfd_manager_get_goup_ifname(char **ifname)
 {
@@ -1201,454 +1247,95 @@ int wfd_manager_get_goup_ifname(char **ifname)
        return 0;
 }
 
-static wfd_access_list_info_s *_wfd_manager_get_device_from_access_list(void *data, unsigned char *dev_addr)
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+int wfd_manager_set_display_device(int type, int port, int hdcp)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_manager_s *manager = (wfd_manager_s*) data;
-       wfd_access_list_info_s *device = NULL;
-       GList *temp = NULL;
-
-       if (!data || !dev_addr) {
-               WDS_LOGE("Invalid parameter");
-               return NULL;
-       }
-
-       temp = g_list_first(manager->access_list);
-       while (temp) {
-               device = temp->data;
-               if (!memcmp(device->mac_address, dev_addr, MACADDR_LEN)) {
-                       WDS_LOGD("device found[" MACSTR "]", MAC2STR(dev_addr));
-                       break;
-               }
-               temp = g_list_next(temp);
-               device = NULL;
-       }
-
-       __WDS_LOG_FUNC_EXIT__;
-       return device;
-}
-
-int wfd_manager_access_control(wfd_manager_s *manager, unsigned char *dev_addr)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_access_list_info_s *result = NULL;
-       int res = 0;
-
-       result = _wfd_manager_get_device_from_access_list(manager, dev_addr);
-
-       if(result)
-               res = result->allowed;
-       else
-               res = WFD_DEV_UNKNOWN;
-
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_manager_add_to_access_list(wfd_manager_s *manager, wfd_device_s *peer, int allowed)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_access_list_info_s *result = NULL;
-       GList *temp = NULL;
-       int res = 0;
-
-       result = _wfd_manager_get_device_from_access_list(manager, peer->dev_addr);
-       if(result)
-       {
-               if(result->allowed == allowed &&
-                               !strcmp(result->device_name, peer->dev_name))
-               {
-                       WDS_LOGD("already exist");
-                       __WDS_LOG_FUNC_EXIT__;
-                       return res;
-               }else {
-
-                       result->allowed = allowed;
-                       strncpy(result->device_name, peer->dev_name, DEV_NAME_LEN);
-                       result->device_name[DEV_NAME_LEN] = '\0';
-                       res = wfd_util_rewrite_device_list_to_file(manager->access_list);
-                       if(res < 0)
-                       {
-                               WDS_LOGE("fail to modify the peer in access list file");
-                       }
-
-               }
-       }else {
-
-               res = wfd_util_add_device_to_list(peer, allowed);
-               if(res > 0)
-               {
-                       result = calloc(1, sizeof(wfd_access_list_info_s));
-                       strncpy(result->mac_address, peer->dev_addr, MACADDR_LEN);
-                       strncpy(result->device_name, peer->dev_name, DEV_NAME_LEN);
-                       result->device_name[DEV_NAME_LEN] = '\0';
-                       result->allowed = allowed;
-                       manager->access_list = g_list_append(manager->access_list, result);
-               }else {
-                       WDS_LOGE("fail to append peer to access list file");
-                       res = -1;
-               }
-       }
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_manager_del_from_access_list(wfd_manager_s *manager, unsigned char *mac)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_access_list_info_s *device = NULL;
-       GList *temp = NULL;
-       int res = 0;
-
-       device = _wfd_manager_get_device_from_access_list(manager, mac);
-       if(device)
-       {
-               manager->access_list = g_list_remove(manager->access_list , device);
-               free(device);
-
-               res = wfd_util_rewrite_device_list_to_file(manager->access_list);
-               if (res < 0)
-                       WDS_LOGE("fail to remove device from list file!");
-
-
-       }else if(!memcmp(mac,"\0x00\0x00\0x00\0x00\0x00\0x00",MACADDR_LEN)){
-
-               res = wfd_util_reset_access_list_file();
-               if(res == 0)
-               {
-                       g_list_foreach (manager->access_list, (GFunc)g_free, NULL);
-                       g_list_free (manager->access_list);
-                       manager->access_list = NULL;
-               }else {
-                       WDS_LOGE("fail to reset access list file");
-               }
-
-       }else {
-               WDS_LOGD("device dose not exist");
-       }
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-static wfd_service_s *_wfd_service_find(wfd_device_s *device, wifi_direct_service_type_e type, char *data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_service_s *result = NULL;
-       GList *temp = NULL;
-       int cmp_result = 0;
-
-       temp = g_list_first(device->services);
-       while (temp) {
-               result = temp->data;
-
-               if(result->service_type == WIFI_DIRECT_SERVICE_BONJOUR)
-                       cmp_result = strncmp(data, result->service_string, strlen(data));
-               else
-                       cmp_result = strcmp(data, result->service_string);
-
-               if(type == result->service_type && !cmp_result)
-               {
-                       WDS_LOGD("Service found");
-                       break;
-               }
-               temp = g_list_next(temp);
-               result = NULL;
-       }
-       __WDS_LOG_FUNC_EXIT__;
-       return result;
-}
-
-static wfd_query_s *_wfd_query_find(wfd_manager_s *manager, unsigned char* mac_addr, wifi_direct_service_type_e  type, char *data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_query_s *query = NULL;
-       GList *temp = NULL;
-       int data_len = 0;
-
-       if(data != NULL)
-               data_len = strlen(data);
-
-       temp = g_list_first(manager->query_handles);
-       while (temp) {
-               query = temp->data;
-
-               if(!memcmp(query->mac_addr, mac_addr, MACADDR_LEN) &&
-                               type == query->service_type)
-               {
-                       if(data_len)
-                       {
-                               if(!strcmp(data, query->query_string))
-                               {
-                                       WDS_LOGD("Query found");
-                                       break;
-                               }
-                       }else{
-                               WDS_LOGD("Query found");
-                               break;
-                       }
-               }
-               temp = g_list_next(temp);
-               query = NULL;
-       }
-       __WDS_LOG_FUNC_EXIT__;
-       return query;
-}
-
-int wfd_manager_service_add(wfd_manager_s *manager, wifi_direct_service_type_e  type, char *data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s * device = manager->local;
-       wfd_service_s * service;
+       wfd_device_s * device = g_manager->local;
+       wfd_oem_display_s display;
        int res = 0;
 
-       if (!device || !data) {
+       if (!device) {
                WDS_LOGE("Invalid parameter");
-               return -1;
-       }
-
-       service = _wfd_service_find(device, type, data);
-       if (service) {
-               WDS_LOGE("service already exist");
-               service->ref_counter++;
-               __WDS_LOG_FUNC_EXIT__;
-               return 0;
-       }
-
-       res = wfd_oem_service_add(manager->oem_ops, type, data);
-       if (res < 0) {
-               WDS_LOGE("Failed to add service");
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
 
-       service = (wfd_service_s*) calloc(1, sizeof(wfd_service_s));
-       service->service_string = strndup(data, strlen(data));
-       service->service_str_length = strlen(data);
-       service->service_type = type;
-       service->ref_counter=1;
-       device->services = g_list_prepend(device->services, service);
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_manager_service_del(wfd_manager_s *manager, wifi_direct_service_type_e  type, char *data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s * device = manager->local;
-       wfd_service_s* service;
-       int res = 0;
-
-       if (!device || !data) {
-               WDS_LOGE("Invalid parameter");
-               return -1;
-       }
-       service = _wfd_service_find(device, type, data);
-       if (!service) {
-               WDS_LOGE("Failed to find service");
-               res = -1;
-
-       }else if(service->ref_counter ==1)
-       {
-               res = wfd_oem_service_del(manager->oem_ops, type, data);
-               if (res < 0) {
-                       WDS_LOGE("Failed to delete service");
-                       __WDS_LOG_FUNC_EXIT__;
-                       return -1;
-               }
-               device->services = g_list_remove(device->services, service);
-               free(service->service_string);
-               free(service);
-
-       }else{
-               service->ref_counter--;
-       }
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
+       memset(&display, 0x0, sizeof(wfd_oem_display_s));
 
-int wfd_manager_serv_disc_req(wfd_manager_s *manager, unsigned char* mad_addr, wifi_direct_service_type_e  type, char *data)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_query_s* query;
-       int res = 0;
+       display.type = type;
+       display.port = port;
+       display.hdcp_support = hdcp;
 
-       if (!manager) {
-               WDS_LOGE("Invalid parameter");
-               return -1;
-       }
-       query = _wfd_query_find(manager, mad_addr, type, data);
-       if (query) {
-               WDS_LOGE("Query already exist");
-               query->ref_counter++;
-               __WDS_LOG_FUNC_EXIT__;
-               return 0;
-       }
+       display.availablity = device->display.availablity;
+       display.max_tput = device->display.max_tput;
 
-       res = wfd_oem_serv_disc_req(manager->oem_ops, mad_addr, type, data);
+       res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
        if (res < 0) {
-               WDS_LOGE("Failed to request service discovery");
-               return res;
-       }
-       query = (wfd_query_s*) calloc(1, sizeof(wfd_query_s));
-       query->handle = res;
-       query->ref_counter=1;
-       memcpy(query->mac_addr, mad_addr, MACADDR_LEN);
-
-       if(data && strlen(data))
-               query->query_string = strndup(data, strlen(data));
-       query->service_type = type;
-       manager->query_handles = g_list_prepend(manager->query_handles, query);
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_manager_serv_disc_cancel(wfd_manager_s *manager,  int handle)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_query_s *query = NULL;
-       GList *temp = NULL;
-       int res = 0;
-
-       temp = g_list_first(manager->query_handles);
-       while (temp) {
-               query = temp->data;
-
-               //TODO : compare the services
-               if(query->handle == handle)
-               {
-                       WDS_LOGD("Query handle found");
-                       break;
-               }
-               temp = g_list_next(temp);
-               query = NULL;
-       }
-
-       if(query == NULL) {
-               WDS_LOGE("handle does not exist");
+               WDS_LOGE("Failed to set wifi display");
                return -1;
-       }else if(query->ref_counter ==1) {
+       }
 
-               res = wfd_oem_serv_disc_cancel(manager->oem_ops, query->handle);
-               if (res < 0) {
-                       WDS_LOGE("Failed to cancel service discovery or already canceled");
-               }
-               manager->query_handles = g_list_remove(manager->query_handles, query);
-               if(query->query_string)
-                       free(query->query_string);
-               free(query);
-       }else
-               query->ref_counter--;
+       device->display.type = type;
+       device->display.port = port;
+       device->display.hdcp_support = hdcp;
 
        __WDS_LOG_FUNC_EXIT__;
        return res;
 }
 
-int wfd_manager_init_service(wfd_device_s *device)
+int wfd_manager_set_session_availability(int availability)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_service_s* service = NULL;
-       GList *temp = NULL;
+       wfd_device_s * device = g_manager->local;
+       wfd_oem_display_s display;
        int res = 0;
 
        if (!device) {
                WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
 
-       if(device->services)
-       {
-               temp = g_list_first(device->services);
-               while (temp) {
-                       service = temp->data;
-                       free(service->service_string);
-                       free(service);
-                       temp = g_list_next(temp);
-               }
-               g_list_free(device->services);
-       }
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_manager_init_query(wfd_manager_s *manager)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_query_s *query = NULL;
-       GList *temp = NULL;
-       int res = 0;
-
-       if (!manager) {
-               WDS_LOGE("Invalid parameter");
-               return -1;
-       }
-
-       if(manager->query_handles)
-       {
-               temp = g_list_first(manager->query_handles);
-               while (temp) {
-                       query = temp->data;
+       memset(&display, 0x0, sizeof(wfd_oem_display_s));
 
-                       free(query->query_string);
-                       free(query);
-                       temp = g_list_next(temp);
-               }
-               g_list_free(manager->query_handles);
-       }
+       display.availablity = availability;
 
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_manager_init_wifi_display(wifi_direct_display_type_e type, int port, int hdcp)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s * device = g_manager->local;
-       wfd_display_info_s * display;
-       int res = 0;
+       display.type = device->display.type;
+       display.hdcp_support = device->display.hdcp_support;
+       display.port = device->display.port;
+       display.max_tput = device->display.max_tput;
 
-       if (type < 0 || port < 0 || hdcp < 0) {
-               WDS_LOGE("Invalid parameter");
-               __WDS_LOG_FUNC_EXIT__;
-               return -1;
-       }
-
-       res = wfd_oem_init_wifi_display(g_manager->oem_ops, type, port, hdcp);
+       res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
        if (res < 0) {
-               WDS_LOGE("Failed to initialize wifi display");
+               WDS_LOGE("Failed to set wifi display session availability");
                return -1;
        }
 
-       if(!device->wifi_display)
-               device->wifi_display = calloc(1, sizeof(wfd_display_info_s));
-
-       device->wifi_display->type = type;
-       device->wifi_display->hdcp_support = hdcp;
-       device->wifi_display->ctrl_port = port;
+       device->display.availablity = availability;
 
        __WDS_LOG_FUNC_EXIT__;
        return res;
 }
 
-int wfd_manager_deinit_wifi_display()
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+
+wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s * device = g_manager->local;
-       wfd_display_info_s * display;
-       int res = 0;
-
-       res = wfd_oem_deinit_wifi_display(g_manager->oem_ops);
-       if (res < 0) {
-               WDS_LOGE("Failed to deinitialize wifi display");
-               return -1;
+       wfd_device_s *peer = NULL;
+       if(manager->group) {
+               peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
        }
 
-       if(device->wifi_display)
-       {
-               free(device->wifi_display);
-               device->wifi_display = NULL;
+       if(peer) {
+               return peer;
        }
+
+       peer = wfd_peer_find_by_addr(manager, peer_addr);
+
+       return peer;
        __WDS_LOG_FUNC_EXIT__;
-       return res;
 }
 
 static wfd_manager_s *wfd_manager_init()
@@ -1657,7 +1344,7 @@ static wfd_manager_s *wfd_manager_init()
        wfd_manager_s *manager = NULL;
        int res = 0;
 
-       manager = (wfd_manager_s*) calloc(1, sizeof(wfd_manager_s));
+       manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
        if (!manager) {
                WDS_LOGE("Failed to allocate memory for wfd_manager structure");
                return NULL;
@@ -1666,16 +1353,10 @@ static wfd_manager_s *wfd_manager_init()
        manager->go_intent = 7;
        manager->req_wps_mode = WFD_WPS_MODE_PBC;
        manager->max_station = 8;
-
-       res = wfd_util_get_access_list(&(manager->access_list));
-       if (res < 0) {
-               WDS_LOGE("Failed to get access list");
-       }
-
        res = _wfd_local_init_device(manager);
        if (res < 0) {
                WDS_LOGE("Failed to initialize local device");
-               free(manager);
+               g_free(manager);
                return NULL;            // really stop manager?
        }
        WDS_LOGD("Succeeded to initialize local device");
@@ -1702,14 +1383,9 @@ int wfd_manager_deinit(wfd_manager_s *manager)
                g_source_remove(manager->exit_timer);
        manager->exit_timer = 0;
 
-       g_list_foreach (manager->access_list, (GFunc)g_free, NULL);
-       g_list_free (manager->access_list);
-       manager->access_list = NULL;
-
        _wfd_local_deinit_device(manager);
 
-       if (manager)
-               free(manager);
+       g_free(manager);
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -1794,10 +1470,14 @@ int main(int argc, char *argv[])
        GMainLoop *main_loop = NULL;
        int res = 0;
 
+#if !GLIB_CHECK_VERSION(2,32,0)
        if (!g_thread_supported())
                g_thread_init(NULL);
+#endif
 
+#if !GLIB_CHECK_VERSION(2,36,0)
        g_type_init();
+#endif
 
        // TODO: Parsing argument
        /* Wi-Fi direct connection for S-Beam can be optimized using argument */
index 6e6d9e6..8b845ac 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 
 #include <glib.h>
 
-#include <wifi-direct-internal.h>
+#include <wifi-direct.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-oem.h"
 #include "wifi-direct-util.h"
@@ -53,15 +55,19 @@ wfd_device_s *wfd_add_peer(void *data, unsigned char *dev_addr, char *dev_name)
 
        peer = wfd_peer_find_by_dev_addr(manager, dev_addr);
        if (peer) {
-               WDS_LOGE("Peer already exist[" MACSTR "]", MAC2STR(dev_addr));
+               WDS_LOGD("Peer already exist[" MACSECSTR "]", MAC2SECSTR(dev_addr));
                __WDS_LOG_FUNC_EXIT__;
                return NULL;
        }
 
-       peer = (wfd_device_s*) calloc(1, sizeof(wfd_device_s));
+       peer = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
+       if (peer == NULL) {
+               WDS_LOGE("Failed to allocate memory for peer[" MACSTR "]", MAC2STR(dev_addr));
+               __WDS_LOG_FUNC_EXIT__;
+               return NULL;
+       }
        memcpy(peer->dev_addr, dev_addr, MACADDR_LEN);
-       strncpy(peer->dev_name, dev_name, DEV_NAME_LEN);
-       peer->dev_name[DEV_NAME_LEN-1] = '\0';
+       g_strlcpy(peer->dev_name, dev_name, DEV_NAME_LEN + 1);
 
        manager->peers = g_list_prepend(manager->peers, peer);
        manager->peer_count++;
@@ -92,10 +98,8 @@ int wfd_remove_peer(void *data, unsigned char *dev_addr)
        manager->peers = g_list_remove(manager->peers, peer);
        manager->peer_count--;
 
-       wfd_manager_init_service(peer);
-       if(peer->wifi_display)
-               free(peer->wifi_display);
-       free(peer);
+       g_free(peer);
+
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
@@ -113,13 +117,17 @@ int wfd_update_peer_time(void*data, unsigned char *peer_addr)
 
        peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
        if (!peer) {
-               WDS_LOGE("Peer not found [" MACSTR "]", MAC2STR(peer_addr));
+               WDS_LOGD("Peer not found [" MACSECSTR "]", MAC2SECSTR(peer_addr));
                return -1;
        }
 
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+       wfd_util_get_current_time(&peer->time);
+#else
        struct timeval tval;
        gettimeofday(&tval, NULL);
        peer->time = tval.tv_sec;
+#endif
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -138,19 +146,20 @@ int wfd_update_peer(void *data, wfd_device_s *peer)
        }
 
        res = wfd_oem_get_peer_info(manager->oem_ops, peer->dev_addr, &oem_dev);
-       if (res < 0) {
+       if (res < 0 || !oem_dev) {
                WDS_LOGE("Failed to get peer information");
                return -1;
        }
 
-       if (oem_dev->age > 4 && peer->state == WFD_PEER_STATE_DISCOVERED) {
+       if (oem_dev->age > 30 && peer->state == WFD_PEER_STATE_DISCOVERED) {
                WDS_LOGE("Too old age to update peer");
+               g_free(oem_dev);
                return -1;
        }
-       strncpy(peer->dev_name, oem_dev->dev_name, DEV_NAME_LEN);
-       peer->dev_name[DEV_NAME_LEN] = '\0';
+       g_strlcpy(peer->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
        memcpy(peer->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
        memcpy(peer->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
+       peer->channel = oem_dev->channel;
        peer->dev_role = oem_dev->dev_role;
        peer->config_methods = oem_dev->config_methods;
        peer->pri_dev_type = oem_dev->pri_dev_type;
@@ -159,13 +168,19 @@ int wfd_update_peer(void *data, wfd_device_s *peer)
        peer->group_flags = oem_dev->group_flags;
        peer->wps_mode =  oem_dev->wps_mode;
 
-       if(!peer->wifi_display)
-               peer->wifi_display = calloc(1, sizeof(wfd_display_info_s));
-       memcpy(peer->wifi_display, &oem_dev->wifi_display, sizeof(wfd_display_info_s));
+#ifdef TIZEN_FEATURE_WIFI_DISPLAY
+       memcpy(&(peer->display), &(oem_dev->display), sizeof(wfd_display_s));
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
+       g_free(oem_dev);
+
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+       wfd_util_get_current_time(&peer->time);
+#else
        struct timeval tval;
        gettimeofday(&tval, NULL);
        peer->time = tval.tv_sec;
+#endif
 
        __WDS_LOG_FUNC_EXIT__;
        return 0;
@@ -186,22 +201,22 @@ int wfd_peer_clear_all(void *data)
        temp = g_list_first(manager->peers);
        while(temp) {
                peer = (wfd_device_s*) temp->data;
-               wfd_manager_init_service(peer);
-               if(peer->wifi_display)
-                       free(peer->wifi_display);
-               free(peer);
+               g_free(peer);
                temp = g_list_next(temp);
                manager->peer_count--;
        }
-       g_list_free(manager->peers);
-       manager->peers = NULL;
+
+       if(manager->peers) {
+               g_list_free(manager->peers);
+               manager->peers = NULL;
+       }
 
        if (manager->peer_count){
                WDS_LOGE("Peer count is not synced. left count=%d", manager->peer_count);
                manager->peer_count = 0;
                return 1;
        }
-       
+
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
@@ -227,7 +242,7 @@ wfd_device_s *wfd_peer_find_by_dev_addr(void *data, unsigned char *dev_addr)
        while (temp) {
                peer = temp->data;
                if (!memcmp(peer->dev_addr, dev_addr, MACADDR_LEN)) {
-                       WDS_LOGD("Peer device found[" MACSTR "]", MAC2STR(dev_addr));
+                       WDS_LOGD("Peer device found[" MACSECSTR "]", MAC2SECSTR(dev_addr));
                        break;
                }
                temp = g_list_next(temp);
@@ -238,6 +253,7 @@ wfd_device_s *wfd_peer_find_by_dev_addr(void *data, unsigned char *dev_addr)
        return peer;
 }
 
+#if 0
 wfd_device_s *wfd_peer_find_by_intf_addr(void *data, unsigned char *intf_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -259,7 +275,7 @@ wfd_device_s *wfd_peer_find_by_intf_addr(void *data, unsigned char *intf_addr)
        while (temp) {
                peer = temp->data;
                if (!memcmp(peer->intf_addr, intf_addr, MACADDR_LEN)) {
-                       WDS_LOGD("Peer device found[" MACSTR "]", MAC2STR(intf_addr));
+                       WDS_LOGD("Peer device found[" MACSECSTR "]", MAC2SECSTR(intf_addr));
                        break;
                }
                temp = g_list_next(temp);
@@ -269,6 +285,7 @@ wfd_device_s *wfd_peer_find_by_intf_addr(void *data, unsigned char *intf_addr)
        __WDS_LOG_FUNC_EXIT__;
        return peer;
 }
+#endif
 
 wfd_device_s *wfd_peer_find_by_addr(void *data, unsigned char *addr)
 {
@@ -292,7 +309,7 @@ wfd_device_s *wfd_peer_find_by_addr(void *data, unsigned char *addr)
                peer = temp->data;
                if (!memcmp(peer->dev_addr, addr, MACADDR_LEN) ||
                                !memcmp(peer->intf_addr, addr, MACADDR_LEN)) {
-                       WDS_LOGE("Peer device found[" MACSTR "]", MAC2STR(addr));
+                       WDS_LOGD("Peer device found[" MACSECSTR "]", MAC2SECSTR(addr));
                        break;
                }
                temp = g_list_next(temp);
@@ -303,26 +320,29 @@ wfd_device_s *wfd_peer_find_by_addr(void *data, unsigned char *addr)
        return peer;
 }
 
+#if 0
 wfd_device_s *wfd_peer_find_current_peer(void *data)
 {
        __WDS_LOG_FUNC_ENTER__;
-       wfd_device_s *peer = NULL;
        wfd_manager_s *manager = (wfd_manager_s*) data;
        if (!manager) {
                WDS_LOGE("Invalid parameter");
                return NULL;
        }
-       
+
        wfd_session_s *session = manager->session;
        if (!session) {
                WDS_LOGE("Session not found");
                return NULL;
        }
 
-       peer = session->peer;
+       if (!session->peer) {
+               WDS_LOGE("Peer not found");
+               return NULL;
+       }
 
        __WDS_LOG_FUNC_EXIT__;
-       return peer;
+       return session->peer;
 }
 
 int wfd_peer_set_data(unsigned char *dev_addr, int type, int data)
@@ -338,4 +358,4 @@ int wfd_peer_get_data(unsigned char *dev_addr, int type, int data)
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
-
+#endif
diff --git a/src/wifi-direct-service.c b/src/wifi-direct-service.c
new file mode 100644 (file)
index 0000000..dfee6a0
--- /dev/null
@@ -0,0 +1,189 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <wifi-direct.h>
+
+#include "wifi-direct-ipc.h"
+#include "wifi-direct-manager.h"
+#include "wifi-direct-oem.h"
+#include "wifi-direct-service.h"
+#include "wifi-direct-util.h"
+
+
+int wfd_service_add(GList **services, int type, char *info_str, int *service_id)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_manager_s *manager = wfd_get_manager();
+       wfd_service_s *service = NULL;
+//     wfd_oem_new_service_s *oem_service = NULL;
+       char *info1 = NULL;
+       char *info2 = NULL;
+       char *sep = NULL;
+       int res = 0;
+
+       if (!info_str) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       if (type < WIFI_DIRECT_SERVICE_TYPE_BONJOUR || type > WIFI_DIRECT_SERVICE_TYPE_VENDOR){
+               WDS_LOGE("Invalid service type");
+               return -1;
+       }
+
+       service = (wfd_service_s*) g_try_malloc0(sizeof(wfd_service_s));
+       if (!service) {
+               WDS_LOGE("Failed to allocate memory for service");
+               return -1;
+       }
+
+       service->type = type;
+       service->id = (int) &service;
+
+       info1 = g_strndup(info_str, strlen(info_str));
+       if(info1 == NULL) {
+               WDS_LOGE("Failed to allocate memory for service");
+               g_free(service);
+               return -1;
+       }
+       sep = strchr(info1, '|');
+       if(sep == NULL) {
+               WDS_LOGE("Failed to find delimiter");
+               g_free(info1);
+               g_free(service);
+               return -1;
+       }
+
+       *sep = '\0';
+       info2 = sep + 1;
+
+       switch (service->type) {
+               case WIFI_DIRECT_SERVICE_TYPE_BONJOUR:
+                       service->data.bonjour.query = info1;
+                       if(strstr(info2, "ptr")){
+                               service->data.bonjour.rdata_type = WFD_BONJOUR_RDATA_PTR;
+                       } else {
+                               service->data.bonjour.rdata_type = WFD_BONJOUR_RDATA_TXT;
+                       }
+                       service->data.bonjour.rdata = info2 +3;
+               break;
+               case WIFI_DIRECT_SERVICE_TYPE_UPNP:
+                       service->data.upnp.version = info1;
+                       service->data.upnp.service = info2;
+               break;
+               case WIFI_DIRECT_SERVICE_TYPE_WS_DISCOVERY:
+               case WIFI_DIRECT_SERVICE_TYPE_WIFI_DISPLAY:
+               case WIFI_DIRECT_SERVICE_TYPE_BT_ADDR:
+                       WDS_LOGE("Not supported yet");
+                       g_free(info1);
+                       g_free(service);
+                       return-1;
+               break;
+               case WIFI_DIRECT_SERVICE_TYPE_VENDOR:
+                       service->data.vendor.info1 = info1;
+                       service->data.vendor.info2 = info2;
+               break;
+               default:
+                       WDS_LOGE("Invalid service type");
+                       g_free(info1);
+                       g_free(service);
+                       return-1;
+               break;
+       }
+
+//     oem_service = (wfd_oem_new_service_s*) calloc(1, sizeof(wfd_oem_new_service_s));
+//     oem_service->protocol = service->type;
+//     oem_service->data = service->data;
+
+       res = wfd_oem_serv_add(manager->oem_ops, (wfd_oem_new_service_s*) service);
+       if (res < 0) {
+               WDS_LOGE("Failed to add service");
+               g_free(info1);
+               g_free(service);
+               return -1;
+       }
+
+//     free(oem_service);
+
+       service->str_ptr = info1;
+       *services = g_list_prepend(*services, service);
+       *service_id = service->id;
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int wfd_service_del(GList *services, int service_id)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_manager_s *manager = wfd_get_manager();
+       GList *temp = NULL;
+       wfd_service_s *service = NULL;
+       int res = 0;
+
+       if (!services) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       temp = g_list_first(services);
+       while (temp) {
+               service = (wfd_service_s*) temp->data;
+               if (service->id == service_id) {
+                       WDS_LOGD("Service found");
+                       break;
+               }
+               service = NULL;
+               temp = g_list_next(temp);
+       }
+
+       if (!service) {
+               WDS_LOGE("Service not found");
+               return -1;
+       }
+
+       res = wfd_oem_serv_del(manager->oem_ops, (wfd_oem_new_service_s*) service);
+       if (res < 0) {
+               WDS_LOGE("Failed to add service");
+               return -1;
+       }
+
+       services = g_list_remove(services, service);
+
+       g_free(service->str_ptr);
+       g_free(service);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+#if 0
+int wfd_service_disc_req(unsigned char *addr, int type, char *data)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       int handle = 0;
+       // TODO: return identifier(handle) for the pending query
+
+       if (!addr) {
+               WDS_LOGE("Invalid parameter");
+               return -1;
+       }
+
+       if (type < WFD_SERVICE_TYPE_ALL || type > WFD_SERVICE_TYPE_VENDOR){
+               WDS_LOGE("Invalid service type");
+               return -1;
+       }
+
+       // TODO: call oem function
+       // TODO: add service information into service list
+
+       __WDS_LOG_FUNC_EXIT__;
+       return handle;
+}
+
+int wfd_service_disc_cancel(int handle)
+{
+       return 0;
+}
+#endif
index 5bc3abe..cc455a2 100644 (file)
@@ -30,8 +30,9 @@
 
 #include <glib.h>
 
-#include <wifi-direct-internal.h>
+#include <wifi-direct.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-oem.h"
 #include "wifi-direct-peer.h"
@@ -64,7 +65,8 @@ static gboolean _session_timeout_cb(gpointer *user_data)
        memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
        noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
        noti.error = WIFI_DIRECT_ERROR_CONNECTION_CANCELED;
-       snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+       if(peer_addr != NULL)
+               g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
        wfd_client_send_event(manager, &noti);
 
        wfd_session_cancel(session, peer_addr);
@@ -81,6 +83,27 @@ static gboolean _session_timeout_cb(gpointer *user_data)
        return FALSE;
 }
 
+static void _wfd_notify_session_failed(wfd_manager_s *manager, unsigned char *peer_addr)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wifi_direct_client_noti_s noti;
+       memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
+       noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
+       noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
+       snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
+       } else {
+               wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+               wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+       }
+
+       wfd_client_send_event(manager, &noti);
+       __WDS_LOG_FUNC_EXIT__;
+}
+
 int wfd_session_timer(wfd_session_s *session, int start)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -92,7 +115,9 @@ int wfd_session_timer(wfd_session_s *session, int start)
        }
 
        if (start) {
-               session->connecting_120 = 1;
+               if (!session->connecting_120)
+                       session->connecting_120 = 1;
+
                if (session->timer > 0) {
                        WDS_LOGE("Session timer already started");
                        __WDS_LOG_FUNC_EXIT__;
@@ -129,12 +154,14 @@ wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_
                return NULL;
        }
 
+       WDS_LOGD("create session for peer[" MACSTR "]", MAC2STR(peer_addr));
+
        if (manager->session) {
                WDS_LOGE("Session already exist");
                return NULL;
        }
 
-       session = (wfd_session_s*) calloc(1, sizeof(wfd_session_s));
+       session = (wfd_session_s*) g_try_malloc0(sizeof(wfd_session_s));
        if (!session) {
                WDS_LOGE("Failed to allocate memory for session");
                __WDS_LOG_FUNC_EXIT__;
@@ -143,8 +170,8 @@ wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_
 
        peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
        if (!peer) {
-               WDS_LOGE("Failed to find peer info[" MACSTR "]", MAC2STR(peer_addr));
-               free(session);
+               WDS_LOGE("Failed to find peer info[" MACSECSTR "]", MAC2SECSTR(peer_addr));
+               g_free(session);
                __WDS_LOG_FUNC_EXIT__;
                return NULL;
        }
@@ -163,7 +190,7 @@ wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_
 
        manager->session = session;
        manager->local->wps_mode = session->wps_mode;
-       if (peer->dev_role == WFD_DEV_ROLE_GO)
+       if (peer->dev_role == WFD_DEV_ROLE_GO && manager->local->dev_role != WFD_DEV_ROLE_GO)
                manager->local->dev_role = WFD_DEV_ROLE_GC;
 
        __WDS_LOG_FUNC_EXIT__;
@@ -184,21 +211,26 @@ int wfd_destroy_session(void *data)
 
        session = (wfd_session_s*) manager->session;
        if (!session) {
-               WDS_LOGE("Session not found");
+               WDS_LOGE("Session not found");  // self prevent 13029
                return -1;
        }
        wfd_session_timer(session, 0);
        peer = session->peer;
-       
-       if (session->state == SESSION_STATE_COMPLETED)
-               peer->state = WFD_PEER_STATE_CONNECTED;
-       else
-               peer->state = WFD_PEER_STATE_DISCOVERED;
 
-       free(session);
+       if(peer) {
+               if (session->state == SESSION_STATE_COMPLETED)
+                       peer->state = WFD_PEER_STATE_CONNECTED;
+               else
+                       peer->state = WFD_PEER_STATE_DISCOVERED;
+       } else {
+               WDS_LOGE("Peer not found");
+       }
+
+       g_free(session);
        manager->session = NULL;
        manager->local->wps_mode = WFD_WPS_MODE_PBC;
        manager->autoconnection = 0;
+       memset(manager->auto_pin, 0x0, PINSTR_LEN);
        if (manager->local->dev_role == WFD_DEV_ROLE_GC)
                manager->local->dev_role = WFD_DEV_ROLE_NONE;
 
@@ -220,6 +252,11 @@ int wfd_session_start(wfd_session_s *session)
                return -1;
        }
 
+       if (session->state > SESSION_STATE_STARTED) {
+               WDS_LOGE("Invalid session state(%d)", session->state);
+               return -1;
+       }
+
        // Check: Invitation Received in Incomming case -> send prov_disc join
        // Check: User select peer to connect with in Outgoing case -> send prov_disc wps_mdde
 
@@ -232,8 +269,8 @@ int wfd_session_start(wfd_session_s *session)
        res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
                                        session->req_wps_mode, join);
        if (res < 0) {
-               WDS_LOGE("Failed to send provision discovery request to peer [" MACSTR "]",
-                                                                       MAC2STR(peer->dev_addr));
+               WDS_LOGD("Failed to send provision discovery request to peer [" MACSECSTR "]",
+                                                                       MAC2SECSTR(peer->dev_addr));
                wfd_destroy_session(manager);
                // TODO: send notification to App
                __WDS_LOG_FUNC_EXIT__;
@@ -246,6 +283,7 @@ int wfd_session_start(wfd_session_s *session)
        return 0;
 }
 
+#if 0
 int wfd_session_stop(wfd_session_s *session)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -279,6 +317,7 @@ int wfd_session_stop(wfd_session_s *session)
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif
 
 /* In case of incomming session, when user accept connection request, this function should be called.
  * In case of outgoing session, when prov_disc response arrived, this function should be called.
@@ -299,10 +338,12 @@ int wfd_session_connect(wfd_session_s *session)
        }
 
        if (session->state > SESSION_STATE_GO_NEG) {
-               WDS_LOGE("Session already starts GO Negotiation");
+               WDS_LOGE("Session already finished GO Negotiation");
                return -1;
        }
 
+       wfd_oem_stop_scan(manager->oem_ops);
+
        session->state = SESSION_STATE_GO_NEG;
        peer = session->peer;
 
@@ -312,16 +353,17 @@ int wfd_session_connect(wfd_session_s *session)
                param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
        param.go_intent = session->go_intent;
        param.freq = session->freq;
+       if(manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
+               param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
+
        if (session->wps_pin[0] != '\0') {
-               strncpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN);
-               param.wps_pin[OEM_PINSTR_LEN] = '\0';
+               g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
        }
 
        res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, &param);
        if (res < 0) {
-               WDS_LOGE("Failed to connect peer [" MACSTR "]", MAC2STR(peer->dev_addr));
+               WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
                wfd_destroy_session(manager);
-               // TODO: send notification to App
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
@@ -349,7 +391,7 @@ int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
                return WIFI_DIRECT_ERROR_NOT_PERMITTED;
        }
 
-       if (session->state > SESSION_STATE_GO_NEG)
+       if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
                res = wfd_oem_wps_cancel(manager->oem_ops);
        else
                res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
@@ -372,28 +414,32 @@ int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
        wfd_device_s *peer = NULL;
        int res = 0;
 
-       if (!session) {
+       if (!session || !manager) {
                WDS_LOGE("Invalid parameter");
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
 
-       if (session->state < SESSION_STATE_STARTED) {
-               WDS_LOGE("Session is not started");
+       /* Invite received case state is just created */
+       if (session->state < SESSION_STATE_CREATED ||
+               session->state >= SESSION_STATE_STOPPED) {
+               WDS_LOGE("Session state is Invalid [%d]", session->state);
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
 
-       if (session->direction != SESSION_DIRECTION_INCOMING) {
-               WDS_LOGE("Cannot reject with outgoing connection");
-               __WDS_LOG_FUNC_EXIT__;
-               return -1;
-       }
+       /*
+        * TODO: check session status and do proper work
+        * for example, reject prov_disc, reject nego, stop wps, etc.
+        *
+        */
 
-       // TODO: check session status and do proper work
-       // for example, reject prov_disc, reject nego, stop wps, etc.
        peer = session->peer;
-       res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
+
+       if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
+               res = wfd_oem_wps_cancel(manager->oem_ops);
+       else
+               res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
        if (res < 0) {
                WDS_LOGE("Failed to reject connection");
                __WDS_LOG_FUNC_EXIT__;
@@ -430,13 +476,12 @@ int wfd_session_join(wfd_session_s *session)
                param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
        param.go_intent = session->go_intent;
        param.freq = session->freq;
-       memcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN);
+       g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
 
        res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, &param);
        if (res < 0) {
-               WDS_LOGE("Failed to join with peer [" MACSTR "]", MAC2STR(peer->dev_addr));
+               WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
                wfd_destroy_session(manager);
-               // TODO: send notification to App
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
@@ -462,6 +507,11 @@ int wfd_session_invite(wfd_session_s *session)
                return -1;
        }
 
+       if (session->state > SESSION_STATE_CREATED) {
+               WDS_LOGE("Invalid session state(%d)", session->state);
+               return -1;
+       }
+
        peer = session->peer;
        group = (wfd_group_s*) manager->group;
 
@@ -469,13 +519,13 @@ int wfd_session_invite(wfd_session_s *session)
        param.ifname = strdup(group->ifname);
        memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
 
-       WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]", MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
+       WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
+                               MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
 
        res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, &param);
        if (res < 0) {
-               WDS_LOGE("Failed to invite with peer [" MACSTR "]", MAC2STR(peer->dev_addr));
+               WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
                wfd_destroy_session(manager);
-               // TODO: send notification to App
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
@@ -512,12 +562,17 @@ int wfd_session_wps(wfd_session_s *session)
                res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
        } else {
                WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
-               res = wfd_oem_enrollee_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
+               wfd_oem_conn_param_s param;
+               memset(&param, 0x00, sizeof(wfd_oem_conn_param_s));
+               param.wps_mode = session->wps_mode;
+               param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
+               param.freq = session->freq;     // currently not used
+               g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
+               res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, &param);
        }
        if (res < 0) {
-               WDS_LOGE("Failed to start wps with peer [" MACSTR "]", MAC2STR(peer->dev_addr));
+               WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
                wfd_destroy_session(manager);
-               // TODO: send notification to App
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
@@ -535,7 +590,7 @@ wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
                WDS_LOGE("Invalid parameter");
                return NULL;
        }
-       
+
        peer = session->peer;
 
        __WDS_LOG_FUNC_EXIT__;
@@ -551,13 +606,14 @@ unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
                WDS_LOGE("Invalid parameter");
                return NULL;
        }
-       
+
        peer = session->peer;
 
        __WDS_LOG_FUNC_EXIT__;
        return peer->dev_addr;
 }
 
+#if 0
 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -597,63 +653,78 @@ int wfd_session_set_state(wfd_session_s *session, int state)
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
+#endif
 
 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
 {
        __WDS_LOG_FUNC_ENTER__;
        wfd_session_s *session = NULL;
+       int res = 0;
 
        if (!manager || !event) {
                WDS_LOGE("Invalid parameter");
                return -1;
        }
 
-       wfd_dev_connection_flag_e flag = 0;
-       flag = wfd_manager_access_control(manager, event->dev_addr);
-
        WDS_LOGD("event ID [%d]", event->event_id);
        session = manager->session;
 
        switch (event->event_id) {
        case WFD_OEM_EVENT_PROV_DISC_REQ:
        {
-               if (session) {
-                       WDS_LOGE("Unexpected event. Session already exist. This request should be ignored");
-                       break;
+               int req_wps_mode = WFD_WPS_MODE_NONE;
+
+               if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
+                       req_wps_mode = WFD_WPS_MODE_KEYPAD;
+               } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
+                       req_wps_mode = WFD_WPS_MODE_DISPLAY;
+               } else {
+                       req_wps_mode = WFD_WPS_MODE_PBC;
                }
 
-               /* Create new session */
-               session = wfd_create_session(manager, event->dev_addr,
-                                               event->wps_mode, SESSION_DIRECTION_INCOMING);
-               if (!session) {
-                       WDS_LOGE("Failed to create session with peer [" MACSTR "]",
-                                               MAC2STR(event->dev_addr));
-                       break;
+               /* Only peer initiated connection or invitation session can be allowed */
+               if (session) {
+                       if (session->type != SESSION_TYPE_INVITE) {
+                               WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
+                                                               MAC2SECSTR(event->dev_addr));
+                               break;
+                       }
+                       WDS_LOGD("=====> session already exist. (invitation session)");
+               } else {
+                       session = wfd_create_session(manager, event->dev_addr,
+                                                               req_wps_mode, SESSION_DIRECTION_INCOMING);
+                       if (!session) {
+                               WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
+                                                               MAC2SECSTR(event->dev_addr));
+                               break;
+                       }
                }
 
                /* Update session */
-               if (event->wps_mode == WFD_OEM_WPS_MODE_DISPLAY) {
-                       strncpy(session->wps_pin, event->wps_pin, PINSTR_LEN);
-                       session->wps_pin[PINSTR_LEN] = '\0';
+               if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
+                       g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
                }
                session->state = SESSION_STATE_STARTED;
+               if (session->type == SESSION_TYPE_INVITE) {
+                       WDS_LOGD("Invitation session");
+               } else if (WFD_DEV_ROLE_GO == manager->local->dev_role) {
+                       session->type = SESSION_TYPE_JOIN;
+               } else {
+                       session->type = SESSION_TYPE_NORMAL;
+               }
                wfd_session_timer(session, 1);
 
-               /* Update manager */
+               /* Update local device */
                manager->local->wps_mode = event->wps_mode;
+
                wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
 
-               if(flag == WFD_DEV_ALLOWED)
-               {
-                       WDS_LOGD("device is allowed");
-                       if (manager->local->dev_role == WFD_DEV_ROLE_GO)
-                               wfd_session_wps(session);
-                       else
-                               wfd_session_connect(session);
-
-               }else {
-                       /* Send event to application */
-                       WDS_LOGD("device is not in access/deny list");
+               if (session->type == SESSION_TYPE_INVITE) {
+                       WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
+                       res = wfd_session_wps(session);
+                       if (res < 0)
+                               _wfd_notify_session_failed(manager, event->dev_addr);
+               } else {
                        wifi_direct_client_noti_s noti;
                        memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
                        noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
@@ -665,8 +736,9 @@ int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
        break;
        case WFD_OEM_EVENT_PROV_DISC_RESP:
        {
-               if (!session) {
-                       WDS_LOGE("Unexpected event. Session not exist. This response should be ignored");
+               if (!session) {         // TODO: check validity of Event
+                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
+                                                                               MAC2SECSTR(event->dev_addr));
                        break;
                }
 
@@ -676,79 +748,94 @@ int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
                }
 
                /* Update session */
-               if (event->wps_mode == WFD_OEM_WPS_MODE_DISPLAY) {
+               session->wps_mode = event->wps_mode;
+               if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
                        session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
-                       strncpy(session->wps_pin, event->wps_pin, PINSTR_LEN);
-                       session->wps_pin[PINSTR_LEN] = '\0';
-               } else if (event->wps_mode == WFD_OEM_WPS_MODE_KEYPAD) {
+                       g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
+               } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
                        session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
                } else {
                        session->req_wps_mode = WFD_WPS_MODE_PBC;
                }
-               session->wps_mode = event->wps_mode;
+               session->state = SESSION_STATE_STARTED;
                wfd_session_timer(session, 1);
 
-               /* Update manager */
+               /* Update local device */
                manager->local->wps_mode = event->wps_mode;
                WDS_LOGD("Local WPS mode is %d", session->wps_mode);
 
-               if (event->wps_mode != WFD_OEM_WPS_MODE_PBC) {
-                       /* Notify WPS_MODE to application so it can display PIN or KEYPAD */
+               if (session->wps_mode != WFD_WPS_MODE_PBC) {
                        wifi_direct_client_noti_s noti;
                        memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
                        noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_WPS_REQ;
-                       snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
+                       g_snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
                        wfd_client_send_event(manager, &noti);
-                       if (session->wps_mode == WFD_WPS_MODE_KEYPAD)
+                       if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
+                               /* We have to wait until user type PIN using Keypad */
                                break;
+                       }
                }
 
-               /* Go to next step of connection immediately */
-               if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
-                       WDS_LOGD("Start joining corresponding to OEM event [%d]", event->event_id);
-                       wfd_session_join(session);
-               } else if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
+               if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
                        WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
-                       wfd_session_wps(session);
+                       res = wfd_session_wps(session);
+               } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
+                       WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
+                       res = wfd_session_join(session);
                } else {
                        WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
-                       wfd_session_connect(session);
+                       res = wfd_session_connect(session);
                }
        }
+       if (res < 0)
+               _wfd_notify_session_failed(manager, event->dev_addr);
        break;
        case WFD_OEM_EVENT_GO_NEG_REQ:
-               if (!session) {         // TODO: check whether connection is started by negotiation not by prov_disc
-                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
+               if (!session) {
+                       // TODO: check whether connection is started by negotiation not by prov_disc
+                       WDS_LOGE("Unexpected event. Session not exist [peer: " MACSECSTR "]",
+                                               MAC2SECSTR(event->dev_addr));
                        break;
                } else {
                        /* Sometimes, Provision Discovery response is not received.
                         * At this time, connection should be triggered by GO Negotiation request event */
-                       if (session->direction == SESSION_DIRECTION_OUTGOING)
-                               wfd_session_connect(session);
+                       if (session->direction == SESSION_DIRECTION_OUTGOING) {
+                               res = wfd_session_connect(session);
+                       } else {
+                               /* In autoconnection mode, MT should not send GO Nego Req
+                                  before receving the GO Nego Req from peer (MO). */
+                               if (manager->autoconnection == TRUE)
+                                       res  = wfd_session_connect(session);
+                       }
+                       if (res < 0)
+                               _wfd_notify_session_failed(manager, event->dev_addr);
                }
                break;
        case WFD_OEM_EVENT_GO_NEG_DONE:
                if (!session) {
-                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
+                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
+                                               MAC2SECSTR(event->dev_addr));
                        break;
                } else {
                        session->state = SESSION_STATE_WPS;
                }
-               
+
                break;
        case WFD_OEM_EVENT_WPS_DONE:
                if (!session) {
-                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
+                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
+                                               MAC2SECSTR(event->dev_addr));
                        break;
                } else {
                        session->state = SESSION_STATE_KEY_NEG;
                }
-               
+
                break;
        case WFD_OEM_EVENT_CONNECTED:
        {
                if (!session) {
-                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
+                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
+                                               MAC2SECSTR(event->dev_addr));
                        break;
                } else {
                        wfd_group_s *group = manager->group;
@@ -770,12 +857,13 @@ int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
        break;
        case WFD_OEM_EVENT_STA_CONNECTED:
                if (!session) {
-                       WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
+                       WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
+                                               MAC2SECSTR(event->dev_addr));
                        break;
                } else {
                        session->state = SESSION_STATE_COMPLETED;
                }
-               
+
                break;
        default:
                break;
index 407d576..f2d4c4c 100644 (file)
  */
 
 #include <stdio.h>
-
 #include <glib.h>
-
 #include <wifi-direct.h>
-#include <wifi-direct-internal.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-state.h"
 #include "wifi-direct-util.h"
 
-
 static char *_wfd_state_string(int state)
 {
        switch (state) {
@@ -63,6 +60,7 @@ static char *_wfd_state_string(int state)
        }
        
 }
+
 int wfd_state_set(wfd_manager_s *manager, int state)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -72,8 +70,9 @@ int wfd_state_set(wfd_manager_s *manager, int state)
                return -1;
        }
 
-       WDS_LOGD("wifi-direct-manager state set [%s] -> [%s]",
+       WDS_LOGI("wifi-direct-manager state set [%s] -> [%s]",
                                _wfd_state_string(manager->state), _wfd_state_string(state));
+
        manager->state = state;
 
        __WDS_LOG_FUNC_EXIT__;
old mode 100644 (file)
new mode 100755 (executable)
index f6d1518..05a9d2d
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
 #include <errno.h>
 
 #include <glib.h>
 
 #include <vconf.h>
-#include <app_service.h>
+#include <app_control.h>
 #include <wifi-direct.h>
-#include <wifi-direct-internal.h>
 
+#include "wifi-direct-ipc.h"
 #include "wifi-direct-manager.h"
 #include "wifi-direct-state.h"
 #include "wifi-direct-client.h"
 #include "wifi-direct-util.h"
+#include "wifi-direct-oem.h"
+#ifdef CTRL_IFACE_DBUS
+#include "wifi-direct-session.h"
+#endif /* CTRL_IFACE_DBUS */
 
 static int _txt_to_mac(char *txt, unsigned char *mac)
 {
@@ -54,14 +62,15 @@ static int _txt_to_mac(char *txt, unsigned char *mac)
 
        for (;;) {
                mac[i++] = (char) strtoul(txt, &txt, 16);
-               if (!*txt++ || i == 6)
+               if (i == MACADDR_LEN || !*txt++)
                        break;
        }
 
        if (i != MACADDR_LEN)
                return -1;
 
-       WDS_LOGD("Converted MAC address [" MACSTR "]", MAC2STR(mac));
+       WDS_LOGD("Converted MAC address [" MACSECSTR "]",
+                                       MAC2SECSTR(mac));
        return 0;
 }
 
@@ -71,17 +80,45 @@ static int _txt_to_ip(char *txt, unsigned char *ip)
 
        for (;;) {
                ip[i++] = (char) strtoul(txt, &txt, 10);
-               if (!*txt++ || i == 4)
+               if (i == IPADDR_LEN || !*txt++)
                        break;
        }
 
-       if (i != 4)
+       if (i != IPADDR_LEN)
                return -1;
 
-       WDS_LOGD("Converted IP address [" IPSTR "]", IP2STR(ip));
+       WDS_LOGD("Converted IP address [" IPSECSTR "]", IP2SECSTR(ip));
        return 0;
 }
 
+#if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
+int wfd_util_get_current_time(unsigned long *cur_time)
+{
+       struct timespec time;
+       int res;
+
+       errno = 0;
+       res = clock_gettime(CLOCK_REALTIME, &time);
+       if (!res) {
+               WDS_LOGD("Succeeded to get current real time");
+               *cur_time = time.tv_sec;
+               return 0;
+       }
+       WDS_LOGE("Failed to get current real time(%s)", strerror(errno));
+
+       errno = 0;
+       res = clock_gettime(CLOCK_MONOTONIC, &time);
+       if (!res) {
+               WDS_LOGD("Succeeded to get current system time");
+               *cur_time = time.tv_sec;
+               return 0;
+       }
+       WDS_LOGE("Failed to get current system time(%s)", strerror(errno));
+
+       return -1;
+}
+#endif
+
 gboolean wfd_util_execute_file(const char *file_path,
        char *const args[], char *const envs[])
 {
@@ -116,7 +153,6 @@ gboolean wfd_util_execute_file(const char *file_path,
                } else if (WIFCONTINUED(rv)) {
                        WDS_LOGD("continued");
                }
-
                return TRUE;
        }
 
@@ -124,10 +160,28 @@ gboolean wfd_util_execute_file(const char *file_path,
        return FALSE;
 }
 
+int wfd_util_channel_to_freq(int channel)
+{
+       if (channel < 1 || channel > 161 ||
+               (channel > 48 && channel < 149) ||
+               (channel > 14 && channel < 36)) {
+               WDS_LOGE("Unsupported channel[%d]", channel);
+               return -1;
+       }
+
+       if (channel >= 36)
+               return 5000 + 5*channel;
+       else if (channel == 14)
+               return 2484;
+       else
+               return 2407 + 5*channel;
+}
+
 int wfd_util_freq_to_channel(int freq)
 {
-       if (freq < 2412 || freq > 5825) {
-               WDS_LOGE("Invalid parameter");
+       if (freq < 2412 || freq > 5825 ||
+               (freq > 2484 && freq < 5180)) {
+               WDS_LOGE("Unsupported frequency[%d]", freq);
                return -1;
        }
 
@@ -151,16 +205,14 @@ int wfd_util_get_phone_name(char *phone_name)
                WDS_LOGE( "Failed to get vconf value for %s", VCONFKEY_SETAPPL_DEVICE_NAME_STR);
                return -1;
        }
-       strncpy(phone_name, name, DEV_NAME_LEN);
-       phone_name[DEV_NAME_LEN] = '\0';
-
+       g_strlcpy(phone_name, name, DEV_NAME_LEN + 1);
        WDS_LOGD( "[%s: %s]", VCONFKEY_SETAPPL_DEVICE_NAME_STR, phone_name);
-       free(name);
+       g_free(name);
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
-void _wfd_util_dev_name_changed_cb(keynode_t *key, voiddata)
+void _wfd_util_dev_name_changed_cb(keynode_t *key, void *data)
 {
        __WDS_LOG_FUNC_ENTER__;
        char dev_name[DEV_NAME_LEN+1] = {0, };
@@ -183,8 +235,13 @@ void _wfd_util_dev_name_changed_cb(keynode_t *key, void* data)
 void wfd_util_set_dev_name_notification()
 {
        __WDS_LOG_FUNC_ENTER__;
+       int res = 0;
 
-       vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb, NULL);
+       res = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb, NULL);
+       if (res) {
+               WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
+               return;
+       }
 
        __WDS_LOG_FUNC_EXIT__;
        return;
@@ -193,13 +250,101 @@ void wfd_util_set_dev_name_notification()
 void wfd_util_unset_dev_name_notification()
 {
        __WDS_LOG_FUNC_ENTER__;
+       int res = 0;
+
+       res = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb);
+       if (res) {
+               WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
+               return;
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return;
+}
+
+
+void _wfd_util_check_country_cb(keynode_t *key, void *data)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_manager_s *manager = (wfd_manager_s*) data;
+       int res = 0;
+       int plmn = 0;
+       char mcc[4] = {0, };
+       char *ccode;
+       GKeyFile *keyfile = NULL;
+       GError * err = NULL;
 
-       vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb);
+       if (!manager) {
+               WDS_LOGE("Invalid parameter");
+               return;
+       }
+
+       res = vconf_get_int(VCONFKEY_TELEPHONY_PLMN, &plmn);
+       if (res) {
+               WDS_LOGE("Failed to get vconf value for PLMN(%d)", res);
+               return;
+       }
+
+       snprintf(mcc, 4, "%d", plmn);
+
+       keyfile = g_key_file_new();
+       res = g_key_file_load_from_file(keyfile, COUNTRY_CODE_FILE, 0, &err);
+       if (!res) {
+               WDS_LOGE("Failed to load key file(%s)", err->message);
+               g_key_file_free(keyfile);
+               return;
+       }
+
+       ccode = g_key_file_get_string(keyfile, "ccode_map", mcc, &err);
+       if (!ccode) {
+               WDS_LOGE("Failed to get country code string(%s)", err->message);
+               return;
+       }
+
+       res = wfd_oem_set_country(manager->oem_ops, ccode);
+       if (res < 0) {
+               WDS_LOGE("Failed to set contry code");
+               return;
+       }
+       WDS_LOGD("Succeeded to set country code(%s)", ccode);
 
        __WDS_LOG_FUNC_EXIT__;
        return;
 }
 
+int wfd_util_set_country()
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_manager_s *manager = wfd_get_manager();
+       int res = 0;
+
+       _wfd_util_check_country_cb(NULL, manager);
+
+       res = vconf_notify_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb, manager);
+       if (res) {
+               WDS_LOGE("Failed to set vconf notification callback(TELEPHONY_PLMN)");
+               return -1;
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int wfd_util_unset_country()
+{
+       __WDS_LOG_FUNC_ENTER__;
+       int res = 0;
+
+       res = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb);
+       if (res) {
+               WDS_LOGE("Failed to unset vconf notification callback(TELEPHONY_PLMN)");
+               return -1;
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+
 int wfd_util_check_wifi_state()
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -250,7 +395,8 @@ int wfd_util_check_mobile_ap_state()
        }
        WDS_LOGD("[%s: %d]", VCONFKEY_MOBILE_HOTSPOT_MODE, mobile_ap_state);
 
-       if (mobile_ap_state != VCONFKEY_MOBILE_HOTSPOT_MODE_NONE) {
+       if ((mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)
+               || (mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP) ) {
                WDS_LOGD("Mobile AP is on");
                __WDS_LOG_FUNC_EXIT__;
                return 1;
@@ -264,33 +410,43 @@ int wfd_util_check_mobile_ap_state()
 int wfd_util_wifi_direct_activatable()
 {
        __WDS_LOG_FUNC_ENTER__;
-       int res = 0;
 
-       res = wfd_util_check_wifi_state();
-       if (res < 0) {
+#ifndef TIZEN_WLAN_CONCURRENT_ENABLE
+       int res_wifi = 0;
+
+       res_wifi = wfd_util_check_wifi_state();
+       if (res_wifi < 0) {
                WDS_LOGE("Failed to check Wi-Fi state");
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
-       } else if (res > 0) {
+       } else if (res_wifi > 0) {
                WDS_LOGE("Wi-Fi is On");
                return WIFI_DIRECT_ERROR_WIFI_USED;
        } else {
                WDS_LOGE("Wi-Fi is Off");
                return WIFI_DIRECT_ERROR_NONE;
        }
+#endif
 
-       res = wfd_util_check_mobile_ap_state();
-       if (res < 0) {
+#if defined TIZEN_TETHERING_ENABLE
+       int res_mobap = 0;
+
+       res_mobap = wfd_util_check_mobile_ap_state();
+       if (res_mobap < 0) {
                WDS_LOGE("Failed to check Mobile AP state");
                return WIFI_DIRECT_ERROR_OPERATION_FAILED;
-       } else if (res > 0) {
+       } else if (res_mobap > 0) {
                WDS_LOGE("Mobile AP is On");
                return WIFI_DIRECT_ERROR_MOBILE_AP_USED;
        } else {
                WDS_LOGE("Mobile AP is Off");
                return WIFI_DIRECT_ERROR_NONE;
        }
+#endif
+
+       return WIFI_DIRECT_ERROR_NONE;
 }
 
+#if 0
 int wfd_util_get_wifi_direct_state()
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -307,6 +463,7 @@ int wfd_util_get_wifi_direct_state()
        __WDS_LOG_FUNC_EXIT__;
        return state;
 }
+#endif
 
 int wfd_util_set_wifi_direct_state(int state)
 {
@@ -326,6 +483,10 @@ int wfd_util_set_wifi_direct_state(int state)
                vconf_state = VCONFKEY_WIFI_DIRECT_GROUP_OWNER;
        else if (state == WIFI_DIRECT_STATE_DISCOVERING)
                vconf_state = VCONFKEY_WIFI_DIRECT_DISCOVERING;
+       else {
+               WDS_LOGE("This state cannot be set as wifi_direct vconf state[%d]", state);
+               return 0;
+       }
        WDS_LOGD("Vconf key set [%s: %d]", VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
 
        res = vconf_set_int(VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
@@ -363,7 +524,7 @@ int wfd_util_get_local_dev_mac(unsigned char *dev_mac)
                __WDS_LOG_FUNC_EXIT__;
                return -1;
        }
-       WDS_LOGD("Local MAC address [%s]", ptr);
+       WDS_SECLOGD("Local MAC address [%s]", ptr);
 
        res = _txt_to_mac(local_mac, dev_mac);
        if (res < 0) {
@@ -374,177 +535,76 @@ int wfd_util_get_local_dev_mac(unsigned char *dev_mac)
        }
 
        dev_mac[0] |= 0x2;
-       WDS_LOGD("Local Device MAC address [" MACSTR "]", MAC2STR(dev_mac));
+       WDS_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(dev_mac));
 
        fclose(fd);
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
-int wfd_util_get_access_list(GList **access_list)
+int wfd_util_start_wifi_direct_popup()
 {
        __WDS_LOG_FUNC_ENTER__;
 
-       wfd_access_list_info_s * device = NULL;
-       char device_info[MACSTR_LEN + DEV_NAME_LEN + 1] = {0, };
-       char dev_mac[MACADDR_LEN] = {0, };
-       int info_str_len = 0;
-
-       FILE *fd = NULL;
-       int res = 0;
-
-
-       fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "r");
-       if (!fd) {
-               WDS_LOGE("Failed to open access list file (%s)", strerror(errno));
-               __WDS_LOG_FUNC_EXIT__;
+       app_control_h control = NULL;
+       if (APP_CONTROL_ERROR_NONE != app_control_create(&control)) {
+               WDS_LOGE("App control create Failed !");
                return -1;
        }
-
-       while (fgets(device_info, MACSTR_LEN + DEV_NAME_LEN + 2, fd) != NULL)
-       {
-               if (device_info[0] == '\0') {
-                       printf("end of list\n");
-                       fclose(fd);
-                       return 0;
-               }
-
-               info_str_len = strlen(device_info);
-               if(info_str_len > MACSTR_LEN)
-                       device_info[info_str_len -1] = '\0';
-
-               res = _txt_to_mac(device_info, dev_mac);
-               if (res < 0) {
-                       WDS_LOGE("Failed to convert text to MAC address");
-                       continue;
-               }
-
-               device = calloc(1, sizeof(wfd_access_list_info_s));
-               memcpy(device->mac_address, dev_mac, MACADDR_LEN);
-               strncpy(device->device_name, &device_info[MACSTR_LEN], strlen(&device_info[MACSTR_LEN]));
-               device->allowed = (device_info[MACSTR_LEN - 1] == 'O');
-
-               *access_list = g_list_append(*access_list, device);
-       }
-       fclose(fd);
-       __WDS_LOG_FUNC_EXIT__;
-       return 0;
-}
-
-int wfd_util_rewrite_device_list_to_file(GList *access_list)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       FILE *fd = NULL;
-       GList *temp = NULL;
-       wfd_access_list_info_s * device = NULL;
-
-       int list_cnt =0;
-       char * buf = NULL;
-       char * ptr = NULL;
-
-       int res = 0;
-       int i;
-
-       list_cnt =  g_list_length(access_list);
-
-       fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "w");
-       if (!fd) {
-               WDS_LOGE("Failed to open access list file (%s)", strerror(errno));
-               free(buf);
-               __WDS_LOG_FUNC_EXIT__;
+       if (APP_CONTROL_ERROR_NONE != app_control_set_operation(control,
+               APP_CONTROL_OPERATION_DEFAULT)) {
+               WDS_LOGE("App control set operation Failed !");
+               app_control_destroy(control);
                return -1;
        }
-       if(list_cnt > 0)
-       {
-               buf = calloc(1,(MACSTR_LEN + DEV_NAME_LEN + 1)*list_cnt +1);
-               ptr = buf;
-               temp = g_list_first(access_list);
-
-               for(i =0; i < list_cnt; i++)
-               {
-                       device = (wfd_access_list_info_s *)temp->data;
-                       snprintf(ptr, MACSTR_LEN + DEV_NAME_LEN + 2, MACSTR "%c%s\n",
-                                         MAC2STR(device->mac_address), device->allowed?'O':'X', device->device_name);
-                       ptr+=strlen(ptr);
-                       temp = g_list_next(temp);
-               }
-               res = fprintf(fd, "%s",buf);
-       }
-
-       fclose(fd);
-       if(buf != NULL)
-               free(buf);
-       __WDS_LOG_FUNC_EXIT__;
-       return res;
-}
-
-int wfd_util_add_device_to_list(wfd_device_s *peer, int allowed)
-{
-       __WDS_LOG_FUNC_ENTER__;
-       FILE *fd = NULL;
-       char buf[MACSTR_LEN + DEV_NAME_LEN + 2] = {0, };
-       int res = 0;
-
-       if(peer == NULL)
-       {
-               WDS_LOGD("There is nothing to add to list");
+       if (APP_CONTROL_ERROR_NONE != app_control_set_app_id(control,
+               "org.tizen.wifi-direct-popup")) {
+               WDS_LOGE("App control set app id Failed !");
+               app_control_destroy(control);
                return -1;
        }
-
-       snprintf(buf, MACSTR_LEN + DEV_NAME_LEN + 2, MACSTR "%c%s\n",
-                       MAC2STR(peer->dev_addr), allowed?'O':'X', peer->dev_name);
-
-       fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "a");
-       if (!fd) {
-               WDS_LOGE("Failed to open access list file (%s)", strerror(errno));
-               __WDS_LOG_FUNC_EXIT__;
+       if (APP_CONTROL_ERROR_NONE !=
+               app_control_send_launch_request(control, NULL, NULL)) {
+               WDS_LOGE("App control send launch request Failed !");
                return -1;
        }
-       res = fprintf(fd,"%s", buf);
-
-       if(res < 0)
-               WDS_LOGE("Failed to write to access list file (%s)", strerror(errno));
 
-       fclose(fd);
+       app_control_destroy(control);
+       WDS_LOGD("Succeeded to launch wifi-direct-popup");
        __WDS_LOG_FUNC_EXIT__;
-       return res;
+       return 0;
 }
 
-int wfd_util_reset_access_list_file()
+int _connect_remote_device(char *ip_str)
 {
-       __WDS_LOG_FUNC_ENTER__;
-       int res = 0;
+       int sock;
+       int flags;
+       struct sockaddr_in remo_addr;
 
-       FILE *fd = NULL;
-       fd = fopen(DEFAULT_DEVICE_LIST_FILE_PATH, "w");
-
-       if (!fd) {
-               WDS_LOGE("Failed to open reset access list file (%s)", strerror(errno));
-               res = -1;
+       errno = 0;
+       sock = socket(PF_INET, SOCK_STREAM, 0);
+       if (sock == -1) {
+               WDS_LOGE("Failed to create socket to remote device(%s)", strerror(errno));
+               return -1;
        }
-       fclose(fd);
 
-       __WDS_LOG_FUNC_EXIT__;
-       return 0;
+       flags = fcntl(sock, F_GETFL, 0);
+       fcntl(sock, F_SETFL, flags | O_NONBLOCK);
 
-}
+       memset(&remo_addr, 0x0, sizeof(remo_addr));
+       remo_addr.sin_family = AF_INET;
+       remo_addr.sin_addr.s_addr = inet_addr(ip_str);
+       remo_addr.sin_port = htons(9999);
 
-int wfd_util_start_wifi_direct_popup()
-{
-       __WDS_LOG_FUNC_ENTER__;
+       errno = 0;
+       connect(sock, (struct sockaddr*) &remo_addr, sizeof(remo_addr));
+       WDS_SECLOGD("Status of connection to remote device[%s] - (%s)", ip_str, strerror(errno));
+
+       close(sock);
 
-       service_h service;
-       service_create(&service);
-       service_set_operation(service, SERVICE_OPERATION_DEFAULT);
-       service_set_package(service, "org.tizen.wifi-direct-popup");
-       service_send_launch_request(service, NULL, NULL);
-       service_destroy(service);
-       WDS_LOGD("Succeeded to launch wifi-direct-popup");
-       __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
 
-
 static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -553,7 +613,7 @@ static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
        wifi_direct_client_noti_s noti;
        FILE *fp = NULL;
        char buf[MAX_DHCP_DUMP_SIZE];
-       char ip_str[IPSTR_LEN];
+       char ip_str[IPSTR_LEN] = {0, };
        char intf_str[MACSTR_LEN];
        unsigned char intf_addr[MACADDR_LEN];
        int n = 0;
@@ -583,17 +643,22 @@ static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
                if (!memcmp(peer->intf_addr, intf_addr, MACADDR_LEN)) {
                        WDS_LOGD("Peer intf mac found");
                        _txt_to_ip(ip_str, peer->ip_addr);
+                       _connect_remote_device(ip_str);
                        noti.event = WIFI_DIRECT_CLI_EVENT_IP_LEASED_IND;
                        snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
                        snprintf(noti.param2, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
                        wfd_client_send_event(manager, &noti);
                        break;
                } else {
-                       WDS_LOGE("Different interface address peer[" MACSTR "] vs dhcp[" MACSTR "]", MAC2STR(peer->intf_addr), MAC2STR(intf_addr));
+                       WDS_LOGD("Different interface address peer[" MACSECSTR "] vs dhcp[" MACSECSTR "]",
+                                               MAC2SECSTR(peer->intf_addr), MAC2SECSTR(intf_addr));
                }
        }
        fclose(fp);
 
+       vconf_ignore_key_changed(VCONFKEY_DHCPS_IP_LEASE, _dhcps_ip_leased_cb);
+       vconf_set_int(VCONFKEY_DHCPS_IP_LEASE, 0);
+
        __WDS_LOG_FUNC_EXIT__;
        return;
 }
@@ -605,29 +670,36 @@ static gboolean _polling_ip(gpointer user_data)
        wfd_device_s *local = (wfd_device_s*) manager->local;
        wfd_device_s *peer = (wfd_device_s*) user_data;
        char *ifname = NULL;
+       char ip_str[IPSTR_LEN] = {0, };
        static int count = 0;
        int res = 0;
 
-       if (count > 28) {
-               WDS_LOGE("Failed to get IP");
-               count = 0;
-               __WDS_LOG_FUNC_EXIT__;
+       if (!peer) {
+               WDS_LOGE("peer data is not exists");
                return FALSE;
        }
+
        res = wfd_manager_get_goup_ifname(&ifname);
        if (res < 0 || !ifname) {
                WDS_LOGE("Failed to get group interface name");
                return FALSE;
        }
 
+       if (count > 28) {
+               WDS_LOGE("Failed to get IP");
+               count = 0;
+               wfd_oem_destroy_group(manager->oem_ops, ifname);
+               __WDS_LOG_FUNC_EXIT__;
+               return FALSE;
+       }
        res = wfd_util_dhcpc_get_ip(ifname, local->ip_addr, 0);
        if (res < 0) {
                WDS_LOGE("Failed to get local IP for interface %s(count=%d)", ifname, count++);
                __WDS_LOG_FUNC_EXIT__;
                return TRUE;
        }
-       WDS_LOGD("Succeeded to get local(client) IP [" IPSTR "] for iface[%s]",
-                                   IP2STR(local->ip_addr), ifname);
+       WDS_LOGD("Succeeded to get local(client) IP [" IPSECSTR "] for iface[%s]",
+                                   IP2SECSTR(local->ip_addr), ifname);
 
        res = wfd_util_dhcpc_get_server_ip(peer->ip_addr);
        if (res < 0) {
@@ -635,11 +707,18 @@ static gboolean _polling_ip(gpointer user_data)
                __WDS_LOG_FUNC_EXIT__;
                return TRUE;
        }
-       WDS_LOGD("Succeeded to get server IP [" IPSTR "]", IP2STR(peer->ip_addr));
+       WDS_LOGD("Succeeded to get server IP [" IPSECSTR "]", IP2SECSTR(peer->ip_addr));
        count = 0;
 
+       g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
+       _connect_remote_device(ip_str);
+
        wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
+#ifdef CTRL_IFACE_DBUS
+       wfd_destroy_session(manager);
+#endif /* CTRL_IFACE_DBUS */
+
        wifi_direct_client_noti_s noti;
        memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
        noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
@@ -667,6 +746,16 @@ int wfd_util_dhcps_start()
                WDS_LOGE("Failed to start wifi-direct-dhcp.sh server");
                return -1;
        }
+
+       /*
+        * As we are GO so IP should be updated
+        * before sending Group Created Event
+        */
+       vconf_set_str(VCONFKEY_IFNAME, GROUP_IFNAME     );
+       vconf_set_str(VCONFKEY_LOCAL_IP, "192.168.49.1");
+       vconf_set_str(VCONFKEY_SUBNET_MASK, "255.255.255.0");
+       vconf_set_str(VCONFKEY_GATEWAY, "192.168.49.1");
+
        WDS_LOGD("Successfully started wifi-direct-dhcp.sh server");
 
        __WDS_LOG_FUNC_EXIT__;
@@ -726,7 +815,6 @@ int wfd_util_dhcpc_start(wfd_device_s *peer)
        }
 
        rv = wfd_util_execute_file(path, args, envs);
-
        if (rv != TRUE) {
                WDS_LOGE("Failed to start wifi-direct-dhcp.sh client");
                return -1;
@@ -785,8 +873,8 @@ int wfd_util_dhcpc_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6)
        }
 
        ifr.ifr_addr.sa_family = AF_INET;
-       memset(ifr.ifr_name, 0x00, 16);
-       strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
+       memset(ifr.ifr_name, 0x00, IFNAMSIZ);
+       g_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
 
        errno = 0;
        res = ioctl(sock, SIOCGIFADDR, &ifr);
@@ -801,7 +889,6 @@ int wfd_util_dhcpc_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6)
        sin = (struct sockaddr_in*) &ifr.ifr_broadaddr;
        ip_str = inet_ntoa(sin->sin_addr);
        _txt_to_ip(ip_str, ip_addr);
-
        __WDS_LOG_FUNC_EXIT__;
        return 0;
 }
@@ -825,6 +912,13 @@ int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr)
                        __WDS_LOG_FUNC_EXIT__;
                        return -1;
                }
+
+               if(strcmp(get_str, ZEROIP) == 0) {
+                       WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_DHCPC_SERVER_IP);
+                       __WDS_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+
                WDS_LOGD("VCONFKEY_DHCPC_SERVER_IP(%s) : %s\n", VCONFKEY_DHCPC_SERVER_IP, get_str);
                _txt_to_ip(get_str, ip_addr);
                if (*ip_addr)
@@ -836,3 +930,39 @@ int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr)
        return 0;
 }
 
+int wfd_util_get_local_ip(unsigned char* ip_addr)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       char* get_str = NULL;
+       int count = 0;
+
+       if (!ip_addr) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       while(count < 10) {
+               get_str = vconf_get_str(VCONFKEY_LOCAL_IP);
+               if (!get_str) {
+                       WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_LOCAL_IP);
+                       __WDS_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+
+               if(strcmp(get_str, ZEROIP) == 0) {
+                       WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_LOCAL_IP);
+                       __WDS_LOG_FUNC_EXIT__;
+                       return -1;
+               }
+
+               WDS_LOGD("VCONFKEY_DHCPC_SERVER_IP(%s) : %s\n", VCONFKEY_LOCAL_IP, get_str);
+               _txt_to_ip(get_str, ip_addr);
+               if (*ip_addr)
+                       break;
+               count++;
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
index 97e8c31..b57e123 100644 (file)
@@ -1,5 +1,30 @@
 <manifest>
+       <define>
+               <domain name="wifi-direct" policy="restricted" plist="wifi-direct-plugin-wpasupplicant"/>
+                       <provide>
+                               <label name="wifi-direct::admin"/>
+                               <label name="wifi-direct::discover"/>
+                               <label name="wifi-direct::info"/>
+                               <label name="wifi-direct::native"/>
+                       </provide>
+               <permit>
+                       <smack permit="system::use_internet" type="w"/>
+               </permit>
+               <request>
+                       <smack request="net-config" type="rw"/>
+                       <smack request="security-server::api-privilege-by-pid" type="w"/>
+                       <smack request="system::use_internet" type="rw"/>
+                       <smack request="dbus" type="rwx"/>
+                       <smack request="wpasupplicant" type="rwx"/>
+               </request>
+       </define>
+       <assign>
+               <filesystem path="/usr/bin/wifi-direct-server.sh" label="_" exec_label="none" />
+               <filesystem path="/usr/bin/wifi-direct-dhcp.sh" label="_" exec_label="none" />
+               <filesystem path="/usr/bin/dhcpd-notify.sh" label="_" exec_label="none" />
+               <filesystem path="/usr/sbin/p2p_supp.sh" label="_" exec_label="none" />
+       </assign>
        <request>
-               <domain name="_"/>
+               <domain name="wifi-direct"/>
        </request>
 </manifest>
index 97e8c31..4cde07a 100644 (file)
@@ -1,5 +1,9 @@
 <manifest>
        <request>
-               <domain name="_"/>
+               <domain name="wifi-direct"/>
        </request>
+       <assign>
+               <filesystem path="/usr/lib/wifi-direct-plugin-wpasupplicant.so" label="_"/>
+               <filesystem path="/usr/sbin/wpa_supplicant" label="_"/>
+       </assign>
 </manifest>