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-client.h"
44 #include "wifi-direct-state.h"
47 static gboolean _session_timeout_cb(gpointer *user_data)
49 __WDS_LOG_FUNC_ENTER__;
50 wfd_manager_s *manager = wfd_get_manager();
51 wfd_session_s *session = (wfd_session_s*) manager->session;
52 wifi_direct_client_noti_s noti;
53 unsigned char *peer_addr = NULL;
56 WDS_LOGE("Invalid parameter");
59 session->connecting_120 = 0;
61 WDS_LOGD("Session timer expired");
63 peer_addr = wfd_session_get_peer_addr(session);
65 memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
66 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
67 noti.error = WIFI_DIRECT_ERROR_CONNECTION_CANCELED;
69 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
70 wfd_client_send_event(manager, ¬i);
72 wfd_session_cancel(session, peer_addr);
74 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
75 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
76 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
78 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
79 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
82 __WDS_LOG_FUNC_EXIT__;
86 static void _wfd_notify_session_failed(wfd_manager_s *manager, unsigned char *peer_addr)
88 __WDS_LOG_FUNC_ENTER__;
89 wifi_direct_client_noti_s noti;
90 memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
91 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
92 noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
93 snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
95 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
96 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
97 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
99 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
100 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
103 wfd_client_send_event(manager, ¬i);
104 __WDS_LOG_FUNC_EXIT__;
107 int wfd_session_timer(wfd_session_s *session, int start)
109 __WDS_LOG_FUNC_ENTER__;
112 WDS_LOGE("Invalid parameter");
113 __WDS_LOG_FUNC_EXIT__;
118 if (!session->connecting_120)
119 session->connecting_120 = 1;
121 if (session->timer > 0) {
122 WDS_LOGE("Session timer already started");
123 __WDS_LOG_FUNC_EXIT__;
126 session->timer = g_timeout_add(120000,
127 (GSourceFunc) _session_timeout_cb,
129 WDS_LOGD("Session timer started");
131 session->connecting_120 = 0;
132 if (session->timer > 0) {
133 g_source_remove(session->timer);
135 WDS_LOGD("Session timer stoped");
139 __WDS_LOG_FUNC_EXIT__;
143 // Check the session instance which has same peer address, before using this function
144 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction)
146 __WDS_LOG_FUNC_ENTER__;
147 wfd_manager_s *manager = (wfd_manager_s*) data;
148 wfd_session_s *session = NULL;
149 wfd_device_s *peer = NULL;
151 if (!data || !peer_addr) {
152 WDS_LOGE("Invalid parameter");
153 __WDS_LOG_FUNC_EXIT__;
157 WDS_LOGD("create session for peer[" MACSTR "]", MAC2STR(peer_addr));
159 if (manager->session) {
160 WDS_LOGE("Session already exist");
164 session = (wfd_session_s*) g_try_malloc0(sizeof(wfd_session_s));
166 WDS_LOGE("Failed to allocate memory for session");
167 __WDS_LOG_FUNC_EXIT__;
171 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
173 WDS_LOGE("Failed to find peer info[" MACSECSTR "]", MAC2SECSTR(peer_addr));
175 __WDS_LOG_FUNC_EXIT__;
178 peer->state = WFD_PEER_STATE_CONNECTING;
180 session->peer = peer;
181 session->req_wps_mode = wps_mode;
182 if (wps_mode == WFD_WPS_MODE_DISPLAY)
183 session->wps_mode = WFD_WPS_MODE_KEYPAD;
184 else if (wps_mode == WFD_WPS_MODE_KEYPAD)
185 session->wps_mode = WFD_WPS_MODE_DISPLAY;
187 session->wps_mode = wps_mode;
188 session->direction = direction;
189 session->state = SESSION_STATE_CREATED;
191 manager->session = session;
192 manager->local->wps_mode = session->wps_mode;
193 if (peer->dev_role == WFD_DEV_ROLE_GO && manager->local->dev_role != WFD_DEV_ROLE_GO)
194 manager->local->dev_role = WFD_DEV_ROLE_GC;
196 __WDS_LOG_FUNC_EXIT__;
200 int wfd_destroy_session(void *data)
202 __WDS_LOG_FUNC_ENTER__;
203 wfd_manager_s *manager = (wfd_manager_s*) data;
204 wfd_session_s *session = NULL;
205 wfd_device_s *peer = NULL;
208 WDS_LOGE("Invalid parameter");
212 session = (wfd_session_s*) manager->session;
214 WDS_LOGE("Session not found"); // self prevent 13029
217 wfd_session_timer(session, 0);
218 peer = session->peer;
221 if (session->state == SESSION_STATE_COMPLETED)
222 peer->state = WFD_PEER_STATE_CONNECTED;
224 peer->state = WFD_PEER_STATE_DISCOVERED;
226 WDS_LOGE("Peer not found");
230 manager->session = NULL;
231 manager->local->wps_mode = WFD_WPS_MODE_PBC;
232 manager->autoconnection = 0;
233 memset(manager->auto_pin, 0x0, PINSTR_LEN);
234 if (manager->local->dev_role == WFD_DEV_ROLE_GC)
235 manager->local->dev_role = WFD_DEV_ROLE_NONE;
237 __WDS_LOG_FUNC_EXIT__;
241 int wfd_session_start(wfd_session_s *session)
243 __WDS_LOG_FUNC_ENTER__;
244 wfd_manager_s *manager = wfd_get_manager();
245 wfd_device_s *peer = NULL;
250 WDS_LOGE("Invalid parameter");
251 __WDS_LOG_FUNC_EXIT__;
255 if (session->state > SESSION_STATE_STARTED) {
256 WDS_LOGE("Invalid session state(%d)", session->state);
260 // Check: Invitation Received in Incomming case -> send prov_disc join
261 // Check: User select peer to connect with in Outgoing case -> send prov_disc wps_mdde
263 wfd_oem_stop_scan(manager->oem_ops);
265 session->state = SESSION_STATE_STARTED;
266 peer = session->peer;
267 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
269 res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
270 session->req_wps_mode, join);
272 WDS_LOGD("Failed to send provision discovery request to peer [" MACSECSTR "]",
273 MAC2SECSTR(peer->dev_addr));
274 wfd_destroy_session(manager);
275 // TODO: send notification to App
276 __WDS_LOG_FUNC_EXIT__;
280 wfd_session_timer(session, 1);
282 __WDS_LOG_FUNC_EXIT__;
287 int wfd_session_stop(wfd_session_s *session)
289 __WDS_LOG_FUNC_ENTER__;
290 wfd_manager_s *manager = wfd_get_manager();
291 wfd_device_s *peer = NULL;
295 WDS_LOGE("Invalid parameter");
296 __WDS_LOG_FUNC_EXIT__;
300 if (session->state > SESSION_STATE_CREATED) {
301 peer = session->peer;
302 if (session->direction == SESSION_DIRECTION_INCOMING) {
303 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
304 } else if (session->direction == SESSION_DIRECTION_OUTGOING) {
305 res = wfd_oem_cancel_connection(manager->oem_ops, peer->dev_addr);
308 WDS_LOGE("Failed to reject or cancel connection");
309 __WDS_LOG_FUNC_EXIT__;
314 session->state = SESSION_STATE_STOPPED;
315 wfd_destroy_session(manager);
317 __WDS_LOG_FUNC_EXIT__;
322 /* In case of incomming session, when user accept connection request, this function should be called.
323 * In case of outgoing session, when prov_disc response arrived, this function should be called.
324 * Even though peer is GO, we can use this function, which can decide using join itself.
326 int wfd_session_connect(wfd_session_s *session)
328 __WDS_LOG_FUNC_ENTER__;
329 wfd_manager_s *manager = wfd_get_manager();
330 wfd_oem_conn_param_s param;
331 wfd_device_s *peer = NULL;
335 WDS_LOGE("Invalid parameter");
336 __WDS_LOG_FUNC_EXIT__;
340 if (session->state > SESSION_STATE_GO_NEG) {
341 WDS_LOGE("Session already finished GO Negotiation");
345 wfd_oem_stop_scan(manager->oem_ops);
347 session->state = SESSION_STATE_GO_NEG;
348 peer = session->peer;
350 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
351 param.wps_mode = session->wps_mode;
352 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
353 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
354 param.go_intent = session->go_intent;
355 param.freq = session->freq;
356 if(manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
357 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
359 if (session->wps_pin[0] != '\0') {
360 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
363 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
365 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
366 wfd_destroy_session(manager);
367 __WDS_LOG_FUNC_EXIT__;
371 wfd_session_timer(session, 1);
373 __WDS_LOG_FUNC_EXIT__;
377 int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
379 __WDS_LOG_FUNC_ENTER__;
380 wfd_manager_s *manager = wfd_get_manager();
383 if (!session || !session->peer) {
384 WDS_LOGE("Invalid parameter");
385 __WDS_LOG_FUNC_EXIT__;
386 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
389 if (memcmp(peer_addr, session->peer->dev_addr, MACADDR_LEN)) {
390 WDS_LOGE("Peer is not included in this session");
391 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
394 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
395 res = wfd_oem_wps_cancel(manager->oem_ops);
397 res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
400 WDS_LOGE("Failed to cancel connection");
401 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
404 wfd_destroy_session(manager);
406 __WDS_LOG_FUNC_EXIT__;
410 int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
412 __WDS_LOG_FUNC_ENTER__;
413 wfd_manager_s *manager = wfd_get_manager();
414 wfd_device_s *peer = NULL;
417 if (!session || !manager) {
418 WDS_LOGE("Invalid parameter");
419 __WDS_LOG_FUNC_EXIT__;
423 /* Invite received case state is just created */
424 if (session->state < SESSION_STATE_CREATED ||
425 session->state >= SESSION_STATE_STOPPED) {
426 WDS_LOGE("Session state is Invalid [%d]", session->state);
427 __WDS_LOG_FUNC_EXIT__;
432 * TODO: check session status and do proper work
433 * for example, reject prov_disc, reject nego, stop wps, etc.
437 peer = session->peer;
439 if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
440 res = wfd_oem_wps_cancel(manager->oem_ops);
442 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
444 WDS_LOGE("Failed to reject connection");
445 __WDS_LOG_FUNC_EXIT__;
449 wfd_destroy_session(manager);
450 // TODO: send notification to App
452 __WDS_LOG_FUNC_EXIT__;
456 int wfd_session_join(wfd_session_s *session)
458 __WDS_LOG_FUNC_ENTER__;
459 wfd_manager_s *manager = wfd_get_manager();
460 wfd_oem_conn_param_s param;
461 wfd_device_s *peer = NULL;
465 WDS_LOGE("Invalid parameter");
466 __WDS_LOG_FUNC_EXIT__;
470 session->state = SESSION_STATE_WPS;
471 peer = session->peer;
473 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
474 param.wps_mode = session->wps_mode;
475 if (peer->dev_role == WFD_DEV_ROLE_GO)
476 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
477 param.go_intent = session->go_intent;
478 param.freq = session->freq;
479 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
481 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
483 WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
484 wfd_destroy_session(manager);
485 __WDS_LOG_FUNC_EXIT__;
489 wfd_session_timer(session, 1);
491 __WDS_LOG_FUNC_EXIT__;
495 int wfd_session_invite(wfd_session_s *session)
497 __WDS_LOG_FUNC_ENTER__;
498 wfd_manager_s *manager = wfd_get_manager();
499 wfd_oem_invite_param_s param;
500 wfd_device_s *peer = NULL;
501 wfd_group_s *group = NULL;
505 WDS_LOGE("Invalid parameter");
506 __WDS_LOG_FUNC_EXIT__;
510 if (session->state > SESSION_STATE_CREATED) {
511 WDS_LOGE("Invalid session state(%d)", session->state);
515 peer = session->peer;
516 group = (wfd_group_s*) manager->group;
518 memset(¶m, 0x00, sizeof(wfd_oem_invite_param_s));
519 param.ifname = strdup(group->ifname);
520 memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
522 WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
523 MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
525 res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, ¶m);
527 WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
528 wfd_destroy_session(manager);
529 __WDS_LOG_FUNC_EXIT__;
533 wfd_session_timer(session, 1);
535 __WDS_LOG_FUNC_EXIT__;
539 int wfd_session_wps(wfd_session_s *session)
541 __WDS_LOG_FUNC_ENTER__;
542 wfd_manager_s *manager = wfd_get_manager();
543 wfd_device_s *peer = NULL;
547 WDS_LOGE("Invalid parameter");
548 __WDS_LOG_FUNC_EXIT__;
552 if (session->state > SESSION_STATE_WPS) {
553 WDS_LOGE("Session already starts WPS");
557 session->state = SESSION_STATE_WPS;
558 peer = session->peer;
560 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
561 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
562 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
564 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
565 wfd_oem_conn_param_s param;
566 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
567 param.wps_mode = session->wps_mode;
568 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
569 param.freq = session->freq; // currently not used
570 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
571 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
574 WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
575 wfd_destroy_session(manager);
576 __WDS_LOG_FUNC_EXIT__;
580 __WDS_LOG_FUNC_EXIT__;
584 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
586 __WDS_LOG_FUNC_ENTER__;
587 wfd_device_s *peer = NULL;
590 WDS_LOGE("Invalid parameter");
594 peer = session->peer;
596 __WDS_LOG_FUNC_EXIT__;
600 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
602 __WDS_LOG_FUNC_ENTER__;
603 wfd_device_s *peer = NULL;
605 if (!session || !session->peer) {
606 WDS_LOGE("Invalid parameter");
610 peer = session->peer;
612 __WDS_LOG_FUNC_EXIT__;
613 return peer->dev_addr;
617 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
619 __WDS_LOG_FUNC_ENTER__;
621 __WDS_LOG_FUNC_EXIT__;
625 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
627 __WDS_LOG_FUNC_ENTER__;
629 __WDS_LOG_FUNC_EXIT__;
633 int wfd_session_set_freq(wfd_session_s *session, int freq)
635 __WDS_LOG_FUNC_ENTER__;
637 __WDS_LOG_FUNC_EXIT__;
641 int wfd_session_get_state(wfd_session_s *session)
643 __WDS_LOG_FUNC_ENTER__;
645 __WDS_LOG_FUNC_EXIT__;
649 int wfd_session_set_state(wfd_session_s *session, int state)
651 __WDS_LOG_FUNC_ENTER__;
653 __WDS_LOG_FUNC_EXIT__;
658 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
660 __WDS_LOG_FUNC_ENTER__;
661 wfd_session_s *session = NULL;
664 if (!manager || !event) {
665 WDS_LOGE("Invalid parameter");
669 WDS_LOGD("event ID [%d]", event->event_id);
670 session = manager->session;
672 switch (event->event_id) {
673 case WFD_OEM_EVENT_PROV_DISC_REQ:
675 int req_wps_mode = WFD_WPS_MODE_NONE;
677 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
678 req_wps_mode = WFD_WPS_MODE_KEYPAD;
679 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
680 req_wps_mode = WFD_WPS_MODE_DISPLAY;
682 req_wps_mode = WFD_WPS_MODE_PBC;
685 /* Only peer initiated connection or invitation session can be allowed */
687 if (session->type != SESSION_TYPE_INVITE) {
688 WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
689 MAC2SECSTR(event->dev_addr));
692 WDS_LOGD("=====> session already exist. (invitation session)");
694 session = wfd_create_session(manager, event->dev_addr,
695 req_wps_mode, SESSION_DIRECTION_INCOMING);
697 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
698 MAC2SECSTR(event->dev_addr));
704 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
705 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
707 session->state = SESSION_STATE_STARTED;
708 if (session->type == SESSION_TYPE_INVITE) {
709 WDS_LOGD("Invitation session");
710 } else if (WFD_DEV_ROLE_GO == manager->local->dev_role) {
711 session->type = SESSION_TYPE_JOIN;
713 session->type = SESSION_TYPE_NORMAL;
715 wfd_session_timer(session, 1);
717 /* Update local device */
718 manager->local->wps_mode = event->wps_mode;
720 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
722 if (session->type == SESSION_TYPE_INVITE) {
723 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
724 res = wfd_session_wps(session);
726 _wfd_notify_session_failed(manager, event->dev_addr);
728 wifi_direct_client_noti_s noti;
729 memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
730 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
731 noti.error = WIFI_DIRECT_ERROR_NONE;
732 snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
733 wfd_client_send_event(manager, ¬i);
737 case WFD_OEM_EVENT_PROV_DISC_RESP:
739 if (!session) { // TODO: check validity of Event
740 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
741 MAC2SECSTR(event->dev_addr));
745 if (session->state > SESSION_STATE_STARTED) {
746 WDS_LOGE("Unexpected event. Session is already started");
751 session->wps_mode = event->wps_mode;
752 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
753 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
754 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
755 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
756 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
758 session->req_wps_mode = WFD_WPS_MODE_PBC;
760 session->state = SESSION_STATE_STARTED;
761 wfd_session_timer(session, 1);
763 /* Update local device */
764 manager->local->wps_mode = event->wps_mode;
765 WDS_LOGD("Local WPS mode is %d", session->wps_mode);
767 if (session->wps_mode != WFD_WPS_MODE_PBC) {
768 wifi_direct_client_noti_s noti;
769 memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
770 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_WPS_REQ;
771 g_snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
772 wfd_client_send_event(manager, ¬i);
773 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
774 /* We have to wait until user type PIN using Keypad */
779 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
780 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
781 res = wfd_session_wps(session);
782 } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
783 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
784 res = wfd_session_join(session);
786 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
787 res = wfd_session_connect(session);
791 _wfd_notify_session_failed(manager, event->dev_addr);
793 case WFD_OEM_EVENT_GO_NEG_REQ:
795 // TODO: check whether connection is started by negotiation not by prov_disc
796 WDS_LOGE("Unexpected event. Session not exist [peer: " MACSECSTR "]",
797 MAC2SECSTR(event->dev_addr));
800 /* Sometimes, Provision Discovery response is not received.
801 * At this time, connection should be triggered by GO Negotiation request event */
802 if (session->direction == SESSION_DIRECTION_OUTGOING) {
803 res = wfd_session_connect(session);
805 /* In autoconnection mode, MT should not send GO Nego Req
806 before receving the GO Nego Req from peer (MO). */
807 if (manager->autoconnection == TRUE)
808 res = wfd_session_connect(session);
811 _wfd_notify_session_failed(manager, event->dev_addr);
814 case WFD_OEM_EVENT_GO_NEG_DONE:
816 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
817 MAC2SECSTR(event->dev_addr));
820 session->state = SESSION_STATE_WPS;
824 case WFD_OEM_EVENT_WPS_DONE:
826 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
827 MAC2SECSTR(event->dev_addr));
830 session->state = SESSION_STATE_KEY_NEG;
834 case WFD_OEM_EVENT_CONNECTED:
837 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
838 MAC2SECSTR(event->dev_addr));
841 wfd_group_s *group = manager->group;
843 group = wfd_create_pending_group(manager, event->intf_addr);
845 WDS_LOGE("Failed to create pending group");
848 manager->group = group;
849 } else { // multiconnection, additional client connected
850 WDS_LOGE("Unexpected event. Group already exist");
851 //wfd_group_add_member(manager, event->intf_addr, peer->dev_addr);
854 session->state = SESSION_STATE_COMPLETED;
858 case WFD_OEM_EVENT_STA_CONNECTED:
860 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
861 MAC2SECSTR(event->dev_addr));
864 session->state = SESSION_STATE_COMPLETED;
871 __WDS_LOG_FUNC_EXIT__;