Add support for ASP session request/response 21/85221/1
authorYu Jiung <jiung.yu@samsung.com>
Wed, 24 Aug 2016 07:55:19 +0000 (16:55 +0900)
committerYu Jiung <jiung.yu@samsung.com>
Wed, 24 Aug 2016 07:55:37 +0000 (16:55 +0900)
Change-Id: I6ab1b3f29497ed8d90fb896bef63e9e184e76748
Signed-off-by: Yu jiung <jiung.yu@samsung.com>
CMakeLists.txt
include/wifi-direct-asp.h [new file with mode: 0644]
include/wifi-direct-manager.h
include/wifi-direct-session.h
packaging/wifi-direct-manager.spec
src/wifi-direct-asp.c [new file with mode: 0644]
src/wifi-direct-event.c
src/wifi-direct-iface.c
src/wifi-direct-manager.c
src/wifi-direct-session.c
src/wifi-direct-util.c

index aae3e95..bf97c0c 100644 (file)
@@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 PROJECT(wfd-manager C)
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED capi-network-wifi-direct glib-2.0 gio-2.0 gobject-2.0 dlog libnl-2.0 capi-appfw-application vconf aul libsystemd-login ${MDM_REQUIRED_PKGS})
+pkg_check_modules(pkgs REQUIRED capi-network-wifi-direct glib-2.0 gio-2.0 gobject-2.0 dlog libnl-2.0 capi-appfw-application vconf aul libsystemd-login libtzplatform-config ${MDM_REQUIRED_PKGS})
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
@@ -102,6 +102,10 @@ IF(TIZEN_FEATURE_SERVICE_DISCOVERY)
        SET(SRCS ${SRCS} ${CMAKE_SOURCE_DIR}/src/wifi-direct-service.c)
 ENDIF(TIZEN_FEATURE_SERVICE_DISCOVERY)
 
+IF(TIZEN_FEATURE_ASP)
+       SET(SRCS ${SRCS} ${CMAKE_SOURCE_DIR}/src/wifi-direct-asp.c)
+ENDIF(TIZEN_FEATURE_ASP)
+
 IF(TIZEN_ENABLE_PRD)
        SET(SRCS ${SRCS} ${CMAKE_SOURCE_DIR}/prd/src/wifi-direct-prd.c)
 ENDIF(TIZEN_ENABLE_PRD)
diff --git a/include/wifi-direct-asp.h b/include/wifi-direct-asp.h
new file mode 100644 (file)
index 0000000..624a8be
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2016 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 Application Service Platfrom(ASP) utility functions.
+ *
+ * @file        wifi-direct-asp.h
+ * @author      Jiung Yu (jiung.yu@samsung.com)
+ * @version     0.1
+ */
+
+#ifndef __WIFI_DIRECT_ASP_H__
+#define __WIFI_DIRECT_ASP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+       ASP_CONNECT_STATUS_NETWORK_ROLE_REJECTED,  /**< network role rejected */
+       ASP_CONNECT_STATUS_NOMORE_CONNECT,  /**< no more connect */
+       ASP_CONNECT_STATUS_REQUEST_SENT,  /**< session request sent */
+       ASP_CONNECT_STATUS_REQUEST_RECEIVED,  /**< session request received */
+       ASP_CONNECT_STATUS_REQUEST_DEFERRED,  /**< session request deferred */
+       ASP_CONNECT_STATUS_REQUEST_ACCEPTED,  /**< session request accepted */
+       ASP_CONNECT_STATUS_REQUEST_FAILED,  /**< session request failed */
+       ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,  /**< group formation started */
+       ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,  /**< group formation completed */
+       ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,  /**< group formation failed*/
+} asp_connect_status_e;
+
+void wfd_asp_session_request(wfd_oem_asp_prov_s *prov_param);
+void wfd_asp_session_config_request(unsigned int session_id, int get_pin, char *pin);
+void wfd_asp_connect_status(unsigned char *session_mac,
+               unsigned int session_id, int status, char *deferred);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WIFI_DIRECT_ASP_H__ */
index 04abeb3..acb4057 100644 (file)
@@ -252,5 +252,10 @@ int wfd_manager_set_session_availability(int availability);
 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 int wfd_manager_start_discovery(wfd_manager_s *manager, int mode, int timeout, const char* type, int channel);
 int wfd_manager_cancel_discovery(wfd_manager_s *manager);
+#if defined(TIZEN_FEATURE_ASP)
+wfd_device_s *wfd_manager_get_connected_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr);
+int wfd_manager_asp_connect_session(wfd_manager_s *manager, void *params);
+int wfd_manager_asp_confirm_session(wfd_manager_s *manager, void *params, int confirmed);
+#endif /* TIZEN_FEATURE_ASP */
 
 #endif /* __WIFI_DIRECT_MANAGER_H__ */
index df0d286..df32456 100644 (file)
@@ -33,6 +33,9 @@ typedef enum {
        SESSION_TYPE_INVITE,
        SESSION_TYPE_JOIN,
        SESSION_TYPE_MULTI,
+#if defined(TIZEN_FEATURE_ASP)
+       SESSION_TYPE_ASP,
+#endif /* TIZEN_FEATURE_ASP */
 } session_type_e;
 
 typedef enum {
@@ -63,6 +66,11 @@ typedef struct {
        int go_intent;
        int freq;
        char wps_pin[PINSTR_LEN+1];
+#if defined(TIZEN_FEATURE_ASP)
+       unsigned int session_id;
+       unsigned char service_mac[MACADDR_LEN];
+       unsigned char session_mac[MACADDR_LEN];
+#endif /* TIZEN_FEATURE_ASP */
 } wfd_session_s;
 
 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction);
