From 916f248959f6aeb4ba23b6a98d2d0aec8eb5084c Mon Sep 17 00:00:00 2001 From: Yu Jiung Date: Fri, 19 Jun 2015 20:51:37 +0900 Subject: [PATCH] [wifi-direct-manager]Merge Tizen 2.4 for sync Change-Id: I15c95401cb76cf8c521facc272e64564783956b8 Signed-off-by: Yu jiung --- AUTHORS | 3 +- CMakeLists.txt | 59 +- files/ccode.conf | 237 ++ files/dhcpd-notify.sh | 4 +- files/dhcpd.p2p.conf | 4 +- files/p2p_supp.conf | 4 +- files/p2p_supp.sh | 71 +- files/p2p_supp_tv.conf | 15 + files/{access_list => persistent-peer} | 0 files/udhcp_script.non-autoip | 26 +- files/wifi-direct-dhcp.sh | 57 +- files/wifi-direct-server.sh | 6 +- include/wifi-direct-client.h | 3 +- include/wifi-direct-group.h | 18 +- include/wifi-direct-ipc.h | 307 ++ include/wifi-direct-manager.h | 121 +- include/wifi-direct-peer.h | 7 +- include/wifi-direct-service.h | 87 + include/wifi-direct-session.h | 3 + include/wifi-direct-util.h | 45 +- oem/wifi-direct-oem.c | 138 +- oem/wifi-direct-oem.h | 250 +- packaging/wifi-direct-manager.changes | 143 - packaging/wifi-direct-manager.spec | 108 +- packaging/wifi-direct-manager.spec~ | 151 + plugin/wpasupplicant/CMakeLists.txt | 54 - .../wpasupplicant/ctrl_iface_dbus/CMakeLists.txt | 30 + .../dbus/wfd-plugin-supplicant-dbus.c | 180 + .../dbus/wfd-plugin-supplicant-dbus.h | 79 + .../ctrl_iface_dbus/include/wfd-plugin-log.h | 67 + .../include/wfd-plugin-wpasupplicant.h | 378 ++ .../ctrl_iface_dbus/wfd-plugin-wpasupplicant.c | 4304 ++++++++++++++++++++ .../wpasupplicant/ctrl_iface_sock/CMakeLists.txt | 28 + .../include}/wfd-plugin-wpasupplicant.h | 201 +- .../wfd-plugin-wpasupplicant.c | 2170 +++++++--- plugin/wpasupplicant/emul/CMakeLists.txt | 29 + .../emul/include/wfd-plugin-wpasupplicant.h | 133 + .../{ => emul}/wfd-plugin-wpasupplicant-emul.c | 101 +- src/wifi-direct-client.c | 1050 +++-- src/wifi-direct-event.c | 687 ++-- src/wifi-direct-group.c | 90 +- src/wifi-direct-manager.c | 934 ++--- src/wifi-direct-peer.c | 84 +- src/wifi-direct-service.c | 189 + src/wifi-direct-session.c | 292 +- src/wifi-direct-state.c | 9 +- src/wifi-direct-util.c | 488 ++- wifi-direct-manager.manifest | 27 +- wifi-direct-plugin-wpasupplicant.manifest | 6 +- 49 files changed, 10767 insertions(+), 2710 deletions(-) create mode 100644 files/ccode.conf mode change 100755 => 100644 files/dhcpd-notify.sh mode change 100755 => 100644 files/p2p_supp.sh create mode 100644 files/p2p_supp_tv.conf rename files/{access_list => persistent-peer} (100%) mode change 100755 => 100644 files/wifi-direct-dhcp.sh mode change 100755 => 100644 files/wifi-direct-server.sh create mode 100644 include/wifi-direct-ipc.h create mode 100644 include/wifi-direct-service.h mode change 100644 => 100755 include/wifi-direct-util.h delete mode 100644 packaging/wifi-direct-manager.changes mode change 100644 => 100755 packaging/wifi-direct-manager.spec create mode 100755 packaging/wifi-direct-manager.spec~ delete mode 100755 plugin/wpasupplicant/CMakeLists.txt create mode 100755 plugin/wpasupplicant/ctrl_iface_dbus/CMakeLists.txt create mode 100755 plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.c create mode 100644 plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.h create mode 100644 plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-log.h create mode 100755 plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-wpasupplicant.h create mode 100755 plugin/wpasupplicant/ctrl_iface_dbus/wfd-plugin-wpasupplicant.c create mode 100755 plugin/wpasupplicant/ctrl_iface_sock/CMakeLists.txt rename plugin/wpasupplicant/{ => ctrl_iface_sock/include}/wfd-plugin-wpasupplicant.h (77%) mode change 100644 => 100755 rename plugin/wpasupplicant/{ => ctrl_iface_sock}/wfd-plugin-wpasupplicant.c (61%) create mode 100755 plugin/wpasupplicant/emul/CMakeLists.txt create mode 100755 plugin/wpasupplicant/emul/include/wfd-plugin-wpasupplicant.h rename plugin/wpasupplicant/{ => emul}/wfd-plugin-wpasupplicant-emul.c (74%) mode change 100644 => 100755 src/wifi-direct-client.c create mode 100644 src/wifi-direct-service.c mode change 100644 => 100755 src/wifi-direct-util.c diff --git a/AUTHORS b/AUTHORS index 1b2f445..b4ce413 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ -Gibyoung Kim \ No newline at end of file +Gibyoung Kim +Maneesh Jain diff --git a/CMakeLists.txt b/CMakeLists.txt index b55e8ec..0625b9b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..e958ad9 --- /dev/null +++ b/files/ccode.conf @@ -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 diff --git a/files/dhcpd-notify.sh b/files/dhcpd-notify.sh old mode 100755 new mode 100644 index 9c2abfe..734fd20 --- a/files/dhcpd-notify.sh +++ b/files/dhcpd-notify.sh @@ -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 diff --git a/files/dhcpd.p2p.conf b/files/dhcpd.p2p.conf index fd3c04e..41545ac 100644 --- a/files/dhcpd.p2p.conf +++ b/files/dhcpd.p2p.conf @@ -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 diff --git a/files/p2p_supp.conf b/files/p2p_supp.conf index 1456e09..bb4e500 100644 --- a/files/p2p_supp.conf +++ b/files/p2p_supp.conf @@ -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 diff --git a/files/p2p_supp.sh b/files/p2p_supp.sh old mode 100755 new mode 100644 index 8bba209..d185d28 --- a/files/p2p_supp.sh +++ b/files/p2p_supp.sh @@ -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 index 0000000..f7fee0e --- /dev/null +++ b/files/p2p_supp_tv.conf @@ -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 + diff --git a/files/access_list b/files/persistent-peer similarity index 100% rename from files/access_list rename to files/persistent-peer diff --git a/files/udhcp_script.non-autoip b/files/udhcp_script.non-autoip index bbab6e2..0163ac6 100644 --- a/files/udhcp_script.non-autoip +++ b/files/udhcp_script.non-autoip @@ -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 diff --git a/files/wifi-direct-dhcp.sh b/files/wifi-direct-dhcp.sh old mode 100755 new mode 100644 index 2cc81d3..68d6eb3 --- a/files/wifi-direct-dhcp.sh +++ b/files/wifi-direct-dhcp.sh @@ -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 } diff --git a/files/wifi-direct-server.sh b/files/wifi-direct-server.sh old mode 100755 new mode 100644 index a993eac..78c2fd5 --- a/files/wifi-direct-server.sh +++ b/files/wifi-direct-server.sh @@ -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 } diff --git a/include/wifi-direct-client.h b/include/wifi-direct-client.h index 7731a7f..fce1025 100644 --- a/include/wifi-direct-client.h +++ b/include/wifi-direct-client.h @@ -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 { diff --git a/include/wifi-direct-group.h b/include/wifi-direct-group.h index 716a8a4..27c1271 100644 --- a/include/wifi-direct-group.h +++ b/include/wifi-direct-group.h @@ -31,12 +31,6 @@ #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 index 0000000..b9878d3 --- /dev/null +++ b/include/wifi-direct-ipc.h @@ -0,0 +1,307 @@ +/* + * wifi-direct + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Sungsik Jang , Dongwook Lee + * + * 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_ */ diff --git a/include/wifi-direct-manager.h b/include/wifi-direct-manager.h index 8141552..2a78292 100644 --- a/include/wifi-direct-manager.h +++ b/include/wifi-direct-manager.h @@ -28,9 +28,15 @@ #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__ */ diff --git a/include/wifi-direct-peer.h b/include/wifi-direct-peer.h index 6dfd78d..283e7bf 100644 --- a/include/wifi-direct-peer.h +++ b/include/wifi-direct-peer.h @@ -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 index 0000000..6f84c03 --- /dev/null +++ b/include/wifi-direct-service.h @@ -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__ */ diff --git a/include/wifi-direct-session.h b/include/wifi-direct-session.h index 2d3eea9..df0d286 100644 --- a/include/wifi-direct-session.h +++ b/include/wifi-direct-session.h @@ -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); diff --git a/include/wifi-direct-util.h b/include/wifi-direct-util.h old mode 100644 new mode 100755 index efe96bf..d8fd124 --- a/include/wifi-direct-util.h +++ b/include/wifi-direct-util.h @@ -27,20 +27,32 @@ #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 @@ -55,8 +67,11 @@ #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 */ @@ -70,24 +85,31 @@ #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__ */ diff --git a/oem/wifi-direct-oem.c b/oem/wifi-direct-oem.c index 5c90b3f..c0dc8d0 100644 --- a/oem/wifi-direct-oem.c +++ b/oem/wifi-direct-oem.c @@ -28,57 +28,49 @@ #include #include - -#include - -#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(); } diff --git a/oem/wifi-direct-oem.h b/oem/wifi-direct-oem.h index eb315e6..e924173 100644 --- a/oem/wifi-direct-oem.h +++ b/oem/wifi-direct-oem.h @@ -32,10 +32,43 @@ #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_s 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 index d016a0d..0000000 --- a/packaging/wifi-direct-manager.changes +++ /dev/null @@ -1,143 +0,0 @@ -Fri, 14 Mar 2014 Jiung Yu (1.0.11) - * Modifiy Provision Discovery Request/Response Event - * Add automatic connection using device access list - -Fri, 07 Mar 2014 Jiung Yu (1.0.10) - * Add support for managing device access list - -Thu, 13 Feb 2014 Jiung Yu (1.0.9) - * Add Wifi Direct Display support - -Fri, 24 Jan 2014 Jiung Yu (1.0.8) - * Add Wifi Direct Service Discovery - -Tue, 15 Jan 2014 Jiung Yu (1.0.7) - * Replace file execution method - -Tue, 15 Jan 2014 Jiung Yu (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 (1.0.5) - * Change group function operation and parameter - -Tue, 15 Jan 2014 Jiung Yu (1.0.4) - * Delete event notify function - -Tue, 15 Jan 2014 Jiung Yu (1.0.3) - * Add wps_cancel operation - * Add session type and session management related operation - -Tue, 15 Jan 2014 Jiung Yu (1.0.2) - * Add update peer by time operation - -Tue, 15 Jan 2014 Jiung Yu (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 (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 (0.8.7) - * If device is GO, manager has wpa passphrase to handle WIFI_DIRECT_CMD_GET_WPA - - -Mon, 02 Sep 2013 Gibyoung Kim (0.8.6) - * Fix bug of display PIN - -Mon, 02 Sep 2013 Gibyoung Kim (0.8.5) - * Fix bug of join(Keypad) - -Wed, 28 Aug 2013 Gibyoung Kim (0.8.4) - * Macro is added for interface name - * Multi-group support is removed - -Thu, 22 Aug 2013 Gibyoung Kim (0.8.3) - * Reject connection process is modified - -Thu, 22 Aug 2013 Gibyoung Kim (0.8.2) - * Check socket before send message to wpasupplicant - -Wed, 21 Aug 2013 Gibyoung Kim (0.8.1) - * Invitation process is modified - -Wed, 21 Aug 2013 Gibyoung Kim (0.8.0) - * GET_CONFIG, SET_CURRENT_WPS_MODE API is modified(internally) - -Mon, 29 Jul 2013 Jiung Yu (0.7.11) - * add feature get_persistent_group - -Mon, 29 Jul 2013 Gibyoung Kim (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 (0.7.2) - * Add scan parameter - * fix bugs of disconnection(jiung) - * Remove not used files - -Thu, 20 Jun 2013 Gibyoung Kim (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 (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. diff --git a/packaging/wifi-direct-manager.spec b/packaging/wifi-direct-manager.spec old mode 100644 new mode 100755 index 7879207..bb9367b --- a/packaging/wifi-direct-manager.spec +++ b/packaging/wifi-direct-manager.spec @@ -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 index 0000000..7c88b15 --- /dev/null +++ b/packaging/wifi-direct-manager.spec~ @@ -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 index 0d904ba..0000000 --- a/plugin/wpasupplicant/CMakeLists.txt +++ /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 index 0000000..60b1077 --- /dev/null +++ b/plugin/wpasupplicant/ctrl_iface_dbus/CMakeLists.txt @@ -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 index 0000000..5ad4189 --- /dev/null +++ b/plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.c @@ -0,0 +1,180 @@ +#include +#include + +#include +#include + +#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 index 0000000..32d2607 --- /dev/null +++ b/plugin/wpasupplicant/ctrl_iface_dbus/dbus/wfd-plugin-supplicant-dbus.h @@ -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 index 0000000..a515aa5 --- /dev/null +++ b/plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-log.h @@ -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 + +#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 index 0000000..7d610ef --- /dev/null +++ b/plugin/wpasupplicant/ctrl_iface_dbus/include/wfd-plugin-wpasupplicant.h @@ -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 index 0000000..8bfff65 --- /dev/null +++ b/plugin/wpasupplicant/ctrl_iface_dbus/wfd-plugin-wpasupplicant.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#define _GNU_SOURCE +#include +#include +#include +#include + +#include +#include + +#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 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; idata.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; idata.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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "RemoveInterface", SUPPLICANT_PATH, g_dbus); + params.params = g_variant_new("(o)", interface_path); + + res = dbus_method_call(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "Flush", g_pd->iface_path, g_dbus); + params.params = NULL; + + res = dbus_method_call(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "Cancel", g_pd->iface_path , g_dbus); + params.params = NULL; + + res = dbus_method_call(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + if (param->scan_mode == WFD_OEM_SCAN_MODE_ACTIVE) { + + dbus_set_method_param(¶ms, "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(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "StopFind", g_pd->iface_path, g_dbus); + params.params = NULL; + + res = dbus_method_call(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "Disconnect", g_pd->group_iface_path, g_dbus); + params.params = NULL; + + res = dbus_method_call(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "Cancel", g_pd->group_iface_path, g_dbus); + params.params = NULL; + + res = dbus_method_call(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, 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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, 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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, 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(¶ms, 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;iiface_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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, 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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "ServiceDiscoveryCancelRequest", g_pd->iface_path, g_dbus); + + params.params = g_variant_new ("(t)", strtoul(query_id, NULL, 16)); + + res = dbus_method_call(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, "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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, 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(¶ms, 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(¶ms, 0x0, sizeof(dbus_method_param_s)); + + dbus_set_method_param(¶ms, 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(¶ms, 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 index 0000000..bd1747f --- /dev/null +++ b/plugin/wpasupplicant/ctrl_iface_sock/CMakeLists.txt @@ -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) diff --git a/plugin/wpasupplicant/wfd-plugin-wpasupplicant.h b/plugin/wpasupplicant/ctrl_iface_sock/include/wfd-plugin-wpasupplicant.h old mode 100644 new mode 100755 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 --- a/plugin/wpasupplicant/wfd-plugin-wpasupplicant.h +++ b/plugin/wpasupplicant/ctrl_iface_sock/include/wfd-plugin-wpasupplicant.h @@ -42,8 +42,11 @@ #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 */ @@ -57,34 +60,73 @@ #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 @@ -117,6 +159,7 @@ #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" @@ -125,22 +168,38 @@ #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__ */ diff --git a/plugin/wpasupplicant/wfd-plugin-wpasupplicant.c b/plugin/wpasupplicant/ctrl_iface_sock/wfd-plugin-wpasupplicant.c similarity index 61% rename from plugin/wpasupplicant/wfd-plugin-wpasupplicant.c rename to plugin/wpasupplicant/ctrl_iface_sock/wfd-plugin-wpasupplicant.c index fb9ba3b..49ea883 100644 --- a/plugin/wpasupplicant/wfd-plugin-wpasupplicant.c +++ b/plugin/wpasupplicant/ctrl_iface_sock/wfd-plugin-wpasupplicant.c @@ -29,9 +29,9 @@ #include #include #include +#include #include #include -#include #include #include #define _GNU_SOURCE @@ -41,10 +41,17 @@ #include #include +#include #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 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; idata.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; idata.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;ictrl_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; icommon; - 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;ictrl_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 index 0000000..d5a4a1b --- /dev/null +++ b/plugin/wpasupplicant/emul/CMakeLists.txt @@ -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 index 0000000..cdbff32 --- /dev/null +++ b/plugin/wpasupplicant/emul/include/wfd-plugin-wpasupplicant.h @@ -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 + +#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__ */ diff --git a/plugin/wpasupplicant/wfd-plugin-wpasupplicant-emul.c b/plugin/wpasupplicant/emul/wfd-plugin-wpasupplicant-emul.c similarity index 74% rename from plugin/wpasupplicant/wfd-plugin-wpasupplicant-emul.c rename to plugin/wpasupplicant/emul/wfd-plugin-wpasupplicant-emul.c index c9cf2be..80ee7bb 100644 --- a/plugin/wpasupplicant/wfd-plugin-wpasupplicant-emul.c +++ b/plugin/wpasupplicant/emul/wfd-plugin-wpasupplicant-emul.c @@ -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 */ diff --git a/src/wifi-direct-client.c b/src/wifi-direct-client.c old mode 100644 new mode 100755 index d05aba1..f3b11e1 --- a/src/wifi-direct-client.c +++ b/src/wifi-direct-client.c @@ -40,8 +40,9 @@ #include #include -#include +//#include +#include "wifi-direct-ipc.h" #include "wifi-direct-manager.h" #include "wifi-direct-oem.h" #include "wifi-direct-session.h" @@ -51,13 +52,20 @@ #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(¶m, 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, ¶m); + 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; } diff --git a/src/wifi-direct-event.c b/src/wifi-direct-event.c index 28a4228..abbc253 100644 --- a/src/wifi-direct-event.c +++ b/src/wifi-direct-event.c @@ -28,14 +28,15 @@ #include #include #include -#include #include +#include #include #include -#include +#include +#include "wifi-direct-ipc.h" #include "wifi-direct-manager.h" #include "wifi-direct-oem.h" #include "wifi-direct-peer.h" @@ -47,94 +48,6 @@ #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(¬i, 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, ¬i); + + // 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(¬i, 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, ¬i); @@ -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(¬i, 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, ¬i); + } + 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(¬i, 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, ¬i); - }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(¬i, 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, ¬i); +#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(¬i, 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(¬i, 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(¬i, 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, ¬i); + + 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(¬i, 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(¶m, 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, ¶m); 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(¬i, 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, ¬i); +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(¬i, 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, ¬i); } } break; +#endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */ + default: WDS_LOGE("Unknown event [event ID: %d]", event->event_id); break; diff --git a/src/wifi-direct-group.c b/src/wifi-direct-group.c index 1ac096b..ea92764 100644 --- a/src/wifi-direct-group.c +++ b/src/wifi-direct-group.c @@ -31,9 +31,11 @@ #include -#include +#include +#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" @@ -42,13 +44,14 @@ #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__; diff --git a/src/wifi-direct-manager.c b/src/wifi-direct-manager.c index 67b903d..7ed6e17 100644 --- a/src/wifi-direct-manager.c +++ b/src/wifi-direct-manager.c @@ -34,10 +34,9 @@ #include #include - #include -#include +#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, ¶m); - 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 */ diff --git a/src/wifi-direct-peer.c b/src/wifi-direct-peer.c index 6e6d9e6..8b845ac 100644 --- a/src/wifi-direct-peer.c +++ b/src/wifi-direct-peer.c @@ -27,11 +27,13 @@ #include #include +#include #include -#include +#include +#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 index 0000000..dfee6a0 --- /dev/null +++ b/src/wifi-direct-service.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include + +#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 diff --git a/src/wifi-direct-session.c b/src/wifi-direct-session.c index 5bc3abe..cc455a2 100644 --- a/src/wifi-direct-session.c +++ b/src/wifi-direct-session.c @@ -30,8 +30,9 @@ #include -#include +#include +#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(¬i, 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, ¬i); 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(¬i, 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, ¬i); + __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, ¶m); 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, ¶m); 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, ¶m); 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(¶m, 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, ¶m); } 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(¬i, 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(¬i, 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, ¬i); - 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; diff --git a/src/wifi-direct-state.c b/src/wifi-direct-state.c index 407d576..f2d4c4c 100644 --- a/src/wifi-direct-state.c +++ b/src/wifi-direct-state.c @@ -26,17 +26,14 @@ */ #include - #include - #include -#include +#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__; diff --git a/src/wifi-direct-util.c b/src/wifi-direct-util.c old mode 100644 new mode 100755 index f6d1518..05a9d2d --- a/src/wifi-direct-util.c +++ b/src/wifi-direct-util.c @@ -27,26 +27,34 @@ #include #include +#include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include -#include +#include #include -#include +#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, void* data) +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, ¬i); 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(¬i, 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; +} diff --git a/wifi-direct-manager.manifest b/wifi-direct-manager.manifest index 97e8c31..b57e123 100644 --- a/wifi-direct-manager.manifest +++ b/wifi-direct-manager.manifest @@ -1,5 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + - + diff --git a/wifi-direct-plugin-wpasupplicant.manifest b/wifi-direct-plugin-wpasupplicant.manifest index 97e8c31..4cde07a 100644 --- a/wifi-direct-plugin-wpasupplicant.manifest +++ b/wifi-direct-plugin-wpasupplicant.manifest @@ -1,5 +1,9 @@ - + + + + + -- 2.7.4