2 * Network Configuration Module
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This file implements wifi direct session functions.
23 * @file wifi-direct-session.c
24 * @author Gibyoung Kim (lastkgb.kim@samsung.com)
33 #include <wifi-direct.h>
35 #include "wifi-direct-ipc.h"
36 #include "wifi-direct-manager.h"
37 #include "wifi-direct-oem.h"
38 #include "wifi-direct-peer.h"
39 #include "wifi-direct-group.h"
40 #include "wifi-direct-oem.h"
41 #include "wifi-direct-util.h"
42 #include "wifi-direct-session.h"
43 #include "wifi-direct-state.h"
44 #include "wifi-direct-error.h"
45 #include "wifi-direct-log.h"
46 #include "wifi-direct-dbus.h"
47 #ifdef TIZEN_FEATURE_ASP
48 #include "wifi-direct-asp.h"
49 #endif /* TIZEN_FEATURE_ASP */
52 static gboolean _session_timeout_cb(gpointer *user_data)
54 __WDS_LOG_FUNC_ENTER__;
55 wfd_manager_s *manager = wfd_get_manager();
56 wfd_session_s *session = (wfd_session_s*) manager->session;
57 unsigned char *peer_addr = NULL;
58 char peer_mac_address[MACSTR_LEN+1] = {0, };
61 WDS_LOGE("Invalid parameter");
64 session->connecting_120 = 0;
66 WDS_LOGD("Session timer expired");
68 peer_addr = wfd_session_get_peer_addr(session);
69 if (peer_addr != NULL)
70 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
72 g_snprintf(peer_mac_address, MACSTR_LEN, "%s", "");
74 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
76 g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_TIME_OUT,
77 WFD_EVENT_CONNECTION_RSP,
80 #if defined(TIZEN_FEATURE_ASP)
81 if (!ISZEROMACADDR(session->session_mac)) {
82 if (session->state < SESSION_STATE_GO_NEG)
83 wfd_asp_connect_status(session->session_mac,
85 ASP_CONNECT_STATUS_REQUEST_FAILED,
88 wfd_asp_connect_status(session->session_mac,
90 ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
95 wfd_session_cancel(session, peer_addr);
97 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
99 wfd_group_s *group = (wfd_group_s*) manager->group;
100 if (group && wfd_util_is_remove_group_allowed()) {
101 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
103 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
104 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
107 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
108 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
111 __WDS_LOG_FUNC_EXIT__;
115 static void _wfd_notify_session_failed(wfd_manager_s *manager, unsigned char *peer_addr)
117 __WDS_LOG_FUNC_ENTER__;
118 char peer_mac_address[MACSTR_LEN+1] = {0, };
120 snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
121 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
123 g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
124 WFD_EVENT_CONNECTION_RSP,
127 #if defined(TIZEN_FEATURE_ASP)
128 wfd_session_s *session = manager->session;
129 if (session && !ISZEROMACADDR(session->session_mac))
130 wfd_asp_connect_status(session->session_mac,
132 ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
136 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
137 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
138 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
140 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
141 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
144 __WDS_LOG_FUNC_EXIT__;
147 int wfd_session_timer(wfd_session_s *session, int start)
149 __WDS_LOG_FUNC_ENTER__;
152 WDS_LOGE("Invalid parameter");
153 __WDS_LOG_FUNC_EXIT__;
158 if (!session->connecting_120)
159 session->connecting_120 = 1;
161 if (session->timer > 0) {
162 WDS_LOGE("Session timer already started");
163 __WDS_LOG_FUNC_EXIT__;
166 session->timer = g_timeout_add(120000,
167 (GSourceFunc) _session_timeout_cb,
169 WDS_LOGD("Session timer started");
171 session->connecting_120 = 0;
172 if (session->timer > 0) {
173 g_source_remove(session->timer);
175 WDS_LOGD("Session timer stoped");
179 __WDS_LOG_FUNC_EXIT__;
183 /* Check the session instance which has same peer address,
184 * before using this function */
185 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction)
187 __WDS_LOG_FUNC_ENTER__;
188 wfd_manager_s *manager = (wfd_manager_s*) data;
189 wfd_session_s *session = NULL;
190 wfd_device_s *peer = NULL;
192 if (!data || !peer_addr) {
193 WDS_LOGE("Invalid parameter");
194 __WDS_LOG_FUNC_EXIT__;
198 WDS_LOGD("create session for peer[" MACSTR "]", MAC2STR(peer_addr));
200 if (manager->session) {
201 WDS_LOGE("Session already exist");
205 session = (wfd_session_s*) g_try_malloc0(sizeof(wfd_session_s));
207 WDS_LOGE("Failed to allocate memory for session");
208 __WDS_LOG_FUNC_EXIT__;
212 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
214 WDS_LOGE("Failed to find peer info[" MACSECSTR "]", MAC2SECSTR(peer_addr));
216 __WDS_LOG_FUNC_EXIT__;
219 peer->state = WFD_PEER_STATE_CONNECTING;
221 session->peer = peer;
222 session->req_wps_mode = wps_mode;
223 if (wps_mode == WFD_WPS_MODE_DISPLAY)
224 session->wps_mode = WFD_WPS_MODE_KEYPAD;
225 else if (wps_mode == WFD_WPS_MODE_KEYPAD)
226 session->wps_mode = WFD_WPS_MODE_DISPLAY;
227 #if defined(TIZEN_FEATURE_ASP)
228 else if (wps_mode == WFD_WPS_MODE_P2PS)
229 session->wps_mode = WFD_WPS_MODE_P2PS;
230 #endif /* TIZEN_FEATURE_ASP */
232 session->wps_mode = wps_mode;
233 session->direction = direction;
234 session->state = SESSION_STATE_CREATED;
236 manager->session = session;
237 manager->local->wps_mode = session->wps_mode;
239 if (peer->dev_role == WFD_DEV_ROLE_GO &&
240 manager->local->wps_mode == WFD_WPS_MODE_DISPLAY) {
241 char *generated_pin = NULL;
242 session->wps_mode = WFD_WPS_MODE_DISPLAY;
243 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
245 if (wfd_oem_generate_pin(manager->oem_ops, &generated_pin) != 0) {
246 WDS_LOGE("Failed to generate pin");
248 __WDS_LOG_FUNC_EXIT__;
252 g_strlcpy(session->wps_pin, generated_pin, PINSTR_LEN + 1);
253 g_free(generated_pin);
256 if (peer->dev_role == WFD_DEV_ROLE_GO && manager->local->dev_role != WFD_DEV_ROLE_GO)
257 manager->local->dev_role = WFD_DEV_ROLE_GC;
259 __WDS_LOG_FUNC_EXIT__;
263 int wfd_destroy_session(void *data)
265 __WDS_LOG_FUNC_ENTER__;
266 wfd_manager_s *manager = (wfd_manager_s*) data;
267 wfd_session_s *session = NULL;
268 wfd_device_s *peer = NULL;
271 WDS_LOGE("Invalid parameter");
275 session = (wfd_session_s*) manager->session;
277 WDS_LOGE("Session not found"); /* self prevent */
280 wfd_session_timer(session, 0);
281 peer = session->peer;
284 if (session->state == SESSION_STATE_COMPLETED)
285 peer->state = WFD_PEER_STATE_CONNECTED;
287 peer->state = WFD_PEER_STATE_DISCOVERED;
289 WDS_LOGE("Peer not found");
293 manager->session = NULL;
294 manager->local->wps_mode = WFD_WPS_MODE_PBC;
295 manager->autoconnection = 0;
296 memset(manager->auto_pin, 0x0, PINSTR_LEN);
297 if (manager->local->dev_role == WFD_DEV_ROLE_GC)
298 manager->local->dev_role = WFD_DEV_ROLE_NONE;
300 __WDS_LOG_FUNC_EXIT__;
304 int wfd_session_start(wfd_session_s *session)
306 __WDS_LOG_FUNC_ENTER__;
307 wfd_manager_s *manager = wfd_get_manager();
308 wfd_device_s *peer = NULL;
313 WDS_LOGE("Invalid parameter");
314 __WDS_LOG_FUNC_EXIT__;
318 if (session->state > SESSION_STATE_STARTED) {
319 WDS_LOGE("Invalid session state(%d)", session->state);
323 /* Check: Invitation Received in Incomming case ->
324 * send prov_disc join
326 * Check: User select peer to connect with in Outgoing case ->
327 * send prov_disc wps_mode */
329 wfd_oem_stop_scan(manager->oem_ops);
331 session->state = SESSION_STATE_STARTED;
332 peer = session->peer;
333 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
335 res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
336 session->req_wps_mode, join);
338 WDS_LOGD("Failed to send provision discovery request to peer [" MACSECSTR "]",
339 MAC2SECSTR(peer->dev_addr));
340 wfd_destroy_session(manager);
341 /* TODO: send notification to App */
342 __WDS_LOG_FUNC_EXIT__;
346 wfd_session_timer(session, 1);
348 __WDS_LOG_FUNC_EXIT__;
352 #if defined(TIZEN_FEATURE_ASP)
353 int wfd_session_asp_session_start(wfd_session_s *session, wfd_oem_asp_prov_s *params)
355 __WDS_LOG_FUNC_ENTER__;
357 wfd_manager_s *manager = wfd_get_manager();
360 if (session == NULL || params == NULL) {
361 WDS_LOGE("Invalid parameter");
362 __WDS_LOG_FUNC_EXIT__;
366 if (session->state > SESSION_STATE_STARTED) {
367 WDS_LOGE("Invalid session state(%d)", session->state);
368 __WDS_LOG_FUNC_EXIT__;
372 res = wfd_oem_asp_prov_disc_req(manager->oem_ops, params);
374 WDS_LOGD("Failed to send ASP provision discovery request to peer");
375 wfd_destroy_session(manager);
376 __WDS_LOG_FUNC_EXIT__;
380 session->state = SESSION_STATE_STARTED;
381 session->session_id = params->session_id;
382 memcpy(session->session_mac, params->session_mac, MACADDR_LEN);
383 memcpy(session->service_mac, params->service_mac, MACADDR_LEN);
384 wfd_session_timer(session, 1);
386 __WDS_LOG_FUNC_EXIT__;
389 #endif /* TIZEN_FEATURE_ASP */
392 int wfd_session_stop(wfd_session_s *session)
394 __WDS_LOG_FUNC_ENTER__;
395 wfd_manager_s *manager = wfd_get_manager();
396 wfd_device_s *peer = NULL;
400 WDS_LOGE("Invalid parameter");
401 __WDS_LOG_FUNC_EXIT__;
405 if (session->state > SESSION_STATE_CREATED) {
406 peer = session->peer;
407 if (session->direction == SESSION_DIRECTION_INCOMING)
408 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
409 else if (session->direction == SESSION_DIRECTION_OUTGOING)
410 res = wfd_oem_cancel_connection(manager->oem_ops, peer->dev_addr);
413 WDS_LOGE("Failed to reject or cancel connection");
414 __WDS_LOG_FUNC_EXIT__;
419 session->state = SESSION_STATE_STOPPED;
420 wfd_destroy_session(manager);
422 __WDS_LOG_FUNC_EXIT__;
427 /* In case of incomming session, when user accept connection request, this function should be called.
428 * In case of outgoing session, when prov_disc response arrived, this function should be called.
429 * Even though peer is GO, we can use this function, which can decide using join itself.
431 int wfd_session_connect(wfd_session_s *session)
433 __WDS_LOG_FUNC_ENTER__;
434 wfd_manager_s *manager = wfd_get_manager();
435 wfd_oem_conn_param_s param;
436 wfd_device_s *peer = NULL;
440 WDS_LOGE("Invalid parameter");
441 __WDS_LOG_FUNC_EXIT__;
445 if (session->state > SESSION_STATE_GO_NEG) {
446 WDS_LOGE("Session already finished GO Negotiation");
450 session->state = SESSION_STATE_GO_NEG;
451 peer = session->peer;
453 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
454 param.wps_mode = session->wps_mode;
455 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
456 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
457 param.go_intent = session->go_intent;
458 param.freq = session->freq;
459 if (manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
460 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
462 if (session->wps_pin[0] != '\0')
463 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
465 /* To connect with windows phone,set go_intent value to 2.
466 * As windows phone does not connect when local device act as GO.
467 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_COMPUTER ==>1 (Assume Peer Device is Windows PC)
468 * WIFI_DIRECT_SECONDARY_DEVICE_TYPE_TELEPHONE_WINDOWS_MOBILE ==>1
469 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_TELEPHONE ==> 10
471 if ((peer->pri_dev_type == 1) ||
472 ((peer->pri_dev_type == 10) && (peer->sec_dev_type == 1))) {
474 WDS_LOGD("go_intent set to %d, Windows device", param.go_intent);
477 WDS_LOGD("connection go_intent: %d", param.go_intent);
478 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
480 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
481 wfd_destroy_session(manager);
482 __WDS_LOG_FUNC_EXIT__;
486 wfd_session_timer(session, 1);
488 __WDS_LOG_FUNC_EXIT__;
492 int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
494 __WDS_LOG_FUNC_ENTER__;
495 wfd_manager_s *manager = wfd_get_manager();
498 if (!session || !session->peer) {
499 WDS_LOGE("Invalid parameter");
500 __WDS_LOG_FUNC_EXIT__;
501 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
504 if (memcmp(peer_addr, session->peer->dev_addr, MACADDR_LEN)) {
505 WDS_LOGE("Peer is not included in this session");
506 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
509 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
510 res = wfd_oem_wps_cancel(manager->oem_ops);
512 res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
515 WDS_LOGE("Failed to cancel connection");
516 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
519 wfd_destroy_session(manager);
521 __WDS_LOG_FUNC_EXIT__;
525 int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
527 __WDS_LOG_FUNC_ENTER__;
528 wfd_manager_s *manager = wfd_get_manager();
529 wfd_device_s *peer = NULL;
532 if (!session || !manager) {
533 WDS_LOGE("Invalid parameter");
534 __WDS_LOG_FUNC_EXIT__;
538 /* Invite received case state is just created */
539 if (session->state < SESSION_STATE_CREATED ||
540 session->state >= SESSION_STATE_STOPPED) {
541 WDS_LOGE("Session state is Invalid [%d]", session->state);
542 __WDS_LOG_FUNC_EXIT__;
547 * TODO: check session status and do proper work
548 * for example, reject prov_disc, reject nego, stop wps, etc.
552 peer = session->peer;
554 if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
555 res = wfd_oem_wps_cancel(manager->oem_ops);
557 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
559 WDS_LOGE("Failed to reject connection");
560 __WDS_LOG_FUNC_EXIT__;
564 wfd_destroy_session(manager);
565 /* TODO: send notification to App */
567 __WDS_LOG_FUNC_EXIT__;
571 int wfd_session_join(wfd_session_s *session)
573 __WDS_LOG_FUNC_ENTER__;
574 wfd_manager_s *manager = wfd_get_manager();
575 wfd_oem_conn_param_s param;
576 wfd_device_s *peer = NULL;
580 WDS_LOGE("Invalid parameter");
581 __WDS_LOG_FUNC_EXIT__;
585 session->state = SESSION_STATE_WPS;
586 peer = session->peer;
588 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
589 param.wps_mode = session->wps_mode;
590 if (peer->dev_role == WFD_DEV_ROLE_GO)
591 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
592 param.go_intent = session->go_intent;
593 param.freq = session->freq;
594 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
596 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
598 WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
599 wfd_destroy_session(manager);
600 __WDS_LOG_FUNC_EXIT__;
604 wfd_session_timer(session, 1);
606 __WDS_LOG_FUNC_EXIT__;
610 int wfd_session_invite(wfd_session_s *session)
612 __WDS_LOG_FUNC_ENTER__;
613 wfd_manager_s *manager = wfd_get_manager();
614 wfd_oem_invite_param_s param;
615 wfd_device_s *peer = NULL;
616 wfd_group_s *group = NULL;
620 WDS_LOGE("Invalid parameter");
621 __WDS_LOG_FUNC_EXIT__;
625 if (session->state > SESSION_STATE_CREATED) {
626 WDS_LOGE("Invalid session state(%d)", session->state);
630 peer = session->peer;
631 group = (wfd_group_s*) manager->group;
633 memset(¶m, 0x00, sizeof(wfd_oem_invite_param_s));
634 param.ifname = strdup(group->ifname);
635 memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
637 WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
638 MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
640 res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, ¶m);
642 WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
643 wfd_destroy_session(manager);
644 __WDS_LOG_FUNC_EXIT__;
648 wfd_session_timer(session, 1);
650 __WDS_LOG_FUNC_EXIT__;
654 int wfd_session_wps(wfd_session_s *session)
656 __WDS_LOG_FUNC_ENTER__;
657 wfd_manager_s *manager = wfd_get_manager();
658 wfd_device_s *peer = NULL;
662 WDS_LOGE("Invalid parameter");
663 __WDS_LOG_FUNC_EXIT__;
667 if (session->state > SESSION_STATE_WPS) {
668 WDS_LOGE("Session already starts WPS");
672 session->state = SESSION_STATE_WPS;
673 peer = session->peer;
675 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
676 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
677 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
679 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
680 wfd_oem_conn_param_s param;
681 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
682 param.wps_mode = session->wps_mode;
683 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
684 param.freq = session->freq; /* currently not used */
685 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
686 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
689 WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
690 wfd_destroy_session(manager);
691 __WDS_LOG_FUNC_EXIT__;
695 __WDS_LOG_FUNC_EXIT__;
699 #if defined(TIZEN_FEATURE_ASP)
700 /* In case of incomming session, when user accept connection request, this function should be called.
701 * In case of outgoing session, when prov_disc response arrived, this function should be called.
702 * Even though peer is GO, we can use this function, which can decide using join itself.
704 int wfd_session_asp_connect(wfd_session_s *session, int role)
706 __WDS_LOG_FUNC_ENTER__;
707 wfd_manager_s *manager = wfd_get_manager();
708 wfd_oem_conn_param_s param;
709 wfd_device_s *peer = NULL;
713 WDS_LOGE("Invalid parameter");
714 __WDS_LOG_FUNC_EXIT__;
718 if (session->state >= SESSION_STATE_GO_NEG) {
719 WDS_LOGE("Session already starting GO Negotiation");
720 __WDS_LOG_FUNC_EXIT__;
724 if (role == WFD_OEM_ASP_SESSION_ROLE_GO) {
725 session->state = SESSION_STATE_WPS;
728 session->state = SESSION_STATE_GO_NEG;
731 peer = session->peer;
733 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
734 param.wps_mode = session->wps_mode;
736 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
737 param.go_intent = session->go_intent;
738 param.freq = session->freq;
739 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
741 if (session->wps_pin[0] != '\0')
742 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
744 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
746 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
747 wfd_destroy_session(manager);
748 __WDS_LOG_FUNC_EXIT__;
752 wfd_session_timer(session, 1);
754 __WDS_LOG_FUNC_EXIT__;
758 /* In case of incomming session, when user accept connection request, this function should be called.
759 * In case of outgoing session, when prov_disc response arrived, this function should be called.
760 * Even though peer is GO, we can use this function, which can decide using join itself.
762 int wfd_session_asp_persistent_connect(wfd_session_s *session, int persist_group_id)
764 __WDS_LOG_FUNC_ENTER__;
765 wfd_manager_s *manager = wfd_get_manager();
766 wfd_oem_group_param_s param;
770 WDS_LOGE("Invalid parameter");
771 __WDS_LOG_FUNC_EXIT__;
775 if (session->state > SESSION_STATE_GO_NEG) {
776 WDS_LOGE("Session already finished GO Negotiation");
777 __WDS_LOG_FUNC_EXIT__;
781 session->state = SESSION_STATE_WPS;
783 memset(¶m, 0x0, sizeof(param));
784 param.persistent = 2;
785 param.persistent_group_id = persist_group_id;
787 res = wfd_oem_create_group(manager->oem_ops, ¶m);
789 WDS_LOGD("Failed to create persistent group for ASP");
790 wfd_destroy_session(manager);
791 __WDS_LOG_FUNC_EXIT__;
795 wfd_session_timer(session, 1);
797 __WDS_LOG_FUNC_EXIT__;
800 #endif /* TIZEN_FEATURE_ASP */
802 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
804 __WDS_LOG_FUNC_ENTER__;
805 wfd_device_s *peer = NULL;
808 WDS_LOGE("Invalid parameter");
812 peer = session->peer;
814 __WDS_LOG_FUNC_EXIT__;
818 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
820 __WDS_LOG_FUNC_ENTER__;
821 wfd_device_s *peer = NULL;
823 if (!session || !session->peer) {
824 WDS_LOGE("Invalid parameter");
828 peer = session->peer;
830 __WDS_LOG_FUNC_EXIT__;
831 return peer->dev_addr;
835 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
837 __WDS_LOG_FUNC_ENTER__;
839 __WDS_LOG_FUNC_EXIT__;
843 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
845 __WDS_LOG_FUNC_ENTER__;
847 __WDS_LOG_FUNC_EXIT__;
851 int wfd_session_set_freq(wfd_session_s *session, int freq)
853 __WDS_LOG_FUNC_ENTER__;
855 __WDS_LOG_FUNC_EXIT__;
859 int wfd_session_get_state(wfd_session_s *session)
861 __WDS_LOG_FUNC_ENTER__;
863 __WDS_LOG_FUNC_EXIT__;
867 int wfd_session_set_state(wfd_session_s *session, int state)
869 __WDS_LOG_FUNC_ENTER__;
871 __WDS_LOG_FUNC_EXIT__;
876 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
878 __WDS_LOG_FUNC_ENTER__;
879 wfd_session_s *session = NULL;
882 if (!manager || !event) {
883 WDS_LOGE("Invalid parameter");
887 WDS_LOGD("event ID [%d]", event->event_id);
888 session = manager->session;
890 switch (event->event_id) {
891 case WFD_OEM_EVENT_PROV_DISC_REQ:
893 int req_wps_mode = WFD_WPS_MODE_NONE;
895 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
896 req_wps_mode = WFD_WPS_MODE_KEYPAD;
897 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
898 req_wps_mode = WFD_WPS_MODE_DISPLAY;
900 req_wps_mode = WFD_WPS_MODE_PBC;
902 /* Only peer initiated connection or invitation session can be allowed */
904 if (session->type != SESSION_TYPE_INVITE) {
905 WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
906 MAC2SECSTR(event->dev_addr));
909 WDS_LOGD("=====> session already exist. (invitation session)");
910 session->req_wps_mode = req_wps_mode;
911 session->wps_mode = event->wps_mode;
913 session = wfd_create_session(manager, event->dev_addr,
914 req_wps_mode, SESSION_DIRECTION_INCOMING);
916 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
917 MAC2SECSTR(event->dev_addr));
923 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
924 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
926 session->state = SESSION_STATE_STARTED;
927 if (session->type == SESSION_TYPE_INVITE)
928 WDS_LOGD("Invitation session");
929 else if (WFD_DEV_ROLE_GO == manager->local->dev_role)
930 session->type = SESSION_TYPE_JOIN;
932 session->type = SESSION_TYPE_NORMAL;
934 wfd_session_timer(session, 1);
936 /* Update local device */
937 manager->local->wps_mode = event->wps_mode;
939 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
940 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
942 if (session->type == SESSION_TYPE_INVITE) {
943 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
944 if (session->wps_mode != WFD_WPS_MODE_PBC) {
945 char peer_mac_address[MACSTR_LEN+1] = {0, };
947 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
948 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
950 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
951 WFD_EVENT_CONNECTION_WPS_REQ,
953 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
954 /* We have to wait until user type PIN using Keypad */
958 res = wfd_session_wps(session);
960 _wfd_notify_session_failed(manager, event->dev_addr);
962 char peer_mac_address[MACSTR_LEN+1] = {0, };
964 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
965 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
967 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
968 WFD_EVENT_CONNECTION_REQ,
973 case WFD_OEM_EVENT_PROV_DISC_RESP:
975 if (!session) { /* TODO: check validity of Event */
976 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
977 MAC2SECSTR(event->dev_addr));
981 if (session->state > SESSION_STATE_STARTED) {
982 WDS_LOGE("Unexpected event. Session is already started");
986 if (session->type == SESSION_TYPE_INVITE) {
987 WDS_LOGE("Session type is invite, ignore provision discovery response");
992 session->wps_mode = event->wps_mode;
993 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
994 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
995 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
996 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
997 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
999 session->req_wps_mode = WFD_WPS_MODE_PBC;
1002 session->state = SESSION_STATE_STARTED;
1003 wfd_session_timer(session, 1);
1005 /* Update local device */
1006 manager->local->wps_mode = event->wps_mode;
1007 WDS_LOGD("Local WPS mode is %d", session->wps_mode);
1009 if (session->wps_mode != WFD_WPS_MODE_PBC) {
1010 char peer_mac_address[MACSTR_LEN+1] = {0, };
1012 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1013 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1015 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1016 WFD_EVENT_CONNECTION_WPS_REQ,
1018 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
1019 /* We have to wait until user type PIN using Keypad */
1024 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1025 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
1026 res = wfd_session_wps(session);
1027 } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
1028 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
1029 res = wfd_session_join(session);
1031 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
1032 res = wfd_session_connect(session);
1036 _wfd_notify_session_failed(manager, event->dev_addr);
1039 case WFD_OEM_EVENT_GO_NEG_REQ:
1042 session = wfd_create_session(manager, event->dev_addr,
1043 event->wps_mode, SESSION_DIRECTION_INCOMING);
1045 WDS_LOGE("Failed to create session");
1046 __WDS_LOG_FUNC_EXIT__;
1050 session->type = SESSION_TYPE_NORMAL;
1051 session->state = SESSION_STATE_GO_NEG;
1052 wfd_session_timer(session, 1);
1053 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
1054 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
1056 char peer_mac_address[MACSTR_LEN+1] = {0, };
1057 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1058 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1060 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1061 WFD_EVENT_CONNECTION_REQ,
1064 /* Sometimes, Provision Discovery response is not received.
1065 * At this time, connection should be triggered by GO Negotiation request event */
1066 if (session->direction == SESSION_DIRECTION_OUTGOING) {
1067 if(session->wps_mode == WFD_WPS_MODE_KEYPAD && session->wps_pin[0] == '\0')
1069 res = wfd_session_connect(session);
1071 /* In autoconnection mode, MT should not send GO Nego Req
1072 before receiving the GO Nego Req from peer (MO). */
1073 if (manager->autoconnection == TRUE)
1074 res = wfd_session_connect(session);
1077 _wfd_notify_session_failed(manager, event->dev_addr);
1081 case WFD_OEM_EVENT_GO_NEG_DONE:
1084 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1085 MAC2SECSTR(event->dev_addr));
1088 manager->local->dev_role = event->dev_role;
1089 session->state = SESSION_STATE_WPS;
1093 case WFD_OEM_EVENT_WPS_DONE:
1096 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1097 MAC2SECSTR(event->dev_addr));
1100 session->state = SESSION_STATE_KEY_NEG;
1104 case WFD_OEM_EVENT_STA_CONNECTED:
1107 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1108 MAC2SECSTR(event->dev_addr));
1111 session->state = SESSION_STATE_COMPLETED;
1115 #if defined(TIZEN_FEATURE_ASP)
1116 case WFD_OEM_EVENT_ASP_PROV_START:
1118 int req_wps_mode = WFD_WPS_MODE_NONE;
1120 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
1121 req_wps_mode = WFD_WPS_MODE_KEYPAD;
1122 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
1123 req_wps_mode = WFD_WPS_MODE_DISPLAY;
1125 req_wps_mode = WFD_WPS_MODE_P2PS;
1127 session = wfd_create_session(manager, event->dev_addr,
1128 req_wps_mode, SESSION_DIRECTION_INCOMING);
1130 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
1131 MAC2SECSTR(event->dev_addr));
1135 /* Update session */
1136 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
1137 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
1139 session->state = SESSION_STATE_STARTED;
1140 wfd_session_timer(session, 1);
1143 case WFD_OEM_EVENT_ASP_PROV_DONE:
1145 int req_wps_mode = WFD_WPS_MODE_NONE;
1147 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
1148 req_wps_mode = WFD_WPS_MODE_KEYPAD;
1149 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
1150 req_wps_mode = WFD_WPS_MODE_DISPLAY;
1152 req_wps_mode = WFD_WPS_MODE_P2PS;
1154 session = (wfd_session_s*) manager->session;
1156 session = wfd_create_session(manager, event->dev_addr,
1157 req_wps_mode, SESSION_DIRECTION_INCOMING);
1159 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
1160 MAC2SECSTR(event->dev_addr));
1163 session->state = SESSION_STATE_STARTED;
1164 wfd_session_timer(session, 1);
1168 #endif /* TIZEN_FEATURE_ASP */
1170 _wfd_notify_session_failed(manager, event->dev_addr);
1175 __WDS_LOG_FUNC_EXIT__;