@@ -84,5 +92,10 @@ int wfd_session_complete(wfd_session_s *session);
 int wfd_session_timer(wfd_session_s *session, int start);
 
 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event);
+#if defined(TIZEN_FEATURE_ASP)
+int wfd_session_asp_session_start(wfd_session_s *session, wfd_oem_asp_prov_s *params);
+int wfd_session_asp_connect(wfd_session_s *session, int role);
+int wfd_session_asp_persistent_connect(wfd_session_s *session, int persist_group_id);
+#endif /* TIZEN_FEATURE_ASP */
 
 #endif /* __WIFI_DIRECT_SESSION_H__ */
index d7e392e..cea7975 100644 (file)
@@ -1,6 +1,6 @@
 Name:          wifi-direct-manager
 Summary:       Wi-Fi Direct manger
-Version:       1.2.197
+Version:       1.2.198
 Release:       1
 Group:      Network & Connectivity/Wireless
 License:    Apache-2.0
diff --git a/src/wifi-direct-asp.c b/src/wifi-direct-asp.c
new file mode 100644 (file)
index 0000000..e0753c6
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2016 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 manager Application Service Platform(ASP) functions.
+ *
+ * @file        wifi-direct-asp.c
+ * @author      Jiung Yu (jiung.yu@samsung.com)
+ * @version     0.1
+ */
+
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include <wifi-direct.h>
+
+#include "wifi-direct-ipc.h"
+#include "wifi-direct-dbus.h"
+#include "wifi-direct-log.h"
+#include "wifi-direct-manager.h"
+#include "wifi-direct-oem.h"
+#include "wifi-direct-util.h"
+
+#include "wifi-direct-asp.h"
+
+void wfd_asp_session_request(wfd_oem_asp_prov_s *prov_param)
+{
+       GVariantBuilder *builder = NULL;
+       GVariant *parameter = NULL;
+       GVariant *get_pin = NULL;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       g_variant_builder_add(builder, "{sv}",
+                       "adv_id",
+                       g_variant_new_uint32(prov_param->adv_id));
+       g_variant_builder_add(builder, "{sv}",
+                       "session_mac",
+                       wfd_manager_dbus_pack_ay(prov_param->session_mac, MACADDR_LEN));
+       g_variant_builder_add(builder, "{sv}",
+                       "session_id",
+                       g_variant_new_uint32(prov_param->session_id));
+
+       if (prov_param->network_config == WFD_WPS_MODE_KEYPAD)
+               get_pin = g_variant_new_boolean(TRUE);
+       else
+               get_pin = g_variant_new_boolean(FALSE);
+       g_variant_builder_add(builder, "{sv}",
+                       "get_pin",
+                       get_pin);
+
+       if (prov_param->wps_pin[0])
+               g_variant_builder_add(builder, "{sv}",
+                               "pin",
+                               g_variant_new_string(prov_param->wps_pin));
+       parameter = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+
+       wfd_manager_dbus_emit_signal(WFD_MANAGER_ASP_INTERFACE, "SessionRequest", parameter);
+       return;
+}
+
+void wfd_asp_session_config_request(unsigned int session_id, int get_pin, char *pin)
+{
+       GVariantBuilder *builder = NULL;
+       GVariant *parameter = NULL;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       g_variant_builder_add(builder, "{sv}",
+                       "session_id",
+                       g_variant_new_uint32(session_id));
+       g_variant_builder_add(builder, "{sv}",
+                       "get_pin",
+                       g_variant_new_int32(get_pin));
+       if (pin)
+               g_variant_builder_add(builder, "{sv}",
+                               "pin",
+                               g_variant_new_string(pin));
+       parameter = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+
+       wfd_manager_dbus_emit_signal(WFD_MANAGER_ASP_INTERFACE, "SessionConfigRequest", parameter);
+       return;
+}
+
+void wfd_asp_connect_status(unsigned char *session_mac,
+               unsigned int session_id, int status, char *deferred)
+{
+       GVariantBuilder *builder = NULL;
+       GVariant *parameter = NULL;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       g_variant_builder_add(builder, "{sv}",
+                       "session_mac",
+                       wfd_manager_dbus_pack_ay(session_mac, MACADDR_LEN));
+       g_variant_builder_add(builder, "{sv}",
+                       "session_id",
+                       g_variant_new_uint32(session_id));
+       g_variant_builder_add(builder, "{sv}",
+                       "status",
+                       g_variant_new_int32(status));
+       if (deferred)
+               g_variant_builder_add(builder, "{sv}",
+                               "deferred",
+                               g_variant_new_string(deferred));
+       parameter = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+
+       wfd_manager_dbus_emit_signal(WFD_MANAGER_ASP_INTERFACE, "ConnectStatus", parameter);
+       return;
+}
index 153e1ac..0f8516e 100644 (file)
@@ -48,6 +48,9 @@
 #include "wifi-direct-error.h"
 #include "wifi-direct-log.h"
 #include "wifi-direct-dbus.h"
+#if defined(TIZEN_FEATURE_ASP)
+#include "wifi-direct-asp.h"
+#endif /* TIZEN_FEATURE_ASP */
 
 
 static int _wfd_event_update_peer(wfd_manager_s *manager, wfd_oem_dev_data_s *data)
@@ -413,6 +416,10 @@ void wfd_event_prov_disc_fail(wfd_oem_event_s *event)
        wfd_session_s *session = NULL;
        unsigned char *peer_addr = NULL;
        char peer_mac_address[MACSTR_LEN+1] = {0, };
+#if defined(TIZEN_FEATURE_ASP)
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       prov_params = (wfd_oem_asp_prov_s *)event->edata;
+#endif
 
        session = (wfd_session_s*) manager->session;
        if (!session) {
@@ -427,7 +434,26 @@ void wfd_event_prov_disc_fail(wfd_oem_event_s *event)
                __WDS_LOG_FUNC_EXIT__;
                return;
        }
