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"
49 static gboolean _session_timeout_cb(gpointer *user_data)
51 __WDS_LOG_FUNC_ENTER__;
52 wfd_manager_s *manager = wfd_get_manager();
53 wfd_session_s *session = (wfd_session_s*) manager->session;
54 unsigned char *peer_addr = NULL;
55 char peer_mac_address[MACSTR_LEN+1] = {0, };
58 WDS_LOGE("Invalid parameter");
61 session->connecting_120 = 0;
63 WDS_LOGD("Session timer expired");
65 peer_addr = wfd_session_get_peer_addr(session);
67 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
69 g_snprintf(peer_mac_address, MACSTR_LEN, "%s", "");
71 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
73 g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_TIME_OUT,
74 WFD_EVENT_CONNECTION_RSP,
77 wfd_session_cancel(session, peer_addr);
79 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
80 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
81 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
83 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
84 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
87 __WDS_LOG_FUNC_EXIT__;
91 static void _wfd_notify_session_failed(wfd_manager_s *manager, unsigned char *peer_addr)
93 __WDS_LOG_FUNC_ENTER__;
94 char peer_mac_address[MACSTR_LEN+1] = {0, };
96 snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
97 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
99 g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
100 WFD_EVENT_CONNECTION_RSP,
103 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
104 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
105 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__;
114 int wfd_session_timer(wfd_session_s *session, int start)
116 __WDS_LOG_FUNC_ENTER__;
119 WDS_LOGE("Invalid parameter");
120 __WDS_LOG_FUNC_EXIT__;
125 if (!session->connecting_120)
126 session->connecting_120 = 1;
128 if (session->timer > 0) {
129 WDS_LOGE("Session timer already started");
130 __WDS_LOG_FUNC_EXIT__;
133 session->timer = g_timeout_add(120000,
134 (GSourceFunc) _session_timeout_cb,
136 WDS_LOGD("Session timer started");
138 session->connecting_120 = 0;
139 if (session->timer > 0) {
140 g_source_remove(session->timer);
142 WDS_LOGD("Session timer stoped");
146 __WDS_LOG_FUNC_EXIT__;
150 // Check the session instance which has same peer address, before using this function
151 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction)
153 __WDS_LOG_FUNC_ENTER__;
154 wfd_manager_s *manager = (wfd_manager_s*) data;
155 wfd_session_s *session = NULL;
156 wfd_device_s *peer = NULL;
158 if (!data || !peer_addr) {
159 WDS_LOGE("Invalid parameter");
160 __WDS_LOG_FUNC_EXIT__;
164 WDS_LOGD("create session for peer[" MACSTR "]", MAC2STR(peer_addr));
166 if (manager->session) {
167 WDS_LOGE("Session already exist");
171 session = (wfd_session_s*) g_try_malloc0(sizeof(wfd_session_s));
173 WDS_LOGE("Failed to allocate memory for session");
174 __WDS_LOG_FUNC_EXIT__;
178 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
180 WDS_LOGE("Failed to find peer info[" MACSECSTR "]", MAC2SECSTR(peer_addr));
182 __WDS_LOG_FUNC_EXIT__;
185 peer->state = WFD_PEER_STATE_CONNECTING;
187 session->peer = peer;
188 session->req_wps_mode = wps_mode;
189 if (wps_mode == WFD_WPS_MODE_DISPLAY)
190 session->wps_mode = WFD_WPS_MODE_KEYPAD;
191 else if (wps_mode == WFD_WPS_MODE_KEYPAD)
192 session->wps_mode = WFD_WPS_MODE_DISPLAY;
194 session->wps_mode = wps_mode;
195 session->direction = direction;
196 session->state = SESSION_STATE_CREATED;
198 manager->session = session;
199 manager->local->wps_mode = session->wps_mode;
201 if (peer->dev_role == WFD_DEV_ROLE_GO &&
202 manager->local->wps_mode == WFD_WPS_MODE_DISPLAY) {
203 char *generated_pin = NULL;
204 session->wps_mode = WFD_WPS_MODE_DISPLAY;
205 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
207 if (wfd_oem_generate_pin(manager->oem_ops, &generated_pin) != 0) {
208 WDS_LOGE("Failed to generate pin");
210 __WDS_LOG_FUNC_EXIT__;
214 g_strlcpy(session->wps_pin, generated_pin, PINSTR_LEN + 1);
215 g_free(generated_pin);
218 if (peer->dev_role == WFD_DEV_ROLE_GO && manager->local->dev_role != WFD_DEV_ROLE_GO)
219 manager->local->dev_role = WFD_DEV_ROLE_GC;
221 __WDS_LOG_FUNC_EXIT__;
225 int wfd_destroy_session(void *data)
227 __WDS_LOG_FUNC_ENTER__;
228 wfd_manager_s *manager = (wfd_manager_s*) data;
229 wfd_session_s *session = NULL;
230 wfd_device_s *peer = NULL;
233 WDS_LOGE("Invalid parameter");
237 session = (wfd_session_s*) manager->session;
239 WDS_LOGE("Session not found"); // self prevent 13029
242 wfd_session_timer(session, 0);
243 peer = session->peer;
246 if (session->state == SESSION_STATE_COMPLETED)
247 peer->state = WFD_PEER_STATE_CONNECTED;
249 peer->state = WFD_PEER_STATE_DISCOVERED;
251 WDS_LOGE("Peer not found");
255 manager->session = NULL;
256 manager->local->wps_mode = WFD_WPS_MODE_PBC;
257 manager->autoconnection = 0;
258 memset(manager->auto_pin, 0x0, PINSTR_LEN);
259 if (manager->local->dev_role == WFD_DEV_ROLE_GC)
260 manager->local->dev_role = WFD_DEV_ROLE_NONE;
262 __WDS_LOG_FUNC_EXIT__;
266 int wfd_session_start(wfd_session_s *session)
268 __WDS_LOG_FUNC_ENTER__;
269 wfd_manager_s *manager = wfd_get_manager();
270 wfd_device_s *peer = NULL;
275 WDS_LOGE("Invalid parameter");
276 __WDS_LOG_FUNC_EXIT__;
280 if (session->state > SESSION_STATE_STARTED) {
281 WDS_LOGE("Invalid session state(%d)", session->state);
285 // Check: Invitation Received in Incomming case -> send prov_disc join
286 // Check: User select peer to connect with in Outgoing case -> send prov_disc wps_mdde
288 wfd_oem_stop_scan(manager->oem_ops);
290 session->state = SESSION_STATE_STARTED;
291 peer = session->peer;
292 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
294 res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
295 session->req_wps_mode, join);
297 WDS_LOGD("Failed to send provision discovery request to peer [" MACSECSTR "]",
298 MAC2SECSTR(peer->dev_addr));
299 wfd_destroy_session(manager);
300 // TODO: send notification to App
301 __WDS_LOG_FUNC_EXIT__;
305 wfd_session_timer(session, 1);
307 __WDS_LOG_FUNC_EXIT__;
312 int wfd_session_stop(wfd_session_s *session)
314 __WDS_LOG_FUNC_ENTER__;
315 wfd_manager_s *manager = wfd_get_manager();
316 wfd_device_s *peer = NULL;
320 WDS_LOGE("Invalid parameter");
321 __WDS_LOG_FUNC_EXIT__;
325 if (session->state > SESSION_STATE_CREATED) {
326 peer = session->peer;
327 if (session->direction == SESSION_DIRECTION_INCOMING) {
328 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
329 } else if (session->direction == SESSION_DIRECTION_OUTGOING) {
330 res = wfd_oem_cancel_connection(manager->oem_ops, peer->dev_addr);
333 WDS_LOGE("Failed to reject or cancel connection");
334 __WDS_LOG_FUNC_EXIT__;
339 session->state = SESSION_STATE_STOPPED;
340 wfd_destroy_session(manager);
342 __WDS_LOG_FUNC_EXIT__;
347 /* In case of incomming session, when user accept connection request, this function should be called.
348 * In case of outgoing session, when prov_disc response arrived, this function should be called.
349 * Even though peer is GO, we can use this function, which can decide using join itself.
351 int wfd_session_connect(wfd_session_s *session)
353 __WDS_LOG_FUNC_ENTER__;
354 wfd_manager_s *manager = wfd_get_manager();
355 wfd_oem_conn_param_s param;
356 wfd_device_s *peer = NULL;
360 WDS_LOGE("Invalid parameter");
361 __WDS_LOG_FUNC_EXIT__;
365 if (session->state > SESSION_STATE_GO_NEG) {
366 WDS_LOGE("Session already finished GO Negotiation");
370 session->state = SESSION_STATE_GO_NEG;
371 peer = session->peer;
373 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
374 param.wps_mode = session->wps_mode;
375 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
376 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
377 param.go_intent = session->go_intent;
378 param.freq = session->freq;
379 if(manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
380 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
382 if (session->wps_pin[0] != '\0') {
383 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
386 /* To connect with windows phone,set go_intent value to 2.
387 * As windows phone does not connect when local device act as GO.
388 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_COMPUTER ==>1 (Assume Peer Device is Windows PC)
389 * WIFI_DIRECT_SECONDARY_DEVICE_TYPE_TELEPHONE_WINDOWS_MOBILE ==>1
390 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_TELEPHONE ==> 10
392 if ((peer->pri_dev_type == 1) ||
393 ((peer->pri_dev_type == 10) && (peer->sec_dev_type == 1))) {
395 WDS_LOGD("go_intent set to %d, Windows device",param.go_intent);
398 WDS_LOGD("connection go_intent: %d", param.go_intent);
399 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
401 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
402 wfd_destroy_session(manager);
403 __WDS_LOG_FUNC_EXIT__;
407 wfd_session_timer(session, 1);
409 __WDS_LOG_FUNC_EXIT__;
413 int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
415 __WDS_LOG_FUNC_ENTER__;
416 wfd_manager_s *manager = wfd_get_manager();
419 if (!session || !session->peer) {
420 WDS_LOGE("Invalid parameter");
421 __WDS_LOG_FUNC_EXIT__;
422 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
425 if (memcmp(peer_addr, session->peer->dev_addr, MACADDR_LEN)) {
426 WDS_LOGE("Peer is not included in this session");
427 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
430 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
431 res = wfd_oem_wps_cancel(manager->oem_ops);
433 res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
436 WDS_LOGE("Failed to cancel connection");
437 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
440 wfd_destroy_session(manager);
442 __WDS_LOG_FUNC_EXIT__;
446 int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
448 __WDS_LOG_FUNC_ENTER__;
449 wfd_manager_s *manager = wfd_get_manager();
450 wfd_device_s *peer = NULL;
453 if (!session || !manager) {
454 WDS_LOGE("Invalid parameter");
455 __WDS_LOG_FUNC_EXIT__;
459 /* Invite received case state is just created */
460 if (session->state < SESSION_STATE_CREATED ||
461 session->state >= SESSION_STATE_STOPPED) {
462 WDS_LOGE("Session state is Invalid [%d]", session->state);
463 __WDS_LOG_FUNC_EXIT__;
468 * TODO: check session status and do proper work
469 * for example, reject prov_disc, reject nego, stop wps, etc.
473 peer = session->peer;
475 if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
476 res = wfd_oem_wps_cancel(manager->oem_ops);
478 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
480 WDS_LOGE("Failed to reject connection");
481 __WDS_LOG_FUNC_EXIT__;
485 wfd_destroy_session(manager);
486 // TODO: send notification to App
488 __WDS_LOG_FUNC_EXIT__;
492 int wfd_session_join(wfd_session_s *session)
494 __WDS_LOG_FUNC_ENTER__;
495 wfd_manager_s *manager = wfd_get_manager();
496 wfd_oem_conn_param_s param;
497 wfd_device_s *peer = NULL;
501 WDS_LOGE("Invalid parameter");
502 __WDS_LOG_FUNC_EXIT__;
506 session->state = SESSION_STATE_WPS;
507 peer = session->peer;
509 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
510 param.wps_mode = session->wps_mode;
511 if (peer->dev_role == WFD_DEV_ROLE_GO)
512 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
513 param.go_intent = session->go_intent;
514 param.freq = session->freq;
515 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
517 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
519 WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
520 wfd_destroy_session(manager);
521 __WDS_LOG_FUNC_EXIT__;
525 wfd_session_timer(session, 1);
527 __WDS_LOG_FUNC_EXIT__;
531 int wfd_session_invite(wfd_session_s *session)
533 __WDS_LOG_FUNC_ENTER__;
534 wfd_manager_s *manager = wfd_get_manager();
535 wfd_oem_invite_param_s param;
536 wfd_device_s *peer = NULL;
537 wfd_group_s *group = NULL;
541 WDS_LOGE("Invalid parameter");
542 __WDS_LOG_FUNC_EXIT__;
546 if (session->state > SESSION_STATE_CREATED) {
547 WDS_LOGE("Invalid session state(%d)", session->state);
551 peer = session->peer;
552 group = (wfd_group_s*) manager->group;
554 memset(¶m, 0x00, sizeof(wfd_oem_invite_param_s));
555 param.ifname = strdup(group->ifname);
556 memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
558 WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
559 MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
561 res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, ¶m);
563 WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
564 wfd_destroy_session(manager);
565 __WDS_LOG_FUNC_EXIT__;
569 wfd_session_timer(session, 1);
571 __WDS_LOG_FUNC_EXIT__;
575 int wfd_session_wps(wfd_session_s *session)
577 __WDS_LOG_FUNC_ENTER__;
578 wfd_manager_s *manager = wfd_get_manager();
579 wfd_device_s *peer = NULL;
583 WDS_LOGE("Invalid parameter");
584 __WDS_LOG_FUNC_EXIT__;
588 if (session->state > SESSION_STATE_WPS) {
589 WDS_LOGE("Session already starts WPS");
593 session->state = SESSION_STATE_WPS;
594 peer = session->peer;
596 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
597 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
598 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
600 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
601 wfd_oem_conn_param_s param;
602 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
603 param.wps_mode = session->wps_mode;
604 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
605 param.freq = session->freq; // currently not used
606 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
607 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
610 WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
611 wfd_destroy_session(manager);
612 __WDS_LOG_FUNC_EXIT__;
616 __WDS_LOG_FUNC_EXIT__;
620 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
622 __WDS_LOG_FUNC_ENTER__;
623 wfd_device_s *peer = NULL;
626 WDS_LOGE("Invalid parameter");
630 peer = session->peer;
632 __WDS_LOG_FUNC_EXIT__;
636 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
638 __WDS_LOG_FUNC_ENTER__;
639 wfd_device_s *peer = NULL;
641 if (!session || !session->peer) {
642 WDS_LOGE("Invalid parameter");
646 peer = session->peer;
648 __WDS_LOG_FUNC_EXIT__;
649 return peer->dev_addr;
653 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
655 __WDS_LOG_FUNC_ENTER__;
657 __WDS_LOG_FUNC_EXIT__;
661 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
663 __WDS_LOG_FUNC_ENTER__;
665 __WDS_LOG_FUNC_EXIT__;
669 int wfd_session_set_freq(wfd_session_s *session, int freq)
671 __WDS_LOG_FUNC_ENTER__;
673 __WDS_LOG_FUNC_EXIT__;
677 int wfd_session_get_state(wfd_session_s *session)
679 __WDS_LOG_FUNC_ENTER__;
681 __WDS_LOG_FUNC_EXIT__;
685 int wfd_session_set_state(wfd_session_s *session, int state)
687 __WDS_LOG_FUNC_ENTER__;
689 __WDS_LOG_FUNC_EXIT__;
694 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
696 __WDS_LOG_FUNC_ENTER__;
697 wfd_session_s *session = NULL;
700 if (!manager || !event) {
701 WDS_LOGE("Invalid parameter");
705 WDS_LOGD("event ID [%d]", event->event_id);
706 session = manager->session;
708 switch (event->event_id) {
709 case WFD_OEM_EVENT_PROV_DISC_REQ:
711 int req_wps_mode = WFD_WPS_MODE_NONE;
713 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
714 req_wps_mode = WFD_WPS_MODE_KEYPAD;
715 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
716 req_wps_mode = WFD_WPS_MODE_DISPLAY;
718 req_wps_mode = WFD_WPS_MODE_PBC;
721 /* Only peer initiated connection or invitation session can be allowed */
723 if (session->type != SESSION_TYPE_INVITE) {
724 WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
725 MAC2SECSTR(event->dev_addr));
728 WDS_LOGD("=====> session already exist. (invitation session)");
729 session->req_wps_mode = req_wps_mode;
730 session->wps_mode = event->wps_mode;
732 session = wfd_create_session(manager, event->dev_addr,
733 req_wps_mode, SESSION_DIRECTION_INCOMING);
735 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
736 MAC2SECSTR(event->dev_addr));
742 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
743 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
745 session->state = SESSION_STATE_STARTED;
746 if (session->type == SESSION_TYPE_INVITE) {
747 WDS_LOGD("Invitation session");
748 } else if (WFD_DEV_ROLE_GO == manager->local->dev_role) {
749 session->type = SESSION_TYPE_JOIN;
751 session->type = SESSION_TYPE_NORMAL;
753 wfd_session_timer(session, 1);
755 /* Update local device */
756 manager->local->wps_mode = event->wps_mode;
758 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
760 if (session->type == SESSION_TYPE_INVITE) {
761 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
762 if (session->wps_mode != WFD_WPS_MODE_PBC) {
763 char peer_mac_address[MACSTR_LEN+1] = {0, };
765 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
766 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
768 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
769 WFD_EVENT_CONNECTION_WPS_REQ,
771 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
772 /* We have to wait until user type PIN using Keypad */
776 res = wfd_session_wps(session);
778 _wfd_notify_session_failed(manager, event->dev_addr);
780 char peer_mac_address[MACSTR_LEN+1] = {0, };
782 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
783 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
785 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
786 WFD_EVENT_CONNECTION_REQ,
791 case WFD_OEM_EVENT_PROV_DISC_RESP:
793 if (!session) { // TODO: check validity of Event
794 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
795 MAC2SECSTR(event->dev_addr));
799 if (session->state > SESSION_STATE_STARTED) {
800 WDS_LOGE("Unexpected event. Session is already started");
804 if (session->type == SESSION_TYPE_INVITE) {
805 WDS_LOGE("Session type is invite, ignore provision discovery response");
810 session->wps_mode = event->wps_mode;
811 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
812 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
813 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
814 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
815 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
817 session->req_wps_mode = WFD_WPS_MODE_PBC;
819 session->state = SESSION_STATE_STARTED;
820 wfd_session_timer(session, 1);
822 /* Update local device */
823 manager->local->wps_mode = event->wps_mode;
824 WDS_LOGD("Local WPS mode is %d", session->wps_mode);
826 if (session->wps_mode != WFD_WPS_MODE_PBC) {
827 char peer_mac_address[MACSTR_LEN+1] = {0, };
829 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
830 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
832 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
833 WFD_EVENT_CONNECTION_WPS_REQ,
835 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
836 /* We have to wait until user type PIN using Keypad */
841 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
842 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
843 res = wfd_session_wps(session);
844 } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
845 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
846 res = wfd_session_join(session);
848 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
849 res = wfd_session_connect(session);
853 _wfd_notify_session_failed(manager, event->dev_addr);
855 case WFD_OEM_EVENT_GO_NEG_REQ:
857 // TODO: check whether connection is started by negotiation not by prov_disc
858 WDS_LOGE("Unexpected event. Session not exist [peer: " MACSECSTR "]",
859 MAC2SECSTR(event->dev_addr));
862 /* Sometimes, Provision Discovery response is not received.
863 * At this time, connection should be triggered by GO Negotiation request event */
864 if (session->direction == SESSION_DIRECTION_OUTGOING) {
865 res = wfd_session_connect(session);
867 /* In autoconnection mode, MT should not send GO Nego Req
868 before receiving the GO Nego Req from peer (MO). */
869 if (manager->autoconnection == TRUE)
870 res = wfd_session_connect(session);
873 _wfd_notify_session_failed(manager, event->dev_addr);
876 case WFD_OEM_EVENT_GO_NEG_DONE:
878 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
879 MAC2SECSTR(event->dev_addr));
882 session->state = SESSION_STATE_WPS;
886 case WFD_OEM_EVENT_WPS_DONE:
888 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
889 MAC2SECSTR(event->dev_addr));
892 session->state = SESSION_STATE_KEY_NEG;
896 case WFD_OEM_EVENT_STA_CONNECTED:
898 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
899 MAC2SECSTR(event->dev_addr));
902 session->state = SESSION_STATE_COMPLETED;
909 __WDS_LOG_FUNC_EXIT__;