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 wfd_oem_stop_scan(manager->oem_ops);
372 session->state = SESSION_STATE_GO_NEG;
373 peer = session->peer;
375 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
376 param.wps_mode = session->wps_mode;
377 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
378 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
379 param.go_intent = session->go_intent;
380 param.freq = session->freq;
381 if(manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
382 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
384 if (session->wps_pin[0] != '\0') {
385 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
388 /* To connect with windows phone,set go_intent value to 2.
389 * As windows phone does not connect when local device act as GO.
390 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_COMPUTER ==>1 (Assume Peer Device is Windows PC)
391 * WIFI_DIRECT_SECONDARY_DEVICE_TYPE_TELEPHONE_WINDOWS_MOBILE ==>1
392 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_TELEPHONE ==> 10
394 if ((peer->pri_dev_type == 1) ||
395 ((peer->pri_dev_type == 10) && (peer->sec_dev_type == 1))) {
397 WDS_LOGD("go_intent set to %d, Windows device",param.go_intent);
400 WDS_LOGD("connection go_intent: %d", param.go_intent);
401 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
403 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
404 wfd_destroy_session(manager);
405 __WDS_LOG_FUNC_EXIT__;
409 wfd_session_timer(session, 1);
411 __WDS_LOG_FUNC_EXIT__;
415 int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
417 __WDS_LOG_FUNC_ENTER__;
418 wfd_manager_s *manager = wfd_get_manager();
421 if (!session || !session->peer) {
422 WDS_LOGE("Invalid parameter");
423 __WDS_LOG_FUNC_EXIT__;
424 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
427 if (memcmp(peer_addr, session->peer->dev_addr, MACADDR_LEN)) {
428 WDS_LOGE("Peer is not included in this session");
429 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
432 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
433 res = wfd_oem_wps_cancel(manager->oem_ops);
435 res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
438 WDS_LOGE("Failed to cancel connection");
439 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
442 wfd_destroy_session(manager);
444 __WDS_LOG_FUNC_EXIT__;
448 int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
450 __WDS_LOG_FUNC_ENTER__;
451 wfd_manager_s *manager = wfd_get_manager();
452 wfd_device_s *peer = NULL;
455 if (!session || !manager) {
456 WDS_LOGE("Invalid parameter");
457 __WDS_LOG_FUNC_EXIT__;
461 /* Invite received case state is just created */
462 if (session->state < SESSION_STATE_CREATED ||
463 session->state >= SESSION_STATE_STOPPED) {
464 WDS_LOGE("Session state is Invalid [%d]", session->state);
465 __WDS_LOG_FUNC_EXIT__;
470 * TODO: check session status and do proper work
471 * for example, reject prov_disc, reject nego, stop wps, etc.
475 peer = session->peer;
477 if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
478 res = wfd_oem_wps_cancel(manager->oem_ops);
480 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
482 WDS_LOGE("Failed to reject connection");
483 __WDS_LOG_FUNC_EXIT__;
487 wfd_destroy_session(manager);
488 // TODO: send notification to App
490 __WDS_LOG_FUNC_EXIT__;
494 int wfd_session_join(wfd_session_s *session)
496 __WDS_LOG_FUNC_ENTER__;
497 wfd_manager_s *manager = wfd_get_manager();
498 wfd_oem_conn_param_s param;
499 wfd_device_s *peer = NULL;
503 WDS_LOGE("Invalid parameter");
504 __WDS_LOG_FUNC_EXIT__;
508 session->state = SESSION_STATE_WPS;
509 peer = session->peer;
511 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
512 param.wps_mode = session->wps_mode;
513 if (peer->dev_role == WFD_DEV_ROLE_GO)
514 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
515 param.go_intent = session->go_intent;
516 param.freq = session->freq;
517 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
519 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
521 WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
522 wfd_destroy_session(manager);
523 __WDS_LOG_FUNC_EXIT__;
527 wfd_session_timer(session, 1);
529 __WDS_LOG_FUNC_EXIT__;
533 int wfd_session_invite(wfd_session_s *session)
535 __WDS_LOG_FUNC_ENTER__;
536 wfd_manager_s *manager = wfd_get_manager();
537 wfd_oem_invite_param_s param;
538 wfd_device_s *peer = NULL;
539 wfd_group_s *group = NULL;
543 WDS_LOGE("Invalid parameter");
544 __WDS_LOG_FUNC_EXIT__;
548 if (session->state > SESSION_STATE_CREATED) {
549 WDS_LOGE("Invalid session state(%d)", session->state);
553 peer = session->peer;
554 group = (wfd_group_s*) manager->group;
556 memset(¶m, 0x00, sizeof(wfd_oem_invite_param_s));
557 param.ifname = strdup(group->ifname);
558 memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
560 WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
561 MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
563 res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, ¶m);
565 WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
566 wfd_destroy_session(manager);
567 __WDS_LOG_FUNC_EXIT__;
571 wfd_session_timer(session, 1);
573 __WDS_LOG_FUNC_EXIT__;
577 int wfd_session_wps(wfd_session_s *session)
579 __WDS_LOG_FUNC_ENTER__;
580 wfd_manager_s *manager = wfd_get_manager();
581 wfd_device_s *peer = NULL;
585 WDS_LOGE("Invalid parameter");
586 __WDS_LOG_FUNC_EXIT__;
590 if (session->state > SESSION_STATE_WPS) {
591 WDS_LOGE("Session already starts WPS");
595 session->state = SESSION_STATE_WPS;
596 peer = session->peer;
598 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
599 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
600 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
602 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
603 wfd_oem_conn_param_s param;
604 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
605 param.wps_mode = session->wps_mode;
606 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
607 param.freq = session->freq; // currently not used
608 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
609 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
612 WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
613 wfd_destroy_session(manager);
614 __WDS_LOG_FUNC_EXIT__;
618 __WDS_LOG_FUNC_EXIT__;
622 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
624 __WDS_LOG_FUNC_ENTER__;
625 wfd_device_s *peer = NULL;
628 WDS_LOGE("Invalid parameter");
632 peer = session->peer;
634 __WDS_LOG_FUNC_EXIT__;
638 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
640 __WDS_LOG_FUNC_ENTER__;
641 wfd_device_s *peer = NULL;
643 if (!session || !session->peer) {
644 WDS_LOGE("Invalid parameter");
648 peer = session->peer;
650 __WDS_LOG_FUNC_EXIT__;
651 return peer->dev_addr;
655 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
657 __WDS_LOG_FUNC_ENTER__;
659 __WDS_LOG_FUNC_EXIT__;
663 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
665 __WDS_LOG_FUNC_ENTER__;
667 __WDS_LOG_FUNC_EXIT__;
671 int wfd_session_set_freq(wfd_session_s *session, int freq)
673 __WDS_LOG_FUNC_ENTER__;
675 __WDS_LOG_FUNC_EXIT__;
679 int wfd_session_get_state(wfd_session_s *session)
681 __WDS_LOG_FUNC_ENTER__;
683 __WDS_LOG_FUNC_EXIT__;
687 int wfd_session_set_state(wfd_session_s *session, int state)
689 __WDS_LOG_FUNC_ENTER__;
691 __WDS_LOG_FUNC_EXIT__;
696 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
698 __WDS_LOG_FUNC_ENTER__;
699 wfd_session_s *session = NULL;
702 if (!manager || !event) {
703 WDS_LOGE("Invalid parameter");
707 WDS_LOGD("event ID [%d]", event->event_id);
708 session = manager->session;
710 switch (event->event_id) {
711 case WFD_OEM_EVENT_PROV_DISC_REQ:
713 int req_wps_mode = WFD_WPS_MODE_NONE;
715 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
716 req_wps_mode = WFD_WPS_MODE_KEYPAD;
717 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
718 req_wps_mode = WFD_WPS_MODE_DISPLAY;
720 req_wps_mode = WFD_WPS_MODE_PBC;
723 /* Only peer initiated connection or invitation session can be allowed */
725 if (session->type != SESSION_TYPE_INVITE) {
726 WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
727 MAC2SECSTR(event->dev_addr));
730 WDS_LOGD("=====> session already exist. (invitation session)");
731 session->req_wps_mode = req_wps_mode;
732 session->wps_mode = event->wps_mode;
734 session = wfd_create_session(manager, event->dev_addr,
735 req_wps_mode, SESSION_DIRECTION_INCOMING);
737 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
738 MAC2SECSTR(event->dev_addr));
744 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
745 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
747 session->state = SESSION_STATE_STARTED;
748 if (session->type == SESSION_TYPE_INVITE) {
749 WDS_LOGD("Invitation session");
750 } else if (WFD_DEV_ROLE_GO == manager->local->dev_role) {
751 session->type = SESSION_TYPE_JOIN;
753 session->type = SESSION_TYPE_NORMAL;
755 wfd_session_timer(session, 1);
757 /* Update local device */
758 manager->local->wps_mode = event->wps_mode;
760 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
762 if (session->type == SESSION_TYPE_INVITE) {
763 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
764 if (session->wps_mode != WFD_WPS_MODE_PBC) {
765 char peer_mac_address[MACSTR_LEN+1] = {0, };
767 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
768 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
770 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
771 WFD_EVENT_CONNECTION_WPS_REQ,
773 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
774 /* We have to wait until user type PIN using Keypad */
778 res = wfd_session_wps(session);
780 _wfd_notify_session_failed(manager, event->dev_addr);
782 char peer_mac_address[MACSTR_LEN+1] = {0, };
784 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
785 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
787 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
788 WFD_EVENT_CONNECTION_REQ,
793 case WFD_OEM_EVENT_PROV_DISC_RESP:
795 if (!session) { // TODO: check validity of Event
796 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
797 MAC2SECSTR(event->dev_addr));
801 if (session->state > SESSION_STATE_STARTED) {
802 WDS_LOGE("Unexpected event. Session is already started");
806 if (session->type == SESSION_TYPE_INVITE) {
807 WDS_LOGE("Session type is invite, ignore provision discovery response");
812 session->wps_mode = event->wps_mode;
813 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
814 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
815 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
816 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
817 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
819 session->req_wps_mode = WFD_WPS_MODE_PBC;
821 session->state = SESSION_STATE_STARTED;
822 wfd_session_timer(session, 1);
824 /* Update local device */
825 manager->local->wps_mode = event->wps_mode;
826 WDS_LOGD("Local WPS mode is %d", session->wps_mode);
828 if (session->wps_mode != WFD_WPS_MODE_PBC) {
829 char peer_mac_address[MACSTR_LEN+1] = {0, };
831 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
832 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
834 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
835 WFD_EVENT_CONNECTION_WPS_REQ,
837 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
838 /* We have to wait until user type PIN using Keypad */
843 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
844 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
845 res = wfd_session_wps(session);
846 } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
847 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
848 res = wfd_session_join(session);
850 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
851 res = wfd_session_connect(session);
855 _wfd_notify_session_failed(manager, event->dev_addr);
857 case WFD_OEM_EVENT_GO_NEG_REQ:
859 // TODO: check whether connection is started by negotiation not by prov_disc
860 WDS_LOGE("Unexpected event. Session not exist [peer: " MACSECSTR "]",
861 MAC2SECSTR(event->dev_addr));
864 /* Sometimes, Provision Discovery response is not received.
865 * At this time, connection should be triggered by GO Negotiation request event */
866 if (session->direction == SESSION_DIRECTION_OUTGOING) {
867 res = wfd_session_connect(session);
869 /* In autoconnection mode, MT should not send GO Nego Req
870 before receiving the GO Nego Req from peer (MO). */
871 if (manager->autoconnection == TRUE)
872 res = wfd_session_connect(session);
875 _wfd_notify_session_failed(manager, event->dev_addr);
878 case WFD_OEM_EVENT_GO_NEG_DONE:
880 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
881 MAC2SECSTR(event->dev_addr));
884 session->state = SESSION_STATE_WPS;
888 case WFD_OEM_EVENT_WPS_DONE:
890 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
891 MAC2SECSTR(event->dev_addr));
894 session->state = SESSION_STATE_KEY_NEG;
898 case WFD_OEM_EVENT_STA_CONNECTED:
900 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
901 MAC2SECSTR(event->dev_addr));
904 session->state = SESSION_STATE_COMPLETED;
911 __WDS_LOG_FUNC_EXIT__;