-
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac)) {
+               /* This connection is for ASP session */
+               if (prov_params->status == WFD_OEM_SC_FAIL_INVALID_PARAMS) {
+                       wfd_oem_scan_param_s param;
+
+                       WDS_LOGD("ASP prov disc deferred. wait response.");
+                       wfd_asp_connect_status(session->session_mac,
+                                                               session->session_id,
+                                                               ASP_CONNECT_STATUS_REQUEST_DEFERRED,
+                                                               NULL);
+                       /* start listen to wait for provision discovery request from peer */
+                       memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
+                       param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
+                       wfd_oem_start_scan(manager->oem_ops, &param);
+                       __WDS_LOG_FUNC_EXIT__;
+                       return;
+               }
+       }
+#endif
        snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
        wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
                                     "Connection",
@@ -435,6 +461,13 @@ void wfd_event_prov_disc_fail(wfd_oem_event_s *event)
                                                   WIFI_DIRECT_ERROR_CONNECTION_FAILED,
                                                   WFD_EVENT_CONNECTION_RSP,
                                                   peer_mac_address));
+#if defined(TIZEN_FEATURE_ASP)
+       WDS_LOGD("ASP prov disc failed. remove session.");
+       wfd_asp_connect_status(session->session_mac,
+                                               session->session_id,
+                                               ASP_CONNECT_STATUS_REQUEST_FAILED,
+                                               NULL);
+#endif
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
                wfd_group_s *group = (wfd_group_s*) manager->group;
@@ -582,6 +615,14 @@ void wfd_event_go_neg_fail(wfd_oem_event_s *event)
                                                   WFD_EVENT_CONNECTION_RSP,
                                                   peer_mac_address));
 
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
+                                                       NULL);
+#endif
+
        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
 
@@ -651,7 +692,13 @@ void wfd_event_wps_fail(wfd_oem_event_s *event)
                                                   WIFI_DIRECT_ERROR_CONNECTION_FAILED,
                                                   WFD_EVENT_CONNECTION_RSP,
                                                   peer_mac_address));
-
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
+                                                       NULL);
+#endif
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
                wfd_group_s *group = (wfd_group_s*) manager->group;
                if (group && !group->member_count &&
@@ -727,7 +774,13 @@ void wfd_event_key_neg_fail(wfd_oem_event_s *event)
                                                   WIFI_DIRECT_ERROR_CONNECTION_FAILED,
                                                   WFD_EVENT_CONNECTION_RSP,
                                                   peer_mac_address));
-
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
+                                                       NULL);
+#endif
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
                wfd_group_s *group = (wfd_group_s*) manager->group;
                if (group && !group->member_count &&
@@ -828,7 +881,13 @@ void wfd_event_group_created(wfd_oem_event_s *event)
                                                     g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
                                                                            WFD_EVENT_CONNECTION_RSP,
                                                                            peer_mac_address));
-
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
+                                                       NULL);
+#endif
                        wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
                        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
 
@@ -874,7 +933,14 @@ void wfd_event_group_destroyed(wfd_oem_event_s *event)
                                             g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
                                                                    WFD_EVENT_CONNECTION_RSP,
                                                                    peer_mac_address));
-
+#if defined(TIZEN_FEATURE_ASP)
+               wfd_session_s *session = manager->session;
+               if (!ISZEROMACADDR(session->session_mac))
+                       wfd_asp_connect_status(session->session_mac,
+                                       session->session_id,
+                                       ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
+                                       NULL);
+#endif
        } else if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
                if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
                        wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
@@ -1092,6 +1158,13 @@ void wfd_event_sta_connected(wfd_oem_event_s *event)
                                     "PeerIPAssigned",
                                     g_variant_new("(ss)", peer_mac_address,
                                                           assigned_ip_address));
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
+                                                       NULL);
+#endif
        } else
 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
        wfd_util_dhcps_wait_ip_leased(peer);
@@ -1224,6 +1297,14 @@ void wfd_event_sta_disconnected(wfd_oem_event_s *event)
                                                     g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
                                                                            WFD_EVENT_CONNECTION_RSP,
                                                                            peer_mac_address));
+#if defined(TIZEN_FEATURE_ASP)
+                       wfd_session_s *session = manager->session;
+                       if (session && !ISZEROMACADDR(session->session_mac))
+                               wfd_asp_connect_status(session->session_mac,
+                                                                       session->session_id,
+                                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
+                                                                       NULL);
+#endif
                } else {
                        WDS_LOGE("Unexpected Peer State. Ignore it");
                        __WDS_LOG_FUNC_EXIT__;
@@ -1291,6 +1372,14 @@ void wfd_event_group_formation_failure(wfd_oem_event_s *event)
                                                            WFD_EVENT_CONNECTION_RSP,
                                                            peer_mac_address));
 
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
+                                                       NULL);
+#endif
+
        wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
        wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
        wfd_destroy_session(manager);
@@ -1475,10 +1564,120 @@ void wfd_event_asp_serv_resp(wfd_oem_event_s *event)
        return;
 }
 
