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);
66 if (peer_addr != NULL)
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,
157 * before using this function */
158 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction)
160 __WDS_LOG_FUNC_ENTER__;
161 wfd_manager_s *manager = (wfd_manager_s*) data;
162 wfd_session_s *session = NULL;
163 wfd_device_s *peer = NULL;
165 if (!data || !peer_addr) {
166 WDS_LOGE("Invalid parameter");
167 __WDS_LOG_FUNC_EXIT__;
171 WDS_LOGD("create session for peer[" MACSTR "]", MAC2STR(peer_addr));
173 if (manager->session) {
174 WDS_LOGE("Session already exist");
178 session = (wfd_session_s*) g_try_malloc0(sizeof(wfd_session_s));
180 WDS_LOGE("Failed to allocate memory for session");
181 __WDS_LOG_FUNC_EXIT__;
185 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
187 WDS_LOGE("Failed to find peer info[" MACSECSTR "]", MAC2SECSTR(peer_addr));
189 __WDS_LOG_FUNC_EXIT__;
192 peer->state = WFD_PEER_STATE_CONNECTING;
194 session->peer = peer;
195 session->req_wps_mode = wps_mode;
196 if (wps_mode == WFD_WPS_MODE_DISPLAY)
197 session->wps_mode = WFD_WPS_MODE_KEYPAD;
198 else if (wps_mode == WFD_WPS_MODE_KEYPAD)
199 session->wps_mode = WFD_WPS_MODE_DISPLAY;
201 session->wps_mode = wps_mode;
202 session->direction = direction;
203 session->state = SESSION_STATE_CREATED;
205 manager->session = session;
206 manager->local->wps_mode = session->wps_mode;
208 if (peer->dev_role == WFD_DEV_ROLE_GO &&
209 manager->local->wps_mode == WFD_WPS_MODE_DISPLAY) {
210 char *generated_pin = NULL;
211 session->wps_mode = WFD_WPS_MODE_DISPLAY;
212 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
214 if (wfd_oem_generate_pin(manager->oem_ops, &generated_pin) != 0) {
215 WDS_LOGE("Failed to generate pin");
217 __WDS_LOG_FUNC_EXIT__;
221 g_strlcpy(session->wps_pin, generated_pin, PINSTR_LEN + 1);
222 g_free(generated_pin);
225 if (peer->dev_role == WFD_DEV_ROLE_GO && manager->local->dev_role != WFD_DEV_ROLE_GO)
226 manager->local->dev_role = WFD_DEV_ROLE_GC;
228 __WDS_LOG_FUNC_EXIT__;
232 int wfd_destroy_session(void *data)
234 __WDS_LOG_FUNC_ENTER__;
235 wfd_manager_s *manager = (wfd_manager_s*) data;
236 wfd_session_s *session = NULL;
237 wfd_device_s *peer = NULL;
240 WDS_LOGE("Invalid parameter");
244 session = (wfd_session_s*) manager->session;
246 WDS_LOGE("Session not found"); /* self prevent */
249 wfd_session_timer(session, 0);
250 peer = session->peer;
253 if (session->state == SESSION_STATE_COMPLETED)
254 peer->state = WFD_PEER_STATE_CONNECTED;
256 peer->state = WFD_PEER_STATE_DISCOVERED;
258 WDS_LOGE("Peer not found");
262 manager->session = NULL;
263 manager->local->wps_mode = WFD_WPS_MODE_PBC;
264 manager->autoconnection = 0;
265 memset(manager->auto_pin, 0x0, PINSTR_LEN);
266 if (manager->local->dev_role == WFD_DEV_ROLE_GC)
267 manager->local->dev_role = WFD_DEV_ROLE_NONE;
269 __WDS_LOG_FUNC_EXIT__;
273 int wfd_session_start(wfd_session_s *session)
275 __WDS_LOG_FUNC_ENTER__;
276 wfd_manager_s *manager = wfd_get_manager();
277 wfd_device_s *peer = NULL;
282 WDS_LOGE("Invalid parameter");
283 __WDS_LOG_FUNC_EXIT__;
287 if (session->state > SESSION_STATE_STARTED) {
288 WDS_LOGE("Invalid session state(%d)", session->state);
292 /* Check: Invitation Received in Incomming case ->
293 * send prov_disc join
295 * Check: User select peer to connect with in Outgoing case ->
296 * send prov_disc wps_mode */
298 wfd_oem_stop_scan(manager->oem_ops);
300 session->state = SESSION_STATE_STARTED;
301 peer = session->peer;
302 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
304 res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
305 session->req_wps_mode, join);
307 WDS_LOGD("Failed to send provision discovery request to peer [" MACSECSTR "]",
308 MAC2SECSTR(peer->dev_addr));
309 wfd_destroy_session(manager);
310 /* TODO: send notification to App */
311 __WDS_LOG_FUNC_EXIT__;
315 wfd_session_timer(session, 1);
317 __WDS_LOG_FUNC_EXIT__;
322 int wfd_session_stop(wfd_session_s *session)
324 __WDS_LOG_FUNC_ENTER__;
325 wfd_manager_s *manager = wfd_get_manager();
326 wfd_device_s *peer = NULL;
330 WDS_LOGE("Invalid parameter");
331 __WDS_LOG_FUNC_EXIT__;
335 if (session->state > SESSION_STATE_CREATED) {
336 peer = session->peer;
337 if (session->direction == SESSION_DIRECTION_INCOMING)
338 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
339 else if (session->direction == SESSION_DIRECTION_OUTGOING)
340 res = wfd_oem_cancel_connection(manager->oem_ops, peer->dev_addr);
343 WDS_LOGE("Failed to reject or cancel connection");
344 __WDS_LOG_FUNC_EXIT__;
349 session->state = SESSION_STATE_STOPPED;
350 wfd_destroy_session(manager);
352 __WDS_LOG_FUNC_EXIT__;
357 /* In case of incomming session, when user accept connection request, this function should be called.
358 * In case of outgoing session, when prov_disc response arrived, this function should be called.
359 * Even though peer is GO, we can use this function, which can decide using join itself.
361 int wfd_session_connect(wfd_session_s *session)
363 __WDS_LOG_FUNC_ENTER__;
364 wfd_manager_s *manager = wfd_get_manager();
365 wfd_oem_conn_param_s param;
366 wfd_device_s *peer = NULL;
370 WDS_LOGE("Invalid parameter");
371 __WDS_LOG_FUNC_EXIT__;
375 if (session->state > SESSION_STATE_GO_NEG) {
376 WDS_LOGE("Session already finished GO Negotiation");
380 session->state = SESSION_STATE_GO_NEG;
381 peer = session->peer;
383 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
384 param.wps_mode = session->wps_mode;
385 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
386 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
387 param.go_intent = session->go_intent;
388 param.freq = session->freq;
389 if (manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
390 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
392 if (session->wps_pin[0] != '\0')
393 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
395 /* To connect with windows phone,set go_intent value to 2.
396 * As windows phone does not connect when local device act as GO.
397 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_COMPUTER ==>1 (Assume Peer Device is Windows PC)
398 * WIFI_DIRECT_SECONDARY_DEVICE_TYPE_TELEPHONE_WINDOWS_MOBILE ==>1
399 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_TELEPHONE ==> 10
401 if ((peer->pri_dev_type == 1) ||
402 ((peer->pri_dev_type == 10) && (peer->sec_dev_type == 1))) {
404 WDS_LOGD("go_intent set to %d, Windows device", param.go_intent);
407 WDS_LOGD("connection go_intent: %d", param.go_intent);
408 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
410 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
411 wfd_destroy_session(manager);
412 __WDS_LOG_FUNC_EXIT__;
416 wfd_session_timer(session, 1);
418 __WDS_LOG_FUNC_EXIT__;
422 int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
424 __WDS_LOG_FUNC_ENTER__;
425 wfd_manager_s *manager = wfd_get_manager();
428 if (!session || !session->peer) {
429 WDS_LOGE("Invalid parameter");
430 __WDS_LOG_FUNC_EXIT__;
431 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
434 if (memcmp(peer_addr, session->peer->dev_addr, MACADDR_LEN)) {
435 WDS_LOGE("Peer is not included in this session");
436 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
439 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
440 res = wfd_oem_wps_cancel(manager->oem_ops);
442 res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
445 WDS_LOGE("Failed to cancel connection");
446 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
449 wfd_destroy_session(manager);
451 __WDS_LOG_FUNC_EXIT__;
455 int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
457 __WDS_LOG_FUNC_ENTER__;
458 wfd_manager_s *manager = wfd_get_manager();
459 wfd_device_s *peer = NULL;
462 if (!session || !manager) {
463 WDS_LOGE("Invalid parameter");
464 __WDS_LOG_FUNC_EXIT__;
468 /* Invite received case state is just created */
469 if (session->state < SESSION_STATE_CREATED ||
470 session->state >= SESSION_STATE_STOPPED) {
471 WDS_LOGE("Session state is Invalid [%d]", session->state);
472 __WDS_LOG_FUNC_EXIT__;
477 * TODO: check session status and do proper work
478 * for example, reject prov_disc, reject nego, stop wps, etc.
482 peer = session->peer;
484 if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
485 res = wfd_oem_wps_cancel(manager->oem_ops);
487 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
489 WDS_LOGE("Failed to reject connection");
490 __WDS_LOG_FUNC_EXIT__;
494 wfd_destroy_session(manager);
495 /* TODO: send notification to App */
497 __WDS_LOG_FUNC_EXIT__;
501 int wfd_session_join(wfd_session_s *session)
503 __WDS_LOG_FUNC_ENTER__;
504 wfd_manager_s *manager = wfd_get_manager();
505 wfd_oem_conn_param_s param;
506 wfd_device_s *peer = NULL;
510 WDS_LOGE("Invalid parameter");
511 __WDS_LOG_FUNC_EXIT__;
515 session->state = SESSION_STATE_WPS;
516 peer = session->peer;
518 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
519 param.wps_mode = session->wps_mode;
520 if (peer->dev_role == WFD_DEV_ROLE_GO)
521 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
522 param.go_intent = session->go_intent;
523 param.freq = session->freq;
524 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
526 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
528 WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
529 wfd_destroy_session(manager);
530 __WDS_LOG_FUNC_EXIT__;
534 wfd_session_timer(session, 1);
536 __WDS_LOG_FUNC_EXIT__;
540 int wfd_session_invite(wfd_session_s *session)
542 __WDS_LOG_FUNC_ENTER__;
543 wfd_manager_s *manager = wfd_get_manager();
544 wfd_oem_invite_param_s param;
545 wfd_device_s *peer = NULL;
546 wfd_group_s *group = NULL;
550 WDS_LOGE("Invalid parameter");
551 __WDS_LOG_FUNC_EXIT__;
555 if (session->state > SESSION_STATE_CREATED) {
556 WDS_LOGE("Invalid session state(%d)", session->state);
560 peer = session->peer;
561 group = (wfd_group_s*) manager->group;
563 memset(¶m, 0x00, sizeof(wfd_oem_invite_param_s));
564 param.ifname = strdup(group->ifname);
565 memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
567 WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
568 MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
570 res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, ¶m);
572 WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
573 wfd_destroy_session(manager);
574 __WDS_LOG_FUNC_EXIT__;
578 wfd_session_timer(session, 1);
580 __WDS_LOG_FUNC_EXIT__;
584 int wfd_session_wps(wfd_session_s *session)
586 __WDS_LOG_FUNC_ENTER__;
587 wfd_manager_s *manager = wfd_get_manager();
588 wfd_device_s *peer = NULL;
592 WDS_LOGE("Invalid parameter");
593 __WDS_LOG_FUNC_EXIT__;
597 if (session->state > SESSION_STATE_WPS) {
598 WDS_LOGE("Session already starts WPS");
602 session->state = SESSION_STATE_WPS;
603 peer = session->peer;
605 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
606 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
607 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
609 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
610 wfd_oem_conn_param_s param;
611 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
612 param.wps_mode = session->wps_mode;
613 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
614 param.freq = session->freq; /* currently not used */
615 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
616 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
619 WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
620 wfd_destroy_session(manager);
621 __WDS_LOG_FUNC_EXIT__;
625 __WDS_LOG_FUNC_EXIT__;
629 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
631 __WDS_LOG_FUNC_ENTER__;
632 wfd_device_s *peer = NULL;
635 WDS_LOGE("Invalid parameter");
639 peer = session->peer;
641 __WDS_LOG_FUNC_EXIT__;
645 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
647 __WDS_LOG_FUNC_ENTER__;
648 wfd_device_s *peer = NULL;
650 if (!session || !session->peer) {
651 WDS_LOGE("Invalid parameter");
655 peer = session->peer;
657 __WDS_LOG_FUNC_EXIT__;
658 return peer->dev_addr;
662 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
664 __WDS_LOG_FUNC_ENTER__;
666 __WDS_LOG_FUNC_EXIT__;
670 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
672 __WDS_LOG_FUNC_ENTER__;
674 __WDS_LOG_FUNC_EXIT__;
678 int wfd_session_set_freq(wfd_session_s *session, int freq)
680 __WDS_LOG_FUNC_ENTER__;
682 __WDS_LOG_FUNC_EXIT__;
686 int wfd_session_get_state(wfd_session_s *session)
688 __WDS_LOG_FUNC_ENTER__;
690 __WDS_LOG_FUNC_EXIT__;
694 int wfd_session_set_state(wfd_session_s *session, int state)
696 __WDS_LOG_FUNC_ENTER__;
698 __WDS_LOG_FUNC_EXIT__;
703 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
705 __WDS_LOG_FUNC_ENTER__;
706 wfd_session_s *session = NULL;
709 if (!manager || !event) {
710 WDS_LOGE("Invalid parameter");
714 WDS_LOGD("event ID [%d]", event->event_id);
715 session = manager->session;
717 switch (event->event_id) {
718 case WFD_OEM_EVENT_PROV_DISC_REQ:
720 int req_wps_mode = WFD_WPS_MODE_NONE;
722 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
723 req_wps_mode = WFD_WPS_MODE_KEYPAD;
724 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
725 req_wps_mode = WFD_WPS_MODE_DISPLAY;
727 req_wps_mode = WFD_WPS_MODE_PBC;
729 /* Only peer initiated connection or invitation session can be allowed */
731 if (session->type != SESSION_TYPE_INVITE) {
732 WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
733 MAC2SECSTR(event->dev_addr));
736 WDS_LOGD("=====> session already exist. (invitation session)");
737 session->req_wps_mode = req_wps_mode;
738 session->wps_mode = event->wps_mode;
740 session = wfd_create_session(manager, event->dev_addr,
741 req_wps_mode, SESSION_DIRECTION_INCOMING);
743 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
744 MAC2SECSTR(event->dev_addr));
750 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
751 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
753 session->state = SESSION_STATE_STARTED;
754 if (session->type == SESSION_TYPE_INVITE)
755 WDS_LOGD("Invitation session");
756 else if (WFD_DEV_ROLE_GO == manager->local->dev_role)
757 session->type = SESSION_TYPE_JOIN;
759 session->type = SESSION_TYPE_NORMAL;
761 wfd_session_timer(session, 1);
763 /* Update local device */
764 manager->local->wps_mode = event->wps_mode;
766 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
768 if (session->type == SESSION_TYPE_INVITE) {
769 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
770 if (session->wps_mode != WFD_WPS_MODE_PBC) {
771 char peer_mac_address[MACSTR_LEN+1] = {0, };
773 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
774 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
776 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
777 WFD_EVENT_CONNECTION_WPS_REQ,
779 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
780 /* We have to wait until user type PIN using Keypad */
784 res = wfd_session_wps(session);
786 _wfd_notify_session_failed(manager, event->dev_addr);
788 char peer_mac_address[MACSTR_LEN+1] = {0, };
790 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
791 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
793 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
794 WFD_EVENT_CONNECTION_REQ,
799 case WFD_OEM_EVENT_PROV_DISC_RESP:
801 if (!session) { /* TODO: check validity of Event */
802 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
803 MAC2SECSTR(event->dev_addr));
807 if (session->state > SESSION_STATE_STARTED) {
808 WDS_LOGE("Unexpected event. Session is already started");
812 if (session->type == SESSION_TYPE_INVITE) {
813 WDS_LOGE("Session type is invite, ignore provision discovery response");
818 session->wps_mode = event->wps_mode;
819 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
820 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
821 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
822 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
823 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
825 session->req_wps_mode = WFD_WPS_MODE_PBC;
828 session->state = SESSION_STATE_STARTED;
829 wfd_session_timer(session, 1);
831 /* Update local device */
832 manager->local->wps_mode = event->wps_mode;
833 WDS_LOGD("Local WPS mode is %d", session->wps_mode);
835 if (session->wps_mode != WFD_WPS_MODE_PBC) {
836 char peer_mac_address[MACSTR_LEN+1] = {0, };
838 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
839 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
841 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
842 WFD_EVENT_CONNECTION_WPS_REQ,
844 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
845 /* We have to wait until user type PIN using Keypad */
850 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
851 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
852 res = wfd_session_wps(session);
853 } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
854 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
855 res = wfd_session_join(session);
857 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
858 res = wfd_session_connect(session);
862 _wfd_notify_session_failed(manager, event->dev_addr);
865 case WFD_OEM_EVENT_GO_NEG_REQ:
868 session = wfd_create_session(manager, event->dev_addr,
869 event->wps_mode, SESSION_DIRECTION_INCOMING);
871 WDS_LOGE("Failed to create session");
872 __WDS_LOG_FUNC_EXIT__;
876 session->type = SESSION_TYPE_NORMAL;
877 session->state = SESSION_STATE_GO_NEG;
878 wfd_session_timer(session, 1);
879 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
881 char peer_mac_address[MACSTR_LEN+1] = {0, };
882 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
883 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
885 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
886 WFD_EVENT_CONNECTION_REQ,
889 /* Sometimes, Provision Discovery response is not received.
890 * At this time, connection should be triggered by GO Negotiation request event */
891 if (session->direction == SESSION_DIRECTION_OUTGOING) {
892 res = wfd_session_connect(session);
894 /* In autoconnection mode, MT should not send GO Nego Req
895 before receiving the GO Nego Req from peer (MO). */
896 if (manager->autoconnection == TRUE)
897 res = wfd_session_connect(session);
900 _wfd_notify_session_failed(manager, event->dev_addr);
904 case WFD_OEM_EVENT_GO_NEG_DONE:
907 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
908 MAC2SECSTR(event->dev_addr));
911 manager->local->dev_role = event->dev_role;
912 session->state = SESSION_STATE_WPS;
916 case WFD_OEM_EVENT_WPS_DONE:
919 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
920 MAC2SECSTR(event->dev_addr));
923 session->state = SESSION_STATE_KEY_NEG;
927 case WFD_OEM_EVENT_STA_CONNECTED:
930 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
931 MAC2SECSTR(event->dev_addr));
934 session->state = SESSION_STATE_COMPLETED;
941 __WDS_LOG_FUNC_EXIT__;