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) {
81 wfd_group_s *group = (wfd_group_s*) manager->group;
82 if (group && wfd_util_is_remove_group_allowed()) {
83 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
85 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
86 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
89 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
90 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
93 __WDS_LOG_FUNC_EXIT__;
97 static void _wfd_notify_session_failed(wfd_manager_s *manager, unsigned char *peer_addr)
99 __WDS_LOG_FUNC_ENTER__;
100 char peer_mac_address[MACSTR_LEN+1] = {0, };
102 snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
103 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
105 g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
106 WFD_EVENT_CONNECTION_RSP,
109 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
110 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
111 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
113 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
114 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
117 __WDS_LOG_FUNC_EXIT__;
120 int wfd_session_timer(wfd_session_s *session, int start)
122 __WDS_LOG_FUNC_ENTER__;
125 WDS_LOGE("Invalid parameter");
126 __WDS_LOG_FUNC_EXIT__;
131 if (!session->connecting_120)
132 session->connecting_120 = 1;
134 if (session->timer > 0) {
135 WDS_LOGE("Session timer already started");
136 __WDS_LOG_FUNC_EXIT__;
139 session->timer = g_timeout_add(120000,
140 (GSourceFunc) _session_timeout_cb,
142 WDS_LOGD("Session timer started");
144 session->connecting_120 = 0;
145 if (session->timer > 0) {
146 g_source_remove(session->timer);
148 WDS_LOGD("Session timer stoped");
152 __WDS_LOG_FUNC_EXIT__;
156 // Check the session instance which has same peer address, before using this function
157 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction)
159 __WDS_LOG_FUNC_ENTER__;
160 wfd_manager_s *manager = (wfd_manager_s*) data;
161 wfd_session_s *session = NULL;
162 wfd_device_s *peer = NULL;
164 if (!data || !peer_addr) {
165 WDS_LOGE("Invalid parameter");
166 __WDS_LOG_FUNC_EXIT__;
170 WDS_LOGD("create session for peer[" MACSTR "]", MAC2STR(peer_addr));
172 if (manager->session) {
173 WDS_LOGE("Session already exist");
177 session = (wfd_session_s*) g_try_malloc0(sizeof(wfd_session_s));
179 WDS_LOGE("Failed to allocate memory for session");
180 __WDS_LOG_FUNC_EXIT__;
184 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
186 WDS_LOGE("Failed to find peer info[" MACSECSTR "]", MAC2SECSTR(peer_addr));
188 __WDS_LOG_FUNC_EXIT__;
191 peer->state = WFD_PEER_STATE_CONNECTING;
193 session->peer = peer;
194 session->req_wps_mode = wps_mode;
195 if (wps_mode == WFD_WPS_MODE_DISPLAY)
196 session->wps_mode = WFD_WPS_MODE_KEYPAD;
197 else if (wps_mode == WFD_WPS_MODE_KEYPAD)
198 session->wps_mode = WFD_WPS_MODE_DISPLAY;
200 session->wps_mode = wps_mode;
201 session->direction = direction;
202 session->state = SESSION_STATE_CREATED;
204 manager->session = session;
205 manager->local->wps_mode = session->wps_mode;
207 if (peer->dev_role == WFD_DEV_ROLE_GO &&
208 manager->local->wps_mode == WFD_WPS_MODE_DISPLAY) {
209 char *generated_pin = NULL;
210 session->wps_mode = WFD_WPS_MODE_DISPLAY;
211 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
213 if (wfd_oem_generate_pin(manager->oem_ops, &generated_pin) != 0) {
214 WDS_LOGE("Failed to generate pin");
216 __WDS_LOG_FUNC_EXIT__;
220 g_strlcpy(session->wps_pin, generated_pin, PINSTR_LEN + 1);
221 g_free(generated_pin);
224 if (peer->dev_role == WFD_DEV_ROLE_GO && manager->local->dev_role != WFD_DEV_ROLE_GO)
225 manager->local->dev_role = WFD_DEV_ROLE_GC;
227 __WDS_LOG_FUNC_EXIT__;
231 int wfd_destroy_session(void *data)
233 __WDS_LOG_FUNC_ENTER__;
234 wfd_manager_s *manager = (wfd_manager_s*) data;
235 wfd_session_s *session = NULL;
236 wfd_device_s *peer = NULL;
239 WDS_LOGE("Invalid parameter");
243 session = (wfd_session_s*) manager->session;
245 WDS_LOGE("Session not found"); // self prevent 13029
248 wfd_session_timer(session, 0);
249 peer = session->peer;
252 if (session->state == SESSION_STATE_COMPLETED)
253 peer->state = WFD_PEER_STATE_CONNECTED;
255 peer->state = WFD_PEER_STATE_DISCOVERED;
257 WDS_LOGE("Peer not found");
261 manager->session = NULL;
262 manager->local->wps_mode = WFD_WPS_MODE_PBC;
263 manager->autoconnection = 0;
264 memset(manager->auto_pin, 0x0, PINSTR_LEN);
265 if (manager->local->dev_role == WFD_DEV_ROLE_GC)
266 manager->local->dev_role = WFD_DEV_ROLE_NONE;
268 __WDS_LOG_FUNC_EXIT__;
272 int wfd_session_start(wfd_session_s *session)
274 __WDS_LOG_FUNC_ENTER__;
275 wfd_manager_s *manager = wfd_get_manager();
276 wfd_device_s *peer = NULL;
281 WDS_LOGE("Invalid parameter");
282 __WDS_LOG_FUNC_EXIT__;
286 if (session->state > SESSION_STATE_STARTED) {
287 WDS_LOGE("Invalid session state(%d)", session->state);
291 // Check: Invitation Received in Incomming case -> send prov_disc join
292 // Check: User select peer to connect with in Outgoing case -> send prov_disc wps_mdde
294 wfd_oem_stop_scan(manager->oem_ops);
296 session->state = SESSION_STATE_STARTED;
297 peer = session->peer;
298 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
300 res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
301 session->req_wps_mode, join);
303 WDS_LOGD("Failed to send provision discovery request to peer [" MACSECSTR "]",
304 MAC2SECSTR(peer->dev_addr));
305 wfd_destroy_session(manager);
306 // TODO: send notification to App
307 __WDS_LOG_FUNC_EXIT__;
311 wfd_session_timer(session, 1);
313 __WDS_LOG_FUNC_EXIT__;
318 int wfd_session_stop(wfd_session_s *session)
320 __WDS_LOG_FUNC_ENTER__;
321 wfd_manager_s *manager = wfd_get_manager();
322 wfd_device_s *peer = NULL;
326 WDS_LOGE("Invalid parameter");
327 __WDS_LOG_FUNC_EXIT__;
331 if (session->state > SESSION_STATE_CREATED) {
332 peer = session->peer;
333 if (session->direction == SESSION_DIRECTION_INCOMING) {
334 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
335 } else if (session->direction == SESSION_DIRECTION_OUTGOING) {
336 res = wfd_oem_cancel_connection(manager->oem_ops, peer->dev_addr);
339 WDS_LOGE("Failed to reject or cancel connection");
340 __WDS_LOG_FUNC_EXIT__;
345 session->state = SESSION_STATE_STOPPED;
346 wfd_destroy_session(manager);
348 __WDS_LOG_FUNC_EXIT__;
353 /* In case of incomming session, when user accept connection request, this function should be called.
354 * In case of outgoing session, when prov_disc response arrived, this function should be called.
355 * Even though peer is GO, we can use this function, which can decide using join itself.
357 int wfd_session_connect(wfd_session_s *session)
359 __WDS_LOG_FUNC_ENTER__;
360 wfd_manager_s *manager = wfd_get_manager();
361 wfd_oem_conn_param_s param;
362 wfd_device_s *peer = NULL;
366 WDS_LOGE("Invalid parameter");
367 __WDS_LOG_FUNC_EXIT__;
371 if (session->state > SESSION_STATE_GO_NEG) {
372 WDS_LOGE("Session already finished GO Negotiation");
376 session->state = SESSION_STATE_GO_NEG;
377 peer = session->peer;
379 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
380 param.wps_mode = session->wps_mode;
381 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
382 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
383 param.go_intent = session->go_intent;
384 param.freq = session->freq;
385 if(manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
386 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
388 if (session->wps_pin[0] != '\0') {
389 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
392 /* To connect with windows phone,set go_intent value to 2.
393 * As windows phone does not connect when local device act as GO.
394 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_COMPUTER ==>1 (Assume Peer Device is Windows PC)
395 * WIFI_DIRECT_SECONDARY_DEVICE_TYPE_TELEPHONE_WINDOWS_MOBILE ==>1
396 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_TELEPHONE ==> 10
398 if ((peer->pri_dev_type == 1) ||
399 ((peer->pri_dev_type == 10) && (peer->sec_dev_type == 1))) {
401 WDS_LOGD("go_intent set to %d, Windows device",param.go_intent);
404 WDS_LOGD("connection go_intent: %d", param.go_intent);
405 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
407 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
408 wfd_destroy_session(manager);
409 __WDS_LOG_FUNC_EXIT__;
413 wfd_session_timer(session, 1);
415 __WDS_LOG_FUNC_EXIT__;
419 int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
421 __WDS_LOG_FUNC_ENTER__;
422 wfd_manager_s *manager = wfd_get_manager();
425 if (!session || !session->peer) {
426 WDS_LOGE("Invalid parameter");
427 __WDS_LOG_FUNC_EXIT__;
428 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
431 if (memcmp(peer_addr, session->peer->dev_addr, MACADDR_LEN)) {
432 WDS_LOGE("Peer is not included in this session");
433 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
436 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
437 res = wfd_oem_wps_cancel(manager->oem_ops);
439 res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
442 WDS_LOGE("Failed to cancel connection");
443 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
446 wfd_destroy_session(manager);
448 __WDS_LOG_FUNC_EXIT__;
452 int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
454 __WDS_LOG_FUNC_ENTER__;
455 wfd_manager_s *manager = wfd_get_manager();
456 wfd_device_s *peer = NULL;
459 if (!session || !manager) {
460 WDS_LOGE("Invalid parameter");
461 __WDS_LOG_FUNC_EXIT__;
465 /* Invite received case state is just created */
466 if (session->state < SESSION_STATE_CREATED ||
467 session->state >= SESSION_STATE_STOPPED) {
468 WDS_LOGE("Session state is Invalid [%d]", session->state);
469 __WDS_LOG_FUNC_EXIT__;
474 * TODO: check session status and do proper work
475 * for example, reject prov_disc, reject nego, stop wps, etc.
479 peer = session->peer;
481 if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
482 res = wfd_oem_wps_cancel(manager->oem_ops);
484 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
486 WDS_LOGE("Failed to reject connection");
487 __WDS_LOG_FUNC_EXIT__;
491 wfd_destroy_session(manager);
492 // TODO: send notification to App
494 __WDS_LOG_FUNC_EXIT__;
498 int wfd_session_join(wfd_session_s *session)
500 __WDS_LOG_FUNC_ENTER__;
501 wfd_manager_s *manager = wfd_get_manager();
502 wfd_oem_conn_param_s param;
503 wfd_device_s *peer = NULL;
507 WDS_LOGE("Invalid parameter");
508 __WDS_LOG_FUNC_EXIT__;
512 session->state = SESSION_STATE_WPS;
513 peer = session->peer;
515 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
516 param.wps_mode = session->wps_mode;
517 if (peer->dev_role == WFD_DEV_ROLE_GO)
518 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
519 param.go_intent = session->go_intent;
520 param.freq = session->freq;
521 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
523 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
525 WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
526 wfd_destroy_session(manager);
527 __WDS_LOG_FUNC_EXIT__;
531 wfd_session_timer(session, 1);
533 __WDS_LOG_FUNC_EXIT__;
537 int wfd_session_invite(wfd_session_s *session)
539 __WDS_LOG_FUNC_ENTER__;
540 wfd_manager_s *manager = wfd_get_manager();
541 wfd_oem_invite_param_s param;
542 wfd_device_s *peer = NULL;
543 wfd_group_s *group = NULL;
547 WDS_LOGE("Invalid parameter");
548 __WDS_LOG_FUNC_EXIT__;
552 if (session->state > SESSION_STATE_CREATED) {
553 WDS_LOGE("Invalid session state(%d)", session->state);
557 peer = session->peer;
558 group = (wfd_group_s*) manager->group;
560 memset(¶m, 0x00, sizeof(wfd_oem_invite_param_s));
561 param.ifname = strdup(group->ifname);
562 memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
564 WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
565 MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
567 res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, ¶m);
569 WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
570 wfd_destroy_session(manager);
571 __WDS_LOG_FUNC_EXIT__;
575 wfd_session_timer(session, 1);
577 __WDS_LOG_FUNC_EXIT__;
581 int wfd_session_wps(wfd_session_s *session)
583 __WDS_LOG_FUNC_ENTER__;
584 wfd_manager_s *manager = wfd_get_manager();
585 wfd_device_s *peer = NULL;
589 WDS_LOGE("Invalid parameter");
590 __WDS_LOG_FUNC_EXIT__;
594 if (session->state > SESSION_STATE_WPS) {
595 WDS_LOGE("Session already starts WPS");
599 session->state = SESSION_STATE_WPS;
600 peer = session->peer;
602 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
603 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
604 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
606 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
607 wfd_oem_conn_param_s param;
608 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
609 param.wps_mode = session->wps_mode;
610 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
611 param.freq = session->freq; // currently not used
612 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
613 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
616 WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
617 wfd_destroy_session(manager);
618 __WDS_LOG_FUNC_EXIT__;
622 __WDS_LOG_FUNC_EXIT__;
626 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
628 __WDS_LOG_FUNC_ENTER__;
629 wfd_device_s *peer = NULL;
632 WDS_LOGE("Invalid parameter");
636 peer = session->peer;
638 __WDS_LOG_FUNC_EXIT__;
642 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
644 __WDS_LOG_FUNC_ENTER__;
645 wfd_device_s *peer = NULL;
647 if (!session || !session->peer) {
648 WDS_LOGE("Invalid parameter");
652 peer = session->peer;
654 __WDS_LOG_FUNC_EXIT__;
655 return peer->dev_addr;
659 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
661 __WDS_LOG_FUNC_ENTER__;
663 __WDS_LOG_FUNC_EXIT__;
667 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
669 __WDS_LOG_FUNC_ENTER__;
671 __WDS_LOG_FUNC_EXIT__;
675 int wfd_session_set_freq(wfd_session_s *session, int freq)
677 __WDS_LOG_FUNC_ENTER__;
679 __WDS_LOG_FUNC_EXIT__;
683 int wfd_session_get_state(wfd_session_s *session)
685 __WDS_LOG_FUNC_ENTER__;
687 __WDS_LOG_FUNC_EXIT__;
691 int wfd_session_set_state(wfd_session_s *session, int state)
693 __WDS_LOG_FUNC_ENTER__;
695 __WDS_LOG_FUNC_EXIT__;
700 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
702 __WDS_LOG_FUNC_ENTER__;
703 wfd_session_s *session = NULL;
706 if (!manager || !event) {
707 WDS_LOGE("Invalid parameter");
711 WDS_LOGD("event ID [%d]", event->event_id);
712 session = manager->session;
714 switch (event->event_id) {
715 case WFD_OEM_EVENT_PROV_DISC_REQ:
717 int req_wps_mode = WFD_WPS_MODE_NONE;
719 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
720 req_wps_mode = WFD_WPS_MODE_KEYPAD;
721 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
722 req_wps_mode = WFD_WPS_MODE_DISPLAY;
724 req_wps_mode = WFD_WPS_MODE_PBC;
726 /* Only peer initiated connection or invitation session can be allowed */
728 if (session->type != SESSION_TYPE_INVITE) {
729 WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
730 MAC2SECSTR(event->dev_addr));
733 WDS_LOGD("=====> session already exist. (invitation session)");
734 session->req_wps_mode = req_wps_mode;
735 session->wps_mode = event->wps_mode;
737 session = wfd_create_session(manager, event->dev_addr,
738 req_wps_mode, SESSION_DIRECTION_INCOMING);
740 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
741 MAC2SECSTR(event->dev_addr));
747 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
748 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
750 session->state = SESSION_STATE_STARTED;
751 if (session->type == SESSION_TYPE_INVITE)
752 WDS_LOGD("Invitation session");
753 else if (WFD_DEV_ROLE_GO == manager->local->dev_role)
754 session->type = SESSION_TYPE_JOIN;
756 session->type = SESSION_TYPE_NORMAL;
758 wfd_session_timer(session, 1);
760 /* Update local device */
761 manager->local->wps_mode = event->wps_mode;
763 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
765 if (session->type == SESSION_TYPE_INVITE) {
766 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
767 if (session->wps_mode != WFD_WPS_MODE_PBC) {
768 char peer_mac_address[MACSTR_LEN+1] = {0, };
770 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
771 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
773 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
774 WFD_EVENT_CONNECTION_WPS_REQ,
776 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
777 /* We have to wait until user type PIN using Keypad */
781 res = wfd_session_wps(session);
783 _wfd_notify_session_failed(manager, event->dev_addr);
785 char peer_mac_address[MACSTR_LEN+1] = {0, };
787 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
788 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
790 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
791 WFD_EVENT_CONNECTION_REQ,
796 case WFD_OEM_EVENT_PROV_DISC_RESP:
798 if (!session) { // TODO: check validity of Event
799 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
800 MAC2SECSTR(event->dev_addr));
804 if (session->state > SESSION_STATE_STARTED) {
805 WDS_LOGE("Unexpected event. Session is already started");
809 if (session->type == SESSION_TYPE_INVITE) {
810 WDS_LOGE("Session type is invite, ignore provision discovery response");
815 session->wps_mode = event->wps_mode;
816 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
817 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
818 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
819 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
820 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
822 session->req_wps_mode = WFD_WPS_MODE_PBC;
825 session->state = SESSION_STATE_STARTED;
826 wfd_session_timer(session, 1);
828 /* Update local device */
829 manager->local->wps_mode = event->wps_mode;
830 WDS_LOGD("Local WPS mode is %d", session->wps_mode);
832 if (session->wps_mode != WFD_WPS_MODE_PBC) {
833 char peer_mac_address[MACSTR_LEN+1] = {0, };
835 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
836 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
838 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
839 WFD_EVENT_CONNECTION_WPS_REQ,
841 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
842 /* We have to wait until user type PIN using Keypad */
847 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
848 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
849 res = wfd_session_wps(session);
850 } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
851 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
852 res = wfd_session_join(session);
854 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
855 res = wfd_session_connect(session);
859 _wfd_notify_session_failed(manager, event->dev_addr);
862 case WFD_OEM_EVENT_GO_NEG_REQ:
865 session = wfd_create_session(manager, event->dev_addr,
866 event->wps_mode, SESSION_DIRECTION_INCOMING);
868 WDS_LOGE("Failed to create session");
869 __WDS_LOG_FUNC_EXIT__;
873 session->type = SESSION_TYPE_NORMAL;
874 session->state = SESSION_STATE_GO_NEG;
875 wfd_session_timer(session, 1);
876 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
878 char peer_mac_address[MACSTR_LEN+1] = {0, };
879 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
880 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
882 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
883 WFD_EVENT_CONNECTION_REQ,
886 /* Sometimes, Provision Discovery response is not received.
887 * At this time, connection should be triggered by GO Negotiation request event */
888 if (session->direction == SESSION_DIRECTION_OUTGOING) {
889 res = wfd_session_connect(session);
891 /* In autoconnection mode, MT should not send GO Nego Req
892 before receiving the GO Nego Req from peer (MO). */
893 if (manager->autoconnection == TRUE)
894 res = wfd_session_connect(session);
897 _wfd_notify_session_failed(manager, event->dev_addr);
901 case WFD_OEM_EVENT_GO_NEG_DONE:
904 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
905 MAC2SECSTR(event->dev_addr));
908 manager->local->dev_role = event->dev_role;
909 session->state = SESSION_STATE_WPS;
913 case WFD_OEM_EVENT_WPS_DONE:
916 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
917 MAC2SECSTR(event->dev_addr));
920 session->state = SESSION_STATE_KEY_NEG;
924 case WFD_OEM_EVENT_STA_CONNECTED:
927 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
928 MAC2SECSTR(event->dev_addr));
931 session->state = SESSION_STATE_COMPLETED;
938 __WDS_LOG_FUNC_EXIT__;