+int __wfd_handle_asp_prov(wfd_manager_s *manager, wfd_oem_event_s *event)
+{
+       __WDS_LOG_FUNC_ENTER__;
+
+       wfd_session_s *session = NULL;
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       int res = 0;
+
+       prov_params = (wfd_oem_asp_prov_s *)event->edata;
+       if (prov_params == NULL) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       res = wfd_session_process_event(manager, event);
+       session = (wfd_session_s *)manager->session;
+       if (res < 0 || session == NULL) {
+               WDS_LOGE("Failed to process event of session");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+       session->session_id = prov_params->session_id;
+       memcpy(session->session_mac, prov_params->session_mac, MACADDR_LEN);
+       memcpy(session->service_mac, prov_params->service_mac, MACADDR_LEN);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+int __wfd_handle_asp_prov_done(wfd_session_s *session, wfd_oem_event_s *event)
+{
+       __WDS_LOG_FUNC_ENTER__;
+
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       prov_params = (wfd_oem_asp_prov_s *)event->edata;
+       int res = 0;
+
+       if (prov_params->persist &&
+       (prov_params->network_role || prov_params->network_config)) {
+               WDS_LOGE("Persistent group is used but "
+                               "conncap/dev_passwd_id are present");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if (!prov_params->persist &&
+       (!prov_params->network_role && !prov_params->network_config)) {
+               WDS_LOGE("Persistent group not used but "
+                               "conncap/dev_passwd_id are missing");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if (session->wps_mode == WFD_OEM_WPS_MODE_P2PS)
+               g_strlcpy(session->wps_pin, OEM_DEFAULT_P2PS_PIN, OEM_PINSTR_LEN + 1);
+
+       if (prov_params->persist) {
+               res = wfd_session_asp_persistent_connect(session, prov_params->persistent_group_id);
+       } else if (prov_params->network_role == WFD_OEM_ASP_SESSION_ROLE_NEW) {
+               res = wfd_session_asp_connect(session, WFD_OEM_ASP_SESSION_ROLE_NEW);
+       } else if (prov_params->network_role == WFD_OEM_ASP_SESSION_ROLE_CLIENT) {
+               res = wfd_session_asp_connect(session, WFD_OEM_ASP_SESSION_ROLE_CLIENT);
+       } else if (prov_params->network_role == WFD_OEM_ASP_SESSION_ROLE_GO) {
+               WDS_LOGD("don't need to take action.");
+
+       } else {
+               WDS_LOGE("Unhandled event");
+               __WDS_LOG_FUNC_EXIT__;
+               res = -1;
+       }
+
+       __WDS_LOG_FUNC_EXIT__;
+       return res;
+}
 void wfd_event_asp_prov_start(wfd_oem_event_s *event)
 {
        __WDS_LOG_FUNC_ENTER__;
 
+       wfd_manager_s *manager = wfd_get_manager();
+       wfd_session_s *session = NULL;
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       int res = 0;
+
+       if (event == NULL || event->edata == NULL) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       prov_params = (wfd_oem_asp_prov_s *)event->edata;
+       res = __wfd_handle_asp_prov(manager, event);
+       session = (wfd_session_s *)manager->session;
+       if (res < 0 || session == NULL) {
+               WDS_LOGE("Failed to process event of session");
+               __WDS_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       WDS_LOGD("created session [%u] with peer [" MACSTR "]", session->session_id,
+                       MAC2STR(session->session_mac));
+
+       /* Incomming Session, auto_accept = TRUE emit request Received */
+       /* generate SessionConfigRequest if event->wps_mode is not P2PS  and return*/
+
+       wfd_session_timer(session, 1);
+       wfd_asp_session_request(prov_params);
+       wfd_asp_connect_status(prov_params->session_mac,
+                                               prov_params->session_id,
+                                               ASP_CONNECT_STATUS_REQUEST_RECEIVED,
+                                               NULL);
+
+       wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
+
        __WDS_LOG_FUNC_EXIT__;
        return;
 }
@@ -1487,6 +1686,79 @@ void wfd_event_asp_prov_done(wfd_oem_event_s *event)
 {
        __WDS_LOG_FUNC_ENTER__;
 
+       wfd_manager_s *manager = wfd_get_manager();
+       wfd_session_s *session = NULL;
+       wfd_oem_asp_prov_s *prov_params;
+       int res = 0;
+
+       if (event == NULL || event->edata == NULL) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       prov_params = (wfd_oem_asp_prov_s *)event->edata;
+       /* Incomming Session, auto_accept = TRUE emit request Received */
+       /* generate SessionConfigRequest if event->wps_mode is not P2PS  and return*/
+       if (manager->session == NULL) {
+               wfd_asp_session_request(prov_params);
+               wfd_asp_connect_status(prov_params->session_mac,
+                                                       prov_params->session_id,
+                                                       ASP_CONNECT_STATUS_REQUEST_RECEIVED,
+                                                       NULL);
+       }
+
+       res = __wfd_handle_asp_prov(manager, event);
+       session = (wfd_session_s *)manager->session;
+       if (res < 0 || session == NULL) {
+               WDS_LOGE("Failed to process event of session");
+               wfd_destroy_session(manager);
+               wfd_asp_connect_status(prov_params->session_mac,
+                                                       prov_params->session_id,
+                                                       ASP_CONNECT_STATUS_REQUEST_FAILED,
+                                                       NULL);
+               wfd_oem_refresh(manager->oem_ops);
+               __WDS_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       if (prov_params->status != WFD_OEM_SC_SUCCESS &&
+                       prov_params->status != WFD_OEM_SC_SUCCESS_ACCEPTED_BY_USER) {
+               WDS_LOGD("ASP-PROV failed. remove session.");
+               wfd_destroy_session(manager);
+               wfd_oem_refresh(manager->oem_ops);
+               wfd_asp_connect_status(prov_params->session_mac,
+                                                       prov_params->session_id,
+                                                       ASP_CONNECT_STATUS_REQUEST_FAILED,
+                                                       NULL);
+               __WDS_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       wfd_asp_connect_status(prov_params->session_mac,
+                                               prov_params->session_id,
+                                               ASP_CONNECT_STATUS_REQUEST_ACCEPTED,
+                                               NULL);
+
+       wfd_asp_connect_status(prov_params->session_mac,
+                                               prov_params->session_id,
+                                               ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
+                                               NULL);
+       res = __wfd_handle_asp_prov_done(session, event);
+       if (res < 0) {
+               WDS_LOGE("Connect failed. remove session.");
+               wfd_destroy_session(manager);
+               wfd_oem_refresh(manager->oem_ops);
+
+               wfd_asp_connect_status(prov_params->session_mac,
+                                                       prov_params->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
+                                                       NULL);
+               __WDS_LOG_FUNC_EXIT__;
+               return;
+       }
+
+       WDS_LOGD("Provision done succeeded.");
        __WDS_LOG_FUNC_EXIT__;
        return;
 }
index ed90835..f9c1725 100644 (file)
@@ -44,6 +44,9 @@
 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
 #include "wifi-direct-service.h"
 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
+#ifdef TIZEN_FEATURE_ASP
+#include "wifi-direct-asp.h"
+#endif /* TIZEN_FEATURE_ASP */
 
 #define WFD_DBUS_REPLY_ERROR_NONE(invocation) \
        g_dbus_method_invocation_return_value((invocation), g_variant_new("(i)", WIFI_DIRECT_ERROR_NONE))
@@ -416,9 +419,29 @@ const gchar wfd_manager_introspection_xml[] = {
                                "<arg type='t' name='search_id' direction='in'/>"
                                "<arg type='i' name='result' direction='out'/>"
                        "</method>"
+               "<method name='ConnectSession'>"
+                       "<arg type='a{sv}' name='parameters' direction='in'/>"
+                       "<arg type='i' name='result' direction='out'/>"
+               "</method>"
+               "<method name='ConfirmSession'>"
+                       "<arg type='a{sv}' name='parameters' direction='in'/>"
+                       "<arg type='i' name='result' direction='out'/>"
+               "</method>"
                        "<signal name='SearchResult'>"
                                "<arg type='a{sv}' name='parameters'/>"
                        "</signal>"
+               "<signal name='SessionRequest'>"
+                       "<arg type='a{sv}' name='parameters'/>"
+               "</signal>"
+               "<signal name='SessionConfigRequest'>"
+                       "<arg type='a{sv}' name='parameters'/>"
+               "</signal>"
+               "<signal name='ConnectStatus'>"
+                       "<arg type='a{sv}' name='parameters'/>"
+               "</signal>"
+               "<signal name='SessionStatus'>"
+                       "<arg type='a{sv}' name='parameters'/>"
+               "</signal>"
                "</interface>"
 #endif
        "</node>"
@@ -952,6 +975,18 @@ static void __wfd_manager_manage_iface_handler(const gchar *method_name,
                                "IsWfdDevice",
                                g_variant_new_boolean(peer->is_wfd_device));
 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
+#ifdef TIZEN_FEATURE_ASP
+               wfd_device_s *connected_peer = NULL;
+               connected_peer = wfd_group_find_member_by_addr(manager->group, mac_addr);
+               if (connected_peer) {
+                       g_variant_builder_add(builder_peer, "{sv}",
+                                       "IsInGroup",
+                                       g_variant_new_boolean(true));
+                       g_variant_builder_add(builder_peer, "{sv}",
+                                       "IPAddress",
+                                       wfd_manager_dbus_pack_ay(connected_peer->ip_addr, IPADDR_LEN));
+               }
+#endif /* TIZEN_FEATURE_WIFI_DISPLAY */
 
                ret = WIFI_DIRECT_ERROR_NONE;
                return_parameters = g_variant_new("(ia{sv})", ret, builder_peer);
@@ -2236,16 +2271,190 @@ static void __wfd_manager_asp_iface_handler(const gchar *method_name,
                ret = WIFI_DIRECT_ERROR_NONE;
                return_parameters = g_variant_new("(i)", ret);
                goto done;
+       } else if (!g_strcmp0(method_name, "ConnectSession")) {
+
+               GVariantIter *iter = NULL;
+               gchar *key = NULL;
+               GVariant *var = NULL;
+               wfd_oem_asp_prov_s prov_params;
+               const char *mac_str = NULL;
+               unsigned char role = 0;
+               unsigned int config = 0;
+               int status = 0;
+
+               if (manager->state != WIFI_DIRECT_STATE_ACTIVATED &&
+                               manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
+                               manager->state != WIFI_DIRECT_STATE_GROUP_OWNER) {
+                       ret = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       goto failed;
+               }
+
+               memset(&prov_params, 0, sizeof(wfd_oem_asp_prov_s));
+
+               g_variant_get(parameters, "(a{sv})", &iter);
+               while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
+
+                       if (!g_strcmp0(key, "service_mac")) {
+                               g_variant_get(var, "&s", &mac_str);
+                               if (mac_str == NULL) {
+                                       ret = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                                       g_variant_iter_free(iter);
+                                       goto failed;
+                               }
+                               macaddr_atoe(mac_str, prov_params.service_mac);
+                       } else if (!g_strcmp0(key, "adv_id")) {
+                               g_variant_get(var, "u", &(prov_params.adv_id));
+                       } else if (!g_strcmp0(key, "session_mac")) {
+                               g_variant_get(var, "&s", &mac_str);
+                               if (mac_str == NULL) {
+                                       ret = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                                       g_variant_iter_free(iter);
+                                       goto failed;
+                               }
+                               macaddr_atoe(mac_str, prov_params.session_mac);
+                       } else if (!g_strcmp0(key, "session_id")) {
+                               g_variant_get(var, "u", &(prov_params.session_id));
+                       } else if (!g_strcmp0(key, "role")) {
+                               g_variant_get(var, "y", &(role));
+                               prov_params.network_role = (int)role;
+                       } else if (!g_strcmp0(key, "config_method")) {
+                               g_variant_get(var, "u", &(config));
+                               prov_params.network_config = (int)config;
+                       } else if (!g_strcmp0(key, "session_info")) {
+                               g_variant_get(var, "&s", &(prov_params.session_information));
+                       } else {
+                               ;/* Do Nothing */
+                       }
+               }
+
+               if (ISZEROMACADDR(prov_params.service_mac) ||
+                               ISZEROMACADDR(prov_params.session_mac)) {
+                       ret = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                       g_variant_iter_free(iter);
+                       goto failed;
+               }
+
+               WFD_DBUS_REPLY_ERROR_NONE(invocation);
+
+               wfd_asp_connect_status(prov_params.session_mac,
+                               prov_params.session_id,
+                               ASP_CONNECT_STATUS_REQUEST_SENT,
+                               NULL);
+
+               wfd_group_s *group = (wfd_group_s*) manager->group;
+               if (group && group->member_count >= manager->max_station) {
+
+                       status = ASP_CONNECT_STATUS_NOMORE_CONNECT;
+                       wfd_asp_connect_status(prov_params.session_mac,
+                                       prov_params.session_id,
+                                       status,
+                                       NULL);
+                       g_variant_iter_free(iter);
+                       __WDS_LOG_FUNC_EXIT__;
+                       return;
+               }
+
+               ret = wfd_manager_asp_connect_session(manager, &prov_params);
+               if (ret == WIFI_DIRECT_ERROR_NONE) {
+                       char peer_mac_address[MACSTR_LEN] = {0,};
+                       g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(prov_params.service_mac));
+                       wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
+                                                    "Connection",
+                                                    g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
+                                                                           WFD_EVENT_CONNECTION_IN_PROGRESS,
+                                                                           peer_mac_address));
+               } else {
+                       wfd_asp_connect_status(prov_params.session_mac,
+                                       prov_params.session_id,
+                                       ASP_CONNECT_STATUS_REQUEST_FAILED,
+                                       NULL);
+               }
+               g_variant_iter_free(iter);
+               __WDS_LOG_FUNC_EXIT__;
+               return;
+
+       } else if (!g_strcmp0(method_name, "ConfirmSession")) {
+
+               GVariantIter *iter = NULL;
+               gchar *key = NULL;
+               GVariant *var = NULL;
+               wfd_oem_asp_prov_s prov_params;
+               const char *mac_str = NULL;
+               const char *pin = NULL;
+               int confirmed = 0;
+
+               if (manager->state != WIFI_DIRECT_STATE_CONNECTING) {
+                       ret = WIFI_DIRECT_ERROR_NOT_PERMITTED;
+                       goto failed;
+               }
+
+               memset(&prov_params, 0, sizeof(wfd_oem_asp_prov_s));
+
+               g_variant_get(parameters, "(a{sv})", &iter);
+               while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
+
+                       if (!g_strcmp0(key, "session_mac")) {
+                               g_variant_get(var, "&s", &mac_str);
+                               if (mac_str == NULL) {
+                                       ret = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                                       g_variant_iter_free(iter);
+                                       goto failed;
+                               }
+                               macaddr_atoe(mac_str, prov_params.session_mac);
+                       } else if (!g_strcmp0(key, "session_id")) {
+                               g_variant_get(var, "u", &(prov_params.session_id));
+                       } else if (!g_strcmp0(key, "confirmed")) {
+                               g_variant_get(var, "y", &(confirmed));
+                       } else if (!g_strcmp0(key, "pin")) {
+                               g_variant_get(var, "&s", &(pin));
+                               g_strlcpy(prov_params.wps_pin, pin, PINSTR_LEN);
+                       } else {
+                               ;/* Do Nothing */
+                       }
+               }
+
+               if (ISZEROMACADDR(prov_params.session_mac))     {
+                       ret = WIFI_DIRECT_ERROR_INVALID_PARAMETER;
+                       g_variant_iter_free(iter);
+                       goto failed;
+               }
+
+               WFD_DBUS_REPLY_ERROR_NONE(invocation);
+
+               ret = wfd_manager_asp_confirm_session(manager, &prov_params, confirmed);
+               if (ret == WIFI_DIRECT_ERROR_NONE && confirmed > 0) {
+                       char peer_mac_address[MACSTR_LEN] = {0,};
+                       g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(prov_params.service_mac));
+                       wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
+                                                    "Connection",
+                                                    g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
+                                                                           WFD_EVENT_CONNECTION_IN_PROGRESS,
+                                                                           peer_mac_address));
+                       wfd_asp_connect_status(prov_params.session_mac,
+                                       prov_params.session_id,
+                                       ASP_CONNECT_STATUS_REQUEST_ACCEPTED,
+                                       NULL);
+               } else {
+                       wfd_asp_connect_status(prov_params.session_mac,
+                                       prov_params.session_id,
+                                       ASP_CONNECT_STATUS_REQUEST_FAILED,
+                                       NULL);
+               }
+               g_variant_iter_free(iter);
+               __WDS_LOG_FUNC_EXIT__;
+               return;
        }
 
 done:
        WFD_DBUS_REPLY_PARAMS(invocation, return_parameters);
