Add update peer by time operation
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-session.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 /**
21  * This file implements wifi direct session functions.
22  *
23  * @file                wifi-direct-session.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30
31 #include <glib.h>
32
33 #include <wifi-direct-internal.h>
34
35 #include "wifi-direct-manager.h"
36 #include "wifi-direct-oem.h"
37 #include "wifi-direct-peer.h"
38 #include "wifi-direct-group.h"
39 #include "wifi-direct-oem.h"
40 #include "wifi-direct-util.h"
41 #include "wifi-direct-session.h"
42 #include "wifi-direct-event.h"
43 #include "wifi-direct-state.h"
44
45
46 static gboolean _session_timeout_cb(gpointer *user_data)
47 {
48         __WDS_LOG_FUNC_ENTER__;
49         wfd_manager_s *manager = wfd_get_manager();
50         wfd_session_s *session = (wfd_session_s*) manager->session;
51
52         if (!session) {
53                 WDS_LOGE("Invalid parameter");
54                 return FALSE;
55         }
56
57         session->connecting_120 = 0;
58         session->timer = 0;
59         wfd_destroy_session(manager);
60
61         __WDS_LOG_FUNC_EXIT__;
62         return FALSE;
63 }
64
65 static int _session_timer(wfd_session_s *session, int start)
66 {
67         __WDS_LOG_FUNC_ENTER__;
68
69         if (!session) {
70                 WDS_LOGE("Invalid parameter");
71                 __WDS_LOG_FUNC_EXIT__;
72                 return -1;
73         }
74
75         if (start) {
76                 session->connecting_120 = 1;
77                 if (session->timer > 0) {
78                         WDS_LOGE("Session timer already started");
79                         __WDS_LOG_FUNC_EXIT__;
80                         return -1;
81                 }
82                 session->timer = g_timeout_add(120000,
83                                                         (GSourceFunc) _session_timeout_cb,
84                                                         session);
85                 WDS_LOGD("Session timer started");
86         } else {
87                 session->connecting_120 = 0;
88                 if (session->timer > 0) {
89                         g_source_remove(session->timer);
90                         session->timer = 0;
91                         WDS_LOGD("Session timer stoped");
92                 }
93         }
94
95         __WDS_LOG_FUNC_EXIT__;
96         return 0;
97 }
98
99 // Check the session instance which has same peer address, before using this function
100 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction)
101 {
102         __WDS_LOG_FUNC_ENTER__;
103         wfd_manager_s *manager = (wfd_manager_s*) data;
104         wfd_session_s *session = NULL;
105         wfd_device_s *peer = NULL;
106
107         if (!data || !peer_addr) {
108                 WDS_LOGE("Invalid parameter");
109                 __WDS_LOG_FUNC_EXIT__;
110                 return NULL;
111         }
112
113         if (manager->session) {
114                 WDS_LOGE("Session already exist");
115                 return NULL;
116         }
117
118         session = (wfd_session_s*) calloc(1, sizeof(wfd_session_s));
119         if (!session) {
120                 WDS_LOGE("Failed to allocate memory for session");
121                 __WDS_LOG_FUNC_EXIT__;
122                 return NULL;
123         }
124
125         peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
126         if (!peer) {
127                 WDS_LOGE("Failed to find peer info[" MACSTR "]", MAC2STR(peer_addr));
128                 free(session);
129                 __WDS_LOG_FUNC_EXIT__;
130                 return NULL;
131         }
132         peer->state = WFD_PEER_STATE_CONNECTING;
133
134         session->peer = peer;
135         session->req_wps_mode = wps_mode;
136         if (wps_mode == WFD_WPS_MODE_DISPLAY)
137                 session->wps_mode = WFD_WPS_MODE_KEYPAD;
138         else if (wps_mode == WFD_WPS_MODE_KEYPAD)
139                 session->wps_mode = WFD_WPS_MODE_DISPLAY;
140         else
141                 session->wps_mode = wps_mode;
142         session->direction = direction;
143         session->state = SESSION_STATE_CREATED;
144
145         manager->session = session;
146         manager->local->wps_mode = session->wps_mode;
147         if (peer->dev_role == WFD_DEV_ROLE_GO)
148                 manager->local->dev_role = WFD_DEV_ROLE_GC;
149
150         __WDS_LOG_FUNC_EXIT__;
151         return session;
152 }
153
154 int wfd_destroy_session(void *data)
155 {
156         __WDS_LOG_FUNC_ENTER__;
157         wfd_manager_s *manager = (wfd_manager_s*) data;
158         wfd_session_s *session = NULL;
159         wfd_device_s *peer = NULL;
160
161         if (!manager) {
162                 WDS_LOGE("Invalid parameter");
163                 return -1;
164         }
165
166         session = (wfd_session_s*) manager->session;
167         if (!session) {
168                 WDS_LOGE("Session not found");
169                 return -1;
170         }
171         _session_timer(session, 0);
172         peer = session->peer;
173         
174         if (session->state == SESSION_STATE_COMPLETED)
175                 peer->state = WFD_PEER_STATE_CONNECTED;
176         else
177                 peer->state = WFD_PEER_STATE_DISCOVERED;
178
179         free(session);
180         manager->session = NULL;
181         manager->local->wps_mode = WFD_WPS_MODE_PBC;
182         manager->autoconnection = 0;
183         if (manager->local->dev_role == WFD_DEV_ROLE_GC)
184                 manager->local->dev_role = WFD_DEV_ROLE_NONE;
185
186         __WDS_LOG_FUNC_EXIT__;
187         return 0;
188 }
189
190 int wfd_session_start(wfd_session_s *session)
191 {
192         __WDS_LOG_FUNC_ENTER__;
193         wfd_manager_s *manager = wfd_get_manager();
194         wfd_device_s *peer = NULL;
195         int join = 0;
196         int res = 0;
197
198         if (!session) {
199                 WDS_LOGE("Invalid parameter");
200                 __WDS_LOG_FUNC_EXIT__;
201                 return -1;
202         }
203
204         // Check: Invitation Received in Incomming case -> send prov_disc join
205         // Check: User select peer to connect with in Outgoing case -> send prov_disc wps_mdde
206
207         wfd_oem_stop_scan(manager->oem_ops);
208
209         session->state = SESSION_STATE_STARTED;
210         peer = session->peer;
211         if (peer->dev_role == WFD_DEV_ROLE_GO || session->invitation)
212                 join = 1;
213         res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
214                                         session->req_wps_mode, join);
215         if (res < 0) {
216                 WDS_LOGE("Failed to send provision discovery request to peer [" MACSTR "]",
217                                                                         MAC2STR(peer->dev_addr));
218                 wfd_destroy_session(manager);
219                 // TODO: send notification to App
220                 __WDS_LOG_FUNC_EXIT__;
221                 return -1;
222         }
223
224         _session_timer(session, 1);
225
226         __WDS_LOG_FUNC_EXIT__;
227         return 0;
228 }
229
230 int wfd_session_stop(wfd_session_s *session)
231 {
232         __WDS_LOG_FUNC_ENTER__;
233         wfd_manager_s *manager = wfd_get_manager();
234         wfd_device_s *peer = NULL;
235         int res = 0;
236
237         if (!session) {
238                 WDS_LOGE("Invalid parameter");
239                 __WDS_LOG_FUNC_EXIT__;
240                 return -1;
241         }
242
243         if (session->state > SESSION_STATE_CREATED) {
244                 peer = session->peer;
245                 if (session->direction == SESSION_DIRECTION_INCOMING) {
246                         res  = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
247                 } else if (session->direction == SESSION_DIRECTION_OUTGOING) {
248                         res = wfd_oem_cancel_connection(manager->oem_ops, peer->dev_addr);
249                 }
250                 if (res < 0) {
251                         WDS_LOGE("Failed to reject or cancel connection");
252                         __WDS_LOG_FUNC_EXIT__;
253                         return -1;
254                 }
255         }
256
257         session->state = SESSION_STATE_STOPPED;
258         wfd_destroy_session(manager);
259
260         __WDS_LOG_FUNC_EXIT__;
261         return 0;
262 }
263
264 /* In case of incomming session, when user accept connection request, this function should be called.
265  * In case of outgoing session, when prov_disc response arrived, this function should be called.
266  * Even though peer is GO, we can use this function, which can decide using join itself.
267  */
268 int wfd_session_connect(wfd_session_s *session)
269 {
270         __WDS_LOG_FUNC_ENTER__;
271         wfd_manager_s *manager = wfd_get_manager();
272         wfd_oem_conn_param_s param;
273         wfd_device_s *peer = NULL;
274         int res = 0;
275
276         if (!session) {
277                 WDS_LOGE("Invalid parameter");
278                 __WDS_LOG_FUNC_EXIT__;
279                 return -1;
280         }
281
282         if (session->state > SESSION_STATE_GO_NEG) {
283                 WDS_LOGE("Session already starts GO Negotiation");
284                 return -1;
285         }
286
287         session->state = SESSION_STATE_GO_NEG;
288         peer = session->peer;
289
290         memset(&param, 0x00, sizeof(wfd_oem_conn_param_s));
291         param.wps_mode = session->wps_mode;
292         if (peer->dev_role == WFD_DEV_ROLE_GO)
293                 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
294         param.go_intent = session->go_intent;
295         param.freq = session->freq;
296         if (session->wps_pin[0] != '\0') {
297                 strncpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN);
298                 param.wps_pin[OEM_PINSTR_LEN] = '\0';
299         }
300
301         res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, &param);
302         if (res < 0) {
303                 WDS_LOGE("Failed to connect peer [" MACSTR "]", MAC2STR(peer->dev_addr));
304                 wfd_destroy_session(manager);
305                 // TODO: send notification to App
306                 __WDS_LOG_FUNC_EXIT__;
307                 return -1;
308         }
309
310         _session_timer(session, 1);
311
312         __WDS_LOG_FUNC_EXIT__;
313         return 0;
314 }
315
316 int wfd_session_reject(wfd_session_s *session)
317 {
318         __WDS_LOG_FUNC_ENTER__;
319         wfd_manager_s *manager = wfd_get_manager();
320         wfd_device_s *peer = NULL;
321         int res = 0;
322
323         if (!session) {
324                 WDS_LOGE("Invalid parameter");
325                 __WDS_LOG_FUNC_EXIT__;
326                 return -1;
327         }
328
329         if (session->state < SESSION_STATE_STARTED) {
330                 WDS_LOGE("Session is not started");
331                 __WDS_LOG_FUNC_EXIT__;
332                 return -1;
333         }
334
335         if (session->direction != SESSION_DIRECTION_INCOMING) {
336                 WDS_LOGE("Cannot reject with outgoing connection");
337                 __WDS_LOG_FUNC_EXIT__;
338                 return -1;
339         }
340
341         // TODO: check session status and do proper work
342         // for example, reject prov_disc, reject nego, stop wps, etc.
343         peer = session->peer;
344         res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
345         if (res < 0) {
346                 WDS_LOGE("Failed to reject connection");
347                 __WDS_LOG_FUNC_EXIT__;
348                 return -1;
349         }
350
351         wfd_destroy_session(manager);
352         // TODO: send notification to App
353
354         __WDS_LOG_FUNC_EXIT__;
355         return 0;
356 }
357
358 int wfd_session_join(wfd_session_s *session)
359 {
360         __WDS_LOG_FUNC_ENTER__;
361         wfd_manager_s *manager = wfd_get_manager();
362         wfd_oem_conn_param_s param;
363         wfd_device_s *peer = NULL;
364         int res = 0;
365
366         if (!session) {
367                 WDS_LOGE("Invalid parameter");
368                 __WDS_LOG_FUNC_EXIT__;
369                 return -1;
370         }
371
372         session->state = SESSION_STATE_WPS;
373         peer = session->peer;
374
375         memset(&param, 0x00, sizeof(wfd_oem_conn_param_s));
376         param.wps_mode = session->wps_mode;
377         if (peer->dev_role == WFD_DEV_ROLE_GO)
378                 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
379         param.go_intent = session->go_intent;
380         param.freq = session->freq;
381         memcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN);
382
383         res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, &param);
384         if (res < 0) {
385                 WDS_LOGE("Failed to join with peer [" MACSTR "]", MAC2STR(peer->dev_addr));
386                 wfd_destroy_session(manager);
387                 // TODO: send notification to App
388                 __WDS_LOG_FUNC_EXIT__;
389                 return -1;
390         }
391
392         _session_timer(session, 1);
393
394         __WDS_LOG_FUNC_EXIT__;
395         return 0;
396 }
397
398 int wfd_session_invite(wfd_session_s *session)
399 {
400         __WDS_LOG_FUNC_ENTER__;
401         wfd_manager_s *manager = wfd_get_manager();
402         wfd_oem_invite_param_s param;
403         wfd_device_s *peer = NULL;
404         wfd_group_s *group = NULL;
405         int res = 0;
406
407         if (!session) {
408                 WDS_LOGE("Invalid parameter");
409                 __WDS_LOG_FUNC_EXIT__;
410                 return -1;
411         }
412
413         peer = session->peer;
414         group = (wfd_group_s*) manager->group;
415
416         memset(&param, 0x00, sizeof(wfd_oem_invite_param_s));
417         param.ifname = strdup(group->ifname);
418         memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
419
420         WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]", MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
421
422         res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, &param);
423         if (res < 0) {
424                 WDS_LOGE("Failed to invite with peer [" MACSTR "]", MAC2STR(peer->dev_addr));
425                 wfd_destroy_session(manager);
426                 // TODO: send notification to App
427                 __WDS_LOG_FUNC_EXIT__;
428                 return -1;
429         }
430
431         _session_timer(session, 1);
432
433         __WDS_LOG_FUNC_EXIT__;
434         return 0;
435 }
436
437 int wfd_session_wps(wfd_session_s *session)
438 {
439         __WDS_LOG_FUNC_ENTER__;
440         wfd_manager_s *manager = wfd_get_manager();
441         wfd_device_s *peer = NULL;
442         int res = 0;
443
444         if (!session) {
445                 WDS_LOGE("Invalid parameter");
446                 __WDS_LOG_FUNC_EXIT__;
447                 return -1;
448         }
449
450         if (session->state > SESSION_STATE_WPS) {
451                 WDS_LOGE("Session already starts WPS");
452                 return -1;
453         }
454
455         session->state = SESSION_STATE_WPS;
456         peer = session->peer;
457
458         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
459                 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
460                 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
461         } else {
462                 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
463                 res = wfd_oem_enrollee_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
464         }
465         if (res < 0) {
466                 WDS_LOGE("Failed to start wps with peer [" MACSTR "]", MAC2STR(peer->dev_addr));
467                 wfd_destroy_session(manager);
468                 // TODO: send notification to App
469                 __WDS_LOG_FUNC_EXIT__;
470                 return -1;
471         }
472
473         __WDS_LOG_FUNC_EXIT__;
474         return 0;
475 }
476
477 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
478 {
479         __WDS_LOG_FUNC_ENTER__;
480         wfd_device_s *peer = NULL;
481
482         if (!session) {
483                 WDS_LOGE("Invalid parameter");
484                 return NULL;
485         }
486         
487         peer = session->peer;
488
489         __WDS_LOG_FUNC_EXIT__;
490         return peer;
491 }
492
493 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
494 {
495         __WDS_LOG_FUNC_ENTER__;
496         wfd_device_s *peer = NULL;
497
498         if (!session || !session->peer) {
499                 WDS_LOGE("Invalid parameter");
500                 return NULL;
501         }
502         
503         peer = session->peer;
504
505         __WDS_LOG_FUNC_EXIT__;
506         return peer->dev_addr;
507 }
508
509 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
510 {
511         __WDS_LOG_FUNC_ENTER__;
512
513         __WDS_LOG_FUNC_EXIT__;
514         return 0;
515 }
516
517 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
518 {
519         __WDS_LOG_FUNC_ENTER__;
520
521         __WDS_LOG_FUNC_EXIT__;
522         return 0;
523 }
524
525 int wfd_session_set_freq(wfd_session_s *session, int freq)
526 {
527         __WDS_LOG_FUNC_ENTER__;
528
529         __WDS_LOG_FUNC_EXIT__;
530         return 0;
531 }
532
533 int wfd_session_get_state(wfd_session_s *session)
534 {
535         __WDS_LOG_FUNC_ENTER__;
536
537         __WDS_LOG_FUNC_EXIT__;
538         return 0;
539 }
540
541 int wfd_session_set_state(wfd_session_s *session, int state)
542 {
543         __WDS_LOG_FUNC_ENTER__;
544
545         __WDS_LOG_FUNC_EXIT__;
546         return 0;
547 }
548
549 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
550 {
551         __WDS_LOG_FUNC_ENTER__;
552         wfd_session_s *session = NULL;
553
554         if (!manager || !event) {
555                 WDS_LOGE("Invalid parameter");
556                 return -1;
557         }
558
559         WDS_LOGD("event ID [%d]", event->event_id);
560         session = manager->session;
561
562         switch (event->event_id) {
563         case WFD_OEM_EVENT_PROV_DISC_REQ:
564         case WFD_OEM_EVENT_PROV_DISC_DISPLAY:
565         case WFD_OEM_EVENT_PROV_DISC_KEYPAD:
566         {
567                 if (!session) {
568                         int req_wps_mode = WFD_WPS_MODE_NONE;
569                         int wps_mode = event->wps_mode;
570
571                         if (wps_mode == WFD_WPS_MODE_DISPLAY) {
572                                 req_wps_mode = WFD_WPS_MODE_KEYPAD;
573                         } else if (wps_mode == WFD_WPS_MODE_KEYPAD) {
574                                 req_wps_mode = WFD_WPS_MODE_DISPLAY;
575                         } else {
576                                 req_wps_mode = WFD_WPS_MODE_PBC;
577                         }
578
579                         session = wfd_create_session(manager, event->dev_addr,
580                                                                                 req_wps_mode, SESSION_DIRECTION_INCOMING);
581                         if (!session) {
582                                 WDS_LOGE("Failed to create session with peer [" MACSTR "]", MAC2STR(event->dev_addr));
583                                 break;
584                         }
585
586                         /* Update session */
587                         if (wps_mode == WFD_WPS_MODE_DISPLAY) {
588                                 strncpy(session->wps_pin, event->wps_pin, PINSTR_LEN);
589                                 session->wps_pin[PINSTR_LEN] = '\0';
590                         }
591                         session->state = SESSION_STATE_STARTED;
592                         _session_timer(session, 1);
593
594                         manager->local->wps_mode = event->wps_mode;
595
596                         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
597
598                         wifi_direct_client_noti_s noti;
599                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
600                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
601                         noti.error = WIFI_DIRECT_ERROR_NONE;
602                         snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
603                         wfd_event_notify_clients(manager, &noti);
604                 } else {
605                         if (session->state > SESSION_STATE_STARTED ||
606                                         session->direction == SESSION_DIRECTION_INCOMING) {
607                                 WDS_LOGE("Unexpected event. Session is already started");
608                                 break;
609                         }
610
611                         session->wps_mode = event->wps_mode;
612                         if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
613                                 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
614                                 strncpy(session->wps_pin, event->wps_pin, PINSTR_LEN);
615                                 session->wps_pin[PINSTR_LEN] = '\0';
616                         } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
617                                 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
618                         } else {
619                                 session->req_wps_mode = WFD_WPS_MODE_PBC;
620                         }
621                         session->state = SESSION_STATE_STARTED;
622                         _session_timer(session, 1);
623
624                         manager->local->wps_mode = event->wps_mode;
625                         WDS_LOGD("Local WPS mode is %d", session->wps_mode);
626
627                         if (session->wps_mode != WFD_WPS_MODE_PBC) {
628                                 wifi_direct_client_noti_s noti;
629                                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
630                                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_WPS_REQ;
631                                 snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
632                                 wfd_event_notify_clients(manager, &noti);
633                                 if (session->wps_mode == WFD_WPS_MODE_KEYPAD)
634                                         break;
635                         }
636
637                         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
638                                 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
639                                 wfd_session_wps(session);
640                         } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
641                                 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
642                                 wfd_session_join(session);
643                         } else {
644                                 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
645                                 wfd_session_connect(session);
646                         }
647                 }
648         }
649         break;
650         case WFD_OEM_EVENT_PROV_DISC_RESP:
651                 if (!session) {
652                         WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
653                         break;
654                 }
655
656                 if (session->state > SESSION_STATE_STARTED) {
657                         WDS_LOGE("Unexpected event. Session is already started");
658                         break;
659                 }
660                 session->state = SESSION_STATE_STARTED;
661
662                 if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
663                         WDS_LOGD("Start joining corresponding to OEM event [%d]", event->event_id);
664                         wfd_session_join(session);
665                 } else if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
666                         WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
667                         wfd_session_wps(session);
668                 } else {
669                         WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
670                         wfd_session_connect(session);
671                 }
672                 break;
673         case WFD_OEM_EVENT_GO_NEG_REQ:
674                 if (!session) {         // TODO: check whether connection is started by negotiation not by prov_disc
675                         WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
676                         break;
677                 } else {
678                         /* Sometimes, Provision Discovery response is not received.
679                          * At this time, connection should be triggered by GO Negotiation request event */
680                         if (session->direction == SESSION_DIRECTION_OUTGOING)
681                                 wfd_session_connect(session);
682                 }
683                 break;
684         case WFD_OEM_EVENT_GO_NEG_DONE:
685                 if (!session) {
686                         WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
687                         break;
688                 } else {
689                         session->state = SESSION_STATE_WPS;
690                 }
691                 
692                 break;
693         case WFD_OEM_EVENT_WPS_DONE:
694                 if (!session) {
695                         WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
696                         break;
697                 } else {
698                         session->state = SESSION_STATE_KEY_NEG;
699                 }
700                 
701                 break;
702         case WFD_OEM_EVENT_CONNECTED:
703         {
704                 if (!session) {
705                         WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
706                         break;
707                 } else {
708                         wfd_group_s *group = manager->group;
709                         if (!group) {
710                                 group = wfd_create_pending_group(manager, event->intf_addr);
711                                 if (!group) {
712                                         WDS_LOGE("Failed to create pending group");
713                                         break;
714                                 }
715                                 manager->group = group;
716                         } else {        // multiconnection, additional client connected
717                                 WDS_LOGE("Unexpected event. Group already exist");
718                                 //wfd_group_add_member(manager, event->intf_addr, peer->dev_addr);
719                                 break;
720                         }
721                         session->state = SESSION_STATE_COMPLETED;
722                 }
723         }
724         break;
725         case WFD_OEM_EVENT_STA_CONNECTED:
726                 if (!session) {
727                         WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSTR "]", MAC2STR(event->dev_addr));
728                         break;
729                 } else {
730                         session->state = SESSION_STATE_COMPLETED;
731                 }
732                 
733                 break;
734         default:
735                 break;
736         }
737         __WDS_LOG_FUNC_EXIT__;
738         return 0;
739 }