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