+       __WDS_LOG_FUNC_EXIT__;
        return;
 
 failed:
        wfd_error_set_gerror(ret, &err);
        g_dbus_method_invocation_return_gerror(invocation, err);
        g_clear_error(&err);
+       __WDS_LOG_FUNC_EXIT__;
        return;
 }
 #endif
index 546e4bb..61f1a8f 100644 (file)
@@ -691,6 +691,111 @@ int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
        return WIFI_DIRECT_ERROR_NONE;
 }
 
+#if defined(TIZEN_FEATURE_ASP)
+int wfd_manager_asp_connect_session(wfd_manager_s *manager, void *params)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_session_s *session = NULL;
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       int req_wps_mode = WFD_WPS_MODE_P2PS;
+       int res = 0;
+
+       prov_params = (wfd_oem_asp_prov_s *)params;
+       if (!manager || !prov_params) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       session = (wfd_session_s*) manager->session;
+       if (session) {
+               WDS_LOGE("Session already exists");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+       if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_DISPLAY)
+               req_wps_mode = WFD_WPS_MODE_DISPLAY;
+       else if (prov_params->network_config == WFD_OEM_ASP_WPS_TYPE_PIN_KEYPAD)
+               req_wps_mode = WFD_WPS_MODE_KEYPAD;
+       else
+               req_wps_mode = WFD_WPS_MODE_P2PS;
+
+       session = wfd_create_session(manager, prov_params->service_mac,
+                       req_wps_mode, SESSION_DIRECTION_OUTGOING);
+       if (!session) {
+               WDS_LOGE("Failed to create new session");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       res = wfd_session_asp_session_start(session, prov_params);
+       if (res < 0) {
+               WDS_LOGE("Failed to start session");
+               wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+
+int wfd_manager_asp_confirm_session(wfd_manager_s *manager, void *params, int confirmed)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_session_s *session = NULL;
+       wfd_oem_asp_prov_s *prov_params = NULL;
+       int res = 0;
+
+       prov_params = (wfd_oem_asp_prov_s *)params;
+       if (!manager || !prov_params) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       session = (wfd_session_s*) manager->session;
+       if (!session) {
+               WDS_LOGE("Session not exists");
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_NOT_PERMITTED;
+       }
+
+
+       WDS_LOGD("confirm session [%u] with peer [" MACSTR "]", prov_params->session_id,
+                       MAC2STR(prov_params->session_mac));
+
+       WDS_LOGD("created session [%u] with peer [" MACSTR "]", session->session_id,
+                       MAC2STR(session->session_mac));
+
+       if (session->session_id != prov_params->session_id ||
+                       memcmp(&(session->session_mac), prov_params->session_mac, MACADDR_LEN) != 0) {
+               WDS_LOGE("Session MAC or ID not matched");
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+
+       if (confirmed)
+               prov_params->status = 12;
+       else
+               prov_params->status = 11;
+
+       res = wfd_oem_asp_prov_disc_req(manager->oem_ops, prov_params);
+       if (res < 0) {
+               WDS_LOGE("Failed to start session");
+               wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
+               return WIFI_DIRECT_ERROR_OPERATION_FAILED;
+       }
+       wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return WIFI_DIRECT_ERROR_NONE;
+}
+#endif
+
 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -1243,6 +1348,26 @@ int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_i
        return count;
 }
 
+#ifdef TIZEN_FEATURE_ASP
+wfd_device_s *wfd_manager_get_connected_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_device_s *peer = NULL;
+
+       if (peer_addr == NULL) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return peer;
+       }
+
+       if (manager->group)
+               peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return peer;
+}
+#endif /* TIZEN_FEATURE_ASP */
+
 #if 0
 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
 {
index 6d1c2de..26b8aa5 100644 (file)
@@ -44,6 +44,9 @@
 #include "wifi-direct-error.h"
 #include "wifi-direct-log.h"
 #include "wifi-direct-dbus.h"
+#ifdef TIZEN_FEATURE_ASP
+#include "wifi-direct-asp.h"
+#endif /* TIZEN_FEATURE_ASP */
 
 
 static gboolean _session_timeout_cb(gpointer *user_data)
@@ -74,6 +77,21 @@ static gboolean _session_timeout_cb(gpointer *user_data)
                                                            WFD_EVENT_CONNECTION_RSP,
                                                            peer_mac_address));
 
+#if defined(TIZEN_FEATURE_ASP)
+       if (!ISZEROMACADDR(session->session_mac)) {
+               if(session->state < SESSION_STATE_GO_NEG)
+                       wfd_asp_connect_status(session->session_mac,
+                                       session->session_id,
+                                       ASP_CONNECT_STATUS_REQUEST_FAILED,
+                                       NULL);
+               else
+                       wfd_asp_connect_status(session->session_mac,
+                                       session->session_id,
+                                       ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
+                                       NULL);
+       }
+#endif
+
        wfd_session_cancel(session, peer_addr);
 
        if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
@@ -106,6 +124,15 @@ static void _wfd_notify_session_failed(wfd_manager_s *manager, unsigned char *pe
                                                            WFD_EVENT_CONNECTION_RSP,
                                                            peer_mac_address));
 
+#if defined(TIZEN_FEATURE_ASP)
+       wfd_session_s *session = manager->session;
+       if (session && !ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
+                                                       NULL);
+#endif
+
        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);
@@ -197,6 +224,10 @@ wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_
                session->wps_mode = WFD_WPS_MODE_KEYPAD;
        else if (wps_mode == WFD_WPS_MODE_KEYPAD)
                session->wps_mode = WFD_WPS_MODE_DISPLAY;
+#if defined(TIZEN_FEATURE_ASP)
+       else if (wps_mode == WFD_WPS_MODE_P2PS)
+               session->wps_mode = WFD_WPS_MODE_P2PS;
+#endif /* TIZEN_FEATURE_ASP */
        else
                session->wps_mode = wps_mode;
        session->direction = direction;
@@ -318,6 +349,45 @@ int wfd_session_start(wfd_session_s *session)
        return 0;
 }
 
+#if defined(TIZEN_FEATURE_ASP)
+int wfd_session_asp_session_start(wfd_session_s *session, wfd_oem_asp_prov_s *params)
+{
+       __WDS_LOG_FUNC_ENTER__;
+
+       wfd_manager_s *manager = wfd_get_manager();
+       int res = 0;
+
+       if (session == NULL || params == NULL) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if (session->state > SESSION_STATE_STARTED) {
+               WDS_LOGE("Invalid session state(%d)", session->state);
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       res = wfd_oem_asp_prov_disc_req(manager->oem_ops, params);
+       if (res < 0) {
+               WDS_LOGD("Failed to send ASP provision discovery request to peer");
+               wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       session->state = SESSION_STATE_STARTED;
+       session->session_id = params->session_id;
+       memcpy(session->session_mac, params->session_mac, MACADDR_LEN);
+       memcpy(session->service_mac, params->service_mac, MACADDR_LEN);
+       wfd_session_timer(session, 1);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif /* TIZEN_FEATURE_ASP */
+
 #if 0
 int wfd_session_stop(wfd_session_s *session)
 {
@@ -626,6 +696,104 @@ int wfd_session_wps(wfd_session_s *session)
        return 0;
 }
 
+#if defined(TIZEN_FEATURE_ASP)
+/* 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.
+ * Even though peer is GO, we can use this function, which can decide using join itself.
+ */
+int wfd_session_asp_connect(wfd_session_s *session, int role)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_manager_s *manager = wfd_get_manager();
+       wfd_oem_conn_param_s param;
+       wfd_device_s *peer = NULL;
+       int res = 0;
+
+       if (!session) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if (session->state > SESSION_STATE_GO_NEG) {
+               WDS_LOGE("Session already finished GO Negotiation");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       session->state = SESSION_STATE_GO_NEG;
+       peer = session->peer;
+
+       memset(&param, 0x00, sizeof(wfd_oem_conn_param_s));
+       param.wps_mode = session->wps_mode;
+       if (role == 2)
+               param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
+       param.go_intent = session->go_intent;
+       param.freq = session->freq;
+       param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
+
+       if (session->wps_pin[0] != '\0')
+               g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
+
+       res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, &param);
+       if (res < 0) {
+               WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
+               wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       wfd_session_timer(session, 1);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+
+/* 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.
+ * Even though peer is GO, we can use this function, which can decide using join itself.
+ */
+int wfd_session_asp_persistent_connect(wfd_session_s *session, int persist_group_id)
+{
+       __WDS_LOG_FUNC_ENTER__;
+       wfd_manager_s *manager = wfd_get_manager();
+       wfd_device_s *peer = NULL;
+       wfd_oem_group_param_s param;
+       int res = 0;
+
+       if (!session) {
+               WDS_LOGE("Invalid parameter");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       if (session->state > SESSION_STATE_GO_NEG) {
+               WDS_LOGE("Session already finished GO Negotiation");
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       session->state = SESSION_STATE_WPS;
+
+       memset(&param, 0x0, sizeof(param));
+       param.persistent = 2;
+       param.persistent_group_id = persist_group_id;
+
+       res = wfd_oem_create_group(manager->oem_ops, &param);
+       if (res < 0) {
+               WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
+               wfd_destroy_session(manager);
+               __WDS_LOG_FUNC_EXIT__;
+               return -1;
+       }
+
+       wfd_session_timer(session, 1);
+
+       __WDS_LOG_FUNC_EXIT__;
+       return 0;
+}
+#endif /* TIZEN_FEATURE_ASP */
+
 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
 {
        __WDS_LOG_FUNC_ENTER__;
@@ -934,6 +1102,63 @@ int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
                        session->state = SESSION_STATE_COMPLETED;
                }
        }
+               break;
+#if defined(TIZEN_FEATURE_ASP)
+       case WFD_OEM_EVENT_ASP_PROV_START:
+       {
+               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_P2PS;
+
+               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_WPS_MODE_DISPLAY)
+                       g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
+
+               session->state = SESSION_STATE_STARTED;
+               wfd_session_timer(session, 1);
+       }
+               break;
+       case WFD_OEM_EVENT_ASP_PROV_DONE:
+       {
+               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_P2PS;
+
+               session = (wfd_session_s*) manager->session;
+               if (!session) {
+                       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;
+                       }
+                       session->state = SESSION_STATE_STARTED;
+                       wfd_session_timer(session, 1);
+               }
+       }
+               break;
+#endif /* TIZEN_FEATURE_ASP */
+       if (res < 0)
+               _wfd_notify_session_failed(manager, event->dev_addr);
        break;
        default:
                break;
index 3942719..cca62a2 100644 (file)
@@ -60,6 +60,9 @@
 #include "wifi-direct-error.h"
 #include "wifi-direct-log.h"
 #include "wifi-direct-dbus.h"
+#if defined(TIZEN_FEATURE_ASP)
+#include "wifi-direct-asp.h"
+#endif
 
 #include <linux/unistd.h>
 #include <asm/types.h>
@@ -838,10 +841,6 @@ static gboolean _polling_ip(gpointer user_data)
        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);
-       wfd_destroy_session(manager);
-
        char peer_mac_address[MACSTR_LEN+1] = {0, };
 
        g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
@@ -851,6 +850,19 @@ static gboolean _polling_ip(gpointer user_data)
                                                            WFD_EVENT_CONNECTION_RSP,
                                                            peer_mac_address));
 
+#if defined(TIZEN_FEATURE_ASP)
+       wfd_session_s *session = manager->session;
+       if (session && !ISZEROMACADDR(session->session_mac))
+               wfd_asp_connect_status(session->session_mac,
+                                                       session->session_id,
+                                                       ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
+                                                       NULL);
+#endif
+
+       wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
+       wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
+       wfd_destroy_session(manager);
+
        __WDS_LOG_FUNC_EXIT__;
        return FALSE;
 }