[wifi-direct-manager]Add the logic for keeping peer memory in session
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-event.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 event functions.
22  *
23  * @file                wifi-direct-event.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <poll.h>
31 #include <unistd.h>
32 #include <time.h>
33 #include <errno.h>
34
35 #include <glib.h>
36
37 #include <wifi-direct.h>
38
39 #include "wifi-direct-ipc.h"
40 #include "wifi-direct-manager.h"
41 #include "wifi-direct-oem.h"
42 #include "wifi-direct-peer.h"
43 #include "wifi-direct-group.h"
44 #include "wifi-direct-session.h"
45 #include "wifi-direct-event.h"
46 #include "wifi-direct-client.h"
47 #include "wifi-direct-state.h"
48 #include "wifi-direct-util.h"
49
50
51 static int _wfd_event_update_peer(wfd_manager_s *manager, wfd_oem_dev_data_s *data)
52 {
53         __WDS_LOG_FUNC_ENTER__;
54
55         wfd_device_s *peer = NULL;
56
57         if (!manager || !data) {
58                 WDS_LOGE("Invalid parameter");
59                 __WDS_LOG_FUNC_EXIT__;
60                 return -1;
61         }
62
63         peer = wfd_peer_find_by_dev_addr(manager, data->p2p_dev_addr);
64         if (!peer) {
65                 peer = wfd_add_peer(manager, data->p2p_dev_addr, data->name);
66                 if (!peer) {
67                         WDS_LOGE("Failed to add peer");
68                         __WDS_LOG_FUNC_EXIT__;
69                         return -1;
70                 }
71         } else {
72                 if (strcmp(peer->dev_name, data->name)) {
73                         g_strlcpy(peer->dev_name, data->name, DEV_NAME_LEN + 1);
74                         WDS_LOGD("Device name is changed [" MACSECSTR ": %s]",
75                                         MAC2SECSTR(peer->dev_addr), peer->dev_name);
76                 }
77         }
78 #ifndef CTRL_IFACE_DBUS
79         memcpy(peer->intf_addr, data->p2p_intf_addr, MACADDR_LEN);
80 #endif /* CTRL_IFACE_DBUS */
81         peer->pri_dev_type = data->pri_dev_type;
82         peer->sec_dev_type = data->sec_dev_type;
83         peer->config_methods = data->config_methods;
84         peer->dev_flags = data->dev_flags;
85         peer->group_flags = data->group_flags;
86         peer->dev_role = data->dev_role;
87 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
88         memcpy(&(peer->display), &(data->display), sizeof(wfd_display_s));
89 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
90
91 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
92         wfd_util_get_current_time(&peer->time);
93 #else
94         struct timeval tval;
95         gettimeofday(&tval, NULL);
96         peer->time = tval.tv_sec;
97 #endif
98         WDS_LOGI("Update time [%s - %ld]", peer->dev_name, peer->time);
99
100         __WDS_LOG_FUNC_EXIT__;
101         return 0;
102 }
103
104  gboolean _wfd_connection_retry(gpointer *data)
105 {
106         wfd_session_s *session = (wfd_session_s*) data;
107         if (!session) {
108                 WDS_LOGE("Session is NULL");
109                 __WDS_LOG_FUNC_EXIT__;
110                 return G_SOURCE_REMOVE;
111         }
112
113         switch (session->state) {
114                 case SESSION_STATE_STARTED:
115                         WDS_LOGD("PD again");
116                         wfd_session_start(session);
117                         break;
118                 case SESSION_STATE_GO_NEG:
119                         WDS_LOGD("Negotiation again");
120                         wfd_session_connect(session);
121                         break;
122                 case SESSION_STATE_WPS:
123                         WDS_LOGD("WPS again");
124                         wfd_session_wps(session);
125                         break;
126                 default:
127                         WDS_LOGE("Invalid session state [%d]", session->state);
128                         break;
129         }
130         __WDS_LOG_FUNC_EXIT__;
131         return G_SOURCE_REMOVE;
132 }
133
134 static void __wfd_process_deactivated(wfd_manager_s *manager, wfd_oem_event_s *event)
135 {
136         __WDS_LOG_FUNC_ENTER__;
137
138         wifi_direct_client_noti_s noti;
139
140         if (event == NULL || manager == NULL) {
141                 WDS_LOGE("Invalid parameter");
142                 __WDS_LOG_FUNC_EXIT__;
143                 return;
144         }
145
146         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
147         noti.event = WIFI_DIRECT_CLI_EVENT_DEACTIVATION;
148         noti.error = WIFI_DIRECT_ERROR_NONE;
149         wfd_client_send_event(manager, &noti);
150
151         wfd_destroy_group(manager, GROUP_IFNAME);
152         wfd_destroy_session(manager);
153         wfd_peer_clear_all(manager);
154         wfd_local_reset_data(manager);
155
156         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
157         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
158         manager->req_wps_mode = WFD_WPS_MODE_PBC;
159
160 #ifdef TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT
161         wfd_util_stop_wifi_direct_popup();
162 #endif /* TIZEN_FEATURE_DEFAULT_CONNECTION_AGENT */
163         __WDS_LOG_FUNC_EXIT__;
164         return;
165 }
166
167 static void __wfd_process_peer_found(wfd_manager_s *manager, wfd_oem_event_s *event)
168 {
169         __WDS_LOG_FUNC_ENTER__;
170
171         wfd_oem_dev_data_s *edata = NULL;
172         wifi_direct_client_noti_s noti;
173         int res = 0;
174
175         if (event == NULL || manager == NULL) {
176                 WDS_LOGE("Invalid parameter");
177                 __WDS_LOG_FUNC_EXIT__;
178                 return;
179         }
180
181         edata = (wfd_oem_dev_data_s*) event->edata;
182         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
183                 WDS_LOGE("Invalid event data");
184                 __WDS_LOG_FUNC_EXIT__;
185                 return;
186         }
187
188         res = _wfd_event_update_peer(manager, edata);
189         if (res < 0) {
190                 WDS_LOGE("Failed to update peer data");
191                 __WDS_LOG_FUNC_EXIT__;
192                 return;
193         }
194
195         if (manager->state > WIFI_DIRECT_STATE_ACTIVATING &&
196                         manager->state != WIFI_DIRECT_STATE_CONNECTING &&
197                         manager->state != WIFI_DIRECT_STATE_DISCONNECTING) {
198                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
199                 snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(edata->p2p_dev_addr));
200                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_FOUND_PEERS;
201                 noti.error = WIFI_DIRECT_ERROR_NONE;
202                 wfd_client_send_event(manager, &noti);
203         }
204
205         __WDS_LOG_FUNC_EXIT__;
206         return;
207 }
208
209 static void __wfd_process_peer_disappeared(wfd_manager_s *manager, wfd_oem_event_s *event)
210 {
211         __WDS_LOG_FUNC_ENTER__;
212
213         wifi_direct_client_noti_s noti;
214         wfd_session_s *session = NULL;
215         wfd_device_s *peer = NULL;
216
217         if (event == NULL || manager == NULL) {
218                 WDS_LOGE("Invalid parameter");
219                 __WDS_LOG_FUNC_EXIT__;
220                 return;
221         }
222
223         session = manager->session;
224         if(session != NULL && session->peer != NULL) {
225                 peer = session->peer;
226                 WDS_LOGD("session peer [" MACSTR "] lost peer ["  MACSTR "]", MAC2STR(peer->dev_addr),
227                                                 MAC2STR(event->dev_addr));
228                 if(memcmp(peer->dev_addr, event->dev_addr, MACADDR_LEN) == 0) {
229                         WDS_LOGD("peer already in connection");
230                         return;
231                 }
232         }
233
234         wfd_remove_peer(manager, event->dev_addr);
235
236         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
237         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
238         noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_LOST_PEERS;
239         noti.error = WIFI_DIRECT_ERROR_NONE;
240         wfd_client_send_event(manager, &noti);
241
242         __WDS_LOG_FUNC_EXIT__;
243         return;
244 }
245
246 static void __wfd_process_discovery_finished(wfd_manager_s *manager, wfd_oem_event_s *event)
247 {
248         __WDS_LOG_FUNC_ENTER__;
249
250         wifi_direct_client_noti_s noti;
251
252         if (event == NULL || manager == NULL) {
253                 WDS_LOGE("Invalid parameter");
254                 __WDS_LOG_FUNC_EXIT__;
255                 return;
256         }
257
258         if (manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
259                         manager->state != WIFI_DIRECT_STATE_ACTIVATED) {
260                 WDS_LOGE("Notify finding stopped when discovering or activated. [%d]", manager->state);
261                 __WDS_LOG_FUNC_EXIT__;
262                 return;
263         }
264
265         if (manager->scan_mode == WFD_SCAN_MODE_PASSIVE) {
266                 WDS_LOGE("During passive scan, Discover Finished event will not notified");
267                 __WDS_LOG_FUNC_EXIT__;
268                 return;
269         }
270
271         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
272                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
273                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
274         } else {
275                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
276                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
277         }
278         manager->scan_mode = WFD_SCAN_MODE_NONE;
279
280         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
281         noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_END;
282         noti.error = WIFI_DIRECT_ERROR_NONE;
283         wfd_client_send_event(manager, &noti);
284
285         __WDS_LOG_FUNC_EXIT__;
286         return;
287 }
288
289 static void __wfd_process_prov_disc_req(wfd_manager_s *manager, wfd_oem_event_s *event)
290 {
291         __WDS_LOG_FUNC_ENTER__;
292
293         wfd_device_s *peer = NULL;
294         int res = 0;
295
296         if (event == NULL || manager == NULL) {
297                 WDS_LOGE("Invalid parameter");
298                 __WDS_LOG_FUNC_EXIT__;
299                 return;
300         }
301
302         wfd_group_s *group = (wfd_group_s*) manager->group;
303         if (group && group->role == WFD_DEV_ROLE_GC &&
304                                                 event->event_id == WFD_OEM_EVENT_PROV_DISC_REQ) {
305                 WDS_LOGD("Device has GC role - ignore this provision request");
306                 __WDS_LOG_FUNC_EXIT__;
307                 return;
308         }
309
310 #ifdef CTRL_IFACE_DBUS
311         wfd_oem_dev_data_s *edata = NULL;
312
313         edata = (wfd_oem_dev_data_s*) event->edata;
314         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
315                 WDS_LOGE("Invalid event data");
316                 __WDS_LOG_FUNC_EXIT__;
317                 return;
318         }
319
320         res = _wfd_event_update_peer(manager, edata);
321         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
322         if (peer)
323                 peer->state = WFD_PEER_STATE_CONNECTING;
324 #else /* CTRL_IFACE_DBUS */
325         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
326         if (!peer) {
327                 WDS_LOGD("Prov_disc from unknown peer. Add new peer");
328                 peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
329                 if (!peer) {
330                         WDS_LOGE("Failed to add peer for invitation");
331                         __WDS_LOG_FUNC_EXIT__;
332                         return;
333                 }
334                 peer->state = WFD_PEER_STATE_CONNECTING;
335                 wfd_update_peer(manager, peer);
336         }
337         wfd_update_peer_time(manager, event->dev_addr);
338 #endif /* CTRL_IFACE_DBUS */
339
340         res = wfd_session_process_event(manager, event);
341         if (res < 0)
342                 WDS_LOGE("Failed to process event of session");
343
344         __WDS_LOG_FUNC_EXIT__;
345         return;
346 }
347
348 static void __wfd_process_prov_disc_resp(wfd_manager_s *manager, wfd_oem_event_s *event)
349 {
350         __WDS_LOG_FUNC_ENTER__;
351
352         wfd_device_s *peer = NULL;
353         int res = 0;
354
355         if (event == NULL || manager == NULL) {
356                 WDS_LOGE("Invalid parameter");
357                 __WDS_LOG_FUNC_EXIT__;
358                 return;
359         }
360
361 #ifdef CTRL_IFACE_DBUS
362         wfd_oem_dev_data_s *edata = NULL;
363
364         edata = (wfd_oem_dev_data_s*) event->edata;
365         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
366                 WDS_LOGE("Invalid event data");
367                 __WDS_LOG_FUNC_EXIT__;
368                 return;
369         }
370
371         res = _wfd_event_update_peer(manager, edata);
372         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
373         if (peer)
374                 peer->state = WFD_PEER_STATE_CONNECTING;
375 #else /* CTRL_IFACE_DBUS */
376         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
377         if (!peer) {
378                 WDS_LOGD("Prov_disc from unknown peer. Add new peer");
379                 peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
380                 if (!peer) {
381                         WDS_LOGE("Failed to add peer for invitation");
382                         __WDS_LOG_FUNC_EXIT__;
383                         return;
384                 }
385                 peer->state = WFD_PEER_STATE_CONNECTING;
386                 wfd_update_peer(manager, peer);
387         }
388         wfd_update_peer_time(manager, event->dev_addr);
389 #endif /* CTRL_IFACE_DBUS */
390
391         res = wfd_session_process_event(manager, event);
392         if (res < 0)
393                 WDS_LOGE("Failed to process event of session");
394
395         __WDS_LOG_FUNC_EXIT__;
396         return;
397 }
398
399 static void __wfd_process_prov_disc_fail(wfd_manager_s *manager, wfd_oem_event_s *event)
400 {
401         __WDS_LOG_FUNC_ENTER__;
402
403         wfd_session_s *session = NULL;
404         wifi_direct_client_noti_s noti;
405         unsigned char *peer_addr = NULL;
406
407         if (event == NULL || manager == NULL) {
408                 WDS_LOGE("Invalid parameter");
409                 __WDS_LOG_FUNC_EXIT__;
410                 return;
411         }
412
413         session = (wfd_session_s*) manager->session;
414         if (!session) {
415                 WDS_LOGE("Unexpected event. Session not exist");
416                 __WDS_LOG_FUNC_EXIT__;
417                 return;
418         }
419
420         peer_addr = wfd_session_get_peer_addr(session);
421         if (!peer_addr) {
422                 WDS_LOGE("Session do not have peer");
423                 __WDS_LOG_FUNC_EXIT__;
424                 return;
425         }
426
427         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
428         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
429         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
430         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
431         wfd_client_send_event(manager, &noti);
432
433         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
434                 wfd_group_s *group = (wfd_group_s*) manager->group;
435                 if (group && !group->member_count && (wfd_group_is_autonomous(group) == FALSE)) {
436                         wfd_destroy_group(manager, GROUP_IFNAME);
437
438                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
439                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
440                 } else {
441                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
442                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
443                 }
444         } else {
445                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
446                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
447         }
448
449         wfd_destroy_session(manager);
450
451         wfd_oem_refresh(manager->oem_ops);
452 #if 0
453         /* After connection failed, scan again */
454         wfd_oem_scan_param_s param;
455         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
456         param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
457         param.scan_time = 2;
458         param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
459         wfd_oem_start_scan(manager->oem_ops, &param);
460         manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
461 #endif
462         __WDS_LOG_FUNC_EXIT__;
463         return;
464 }
465
466 static void __wfd_process_go_neg_req(wfd_manager_s *manager, wfd_oem_event_s *event)
467 {
468         __WDS_LOG_FUNC_ENTER__;
469
470         wfd_session_s *session = NULL;
471         wifi_direct_client_noti_s noti;
472
473         if (event == NULL || manager == NULL) {
474                 WDS_LOGE("Invalid parameter");
475                 __WDS_LOG_FUNC_EXIT__;
476                 return;
477         }
478
479         wfd_group_s *group = (wfd_group_s*) manager->group;
480         if (group && group->role == WFD_DEV_ROLE_GC) {
481                 WDS_LOGD("Device has GC role - ignore this go neg request");
482                 __WDS_LOG_FUNC_EXIT__;
483                 return;
484         }
485
486 #ifdef CTRL_IFACE_DBUS
487         wfd_oem_dev_data_s *edata = NULL;
488         int res = 0;
489
490         edata = (wfd_oem_dev_data_s*) event->edata;
491         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
492                 WDS_LOGE("Invalid event data");
493                 __WDS_LOG_FUNC_EXIT__;
494                 return;
495         }
496
497         res = _wfd_event_update_peer(manager, edata);
498         if (res < 0) {
499                 WDS_LOGE("Failed to update peer data");
500                 __WDS_LOG_FUNC_EXIT__;
501                 return;
502         }
503 #else /* CTRL_IFACE_DBUS */
504         wfd_oem_conn_data_s *edata = NULL;
505         wfd_device_s *peer = NULL;
506
507         edata = (wfd_oem_conn_data_s*) event->edata;
508         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_CONN) {
509                 WDS_LOGE("Invalid connection event data");
510                 __WDS_LOG_FUNC_EXIT__;
511                 return;
512         }
513
514         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
515         if (!peer) {
516                 WDS_LOGD("Invitation from unknown peer. Add new peer");
517                 peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
518                 if (!peer) {
519                         WDS_LOGE("Failed to add peer for invitation");
520                         __WDS_LOG_FUNC_EXIT__;
521                         return;
522                 }
523         }
524
525         if (edata->wps_mode == 0)
526                 edata->wps_mode = 1;
527 #endif /* CTRL_IFACE_DBUS */
528
529         session = (wfd_session_s*) manager->session;
530         if (!session) {
531                 session = wfd_create_session(manager, event->dev_addr,
532 #ifdef CTRL_IFACE_DBUS
533                                                 event->wps_mode, SESSION_DIRECTION_INCOMING);
534 #else /* CTRL_IFACE_DBUS */
535                                                 edata->wps_mode, SESSION_DIRECTION_INCOMING);
536 #endif /* CTRL_IFACE_DBUS */
537                 if (!session) {
538                         WDS_LOGE("Failed to create session");
539                         __WDS_LOG_FUNC_EXIT__;
540                         return;
541                 }
542                 session->type = SESSION_TYPE_NORMAL;
543                 session->state = SESSION_STATE_GO_NEG;
544                 wfd_session_timer(session, 1);
545                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
546
547                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
548                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
549                 noti.error = WIFI_DIRECT_ERROR_NONE;
550                 g_snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
551                 wfd_client_send_event(manager, &noti);
552         } else {
553                 wfd_session_process_event(manager, event);
554         }
555         __WDS_LOG_FUNC_EXIT__;
556         return;
557 }
558
559  static void __wfd_process_go_neg_fail(wfd_manager_s *manager, wfd_oem_event_s *event)
560  {
561         __WDS_LOG_FUNC_ENTER__;
562
563         wfd_session_s *session = NULL;
564         wfd_oem_conn_data_s *edata = NULL;
565         wifi_direct_client_noti_s noti;
566         unsigned char *peer_addr = NULL;
567
568         if (event == NULL || manager == NULL) {
569                 WDS_LOGE("Invalid parameter");
570                 __WDS_LOG_FUNC_EXIT__;
571                 return;
572         }
573
574         session = (wfd_session_s*) manager->session;
575         if (!session) {
576                 WDS_LOGE("Unexpected event. Session not exist");
577                 __WDS_LOG_FUNC_EXIT__;
578                 return;
579         }
580
581         peer_addr = wfd_session_get_peer_addr(session);
582         if (!peer_addr) {
583                 WDS_LOGE("Session do not have peer");
584                 __WDS_LOG_FUNC_EXIT__;
585                 return;
586         }
587
588         edata = (wfd_oem_conn_data_s*) event->edata;
589         if (!edata) {
590                 WDS_LOGE("Invalid p2p connection data");
591                 __WDS_LOG_FUNC_EXIT__;
592                 return;
593         }
594
595         if (edata->status < 0 && session->connecting_120) {
596                 if (session->retry_gsrc) {
597                         g_source_remove(session->retry_gsrc);
598                         session->retry_gsrc = 0;
599                 }
600                 session->retry_gsrc = g_idle_add((GSourceFunc) _wfd_connection_retry, session);
601                 WDS_LOGD("Connection will be retried");
602                 __WDS_LOG_FUNC_EXIT__;
603                 return;
604         }
605
606         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
607         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
608         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
609         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
610         wfd_client_send_event(manager, &noti);
611
612         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
613         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
614
615         wfd_destroy_group(manager, GROUP_IFNAME);
616         wfd_destroy_session(manager);
617         manager->local->dev_role = WFD_DEV_ROLE_NONE;
618         __WDS_LOG_FUNC_EXIT__;
619         return;
620 }
621
622 static void __wfd_process_go_neg_done(wfd_manager_s *manager, wfd_oem_event_s *event)
623 {
624         __WDS_LOG_FUNC_ENTER__;
625
626 #ifdef CTRL_IFACE_DBUS
627         wfd_session_s *session = NULL;
628         wfd_oem_conn_data_s *edata = NULL;
629         wfd_device_s *peer = NULL;
630
631         if (event == NULL || manager == NULL) {
632                 WDS_LOGE("Invalid parameter");
633                 __WDS_LOG_FUNC_EXIT__;
634                 return;
635         }
636
637         edata = (wfd_oem_conn_data_s*) event->edata;
638         if (edata == NULL) {
639                 WDS_LOGE("Invalid event data");
640                 __WDS_LOG_FUNC_EXIT__;
641                 return;
642         }
643
644         session = (wfd_session_s*) manager->session;
645         if(session && session->peer) {
646                 peer = session->peer;
647                 memcpy(peer->intf_addr, edata->peer_intf_addr, MACADDR_LEN);
648         }
649         manager->local->dev_role = event->dev_role;
650         wfd_session_process_event(manager, event);
651 #endif /* CTRL_IFACE_DBUS */
652         __WDS_LOG_FUNC_EXIT__;
653         return;
654 }
655
656 static void __wfd_process_wps_fail(wfd_manager_s *manager, wfd_oem_event_s *event)
657 {
658         __WDS_LOG_FUNC_ENTER__;
659
660         wfd_session_s *session = NULL;
661         wifi_direct_client_noti_s noti;
662         unsigned char *peer_addr = NULL;
663
664         if (event == NULL || manager == NULL) {
665                 WDS_LOGE("Invalid parameter");
666                 __WDS_LOG_FUNC_EXIT__;
667                 return;
668         }
669
670         session = (wfd_session_s*) manager->session;
671         if (!session) {
672                 WDS_LOGE("Unexpected event. Session not exist");
673                 __WDS_LOG_FUNC_EXIT__;
674                 return;
675         }
676
677         peer_addr = wfd_session_get_peer_addr(session);
678         if (!peer_addr) {
679                 WDS_LOGE("Session do not have peer");
680                 __WDS_LOG_FUNC_EXIT__;
681                 return;
682         }
683
684         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
685         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
686         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
687         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
688         wfd_client_send_event(manager, &noti);
689
690         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
691                 wfd_group_s *group = (wfd_group_s*) manager->group;
692                 if (group && !group->member_count && (wfd_group_is_autonomous(group) == FALSE)) {
693                         wfd_destroy_group(manager, GROUP_IFNAME);
694
695                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
696                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
697                 } else {
698                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
699                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
700                 }
701         } else {
702                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
703                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
704         }
705
706         wfd_destroy_session(manager);
707
708         wfd_oem_refresh(manager->oem_ops);
709 #if 0
710         /* After connection failed, scan again */
711         wfd_oem_scan_param_s param;
712         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
713         param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
714         param.scan_time = 2;
715         param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
716         wfd_oem_start_scan(manager->oem_ops, &param);
717         manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
718 #endif
719         __WDS_LOG_FUNC_EXIT__;
720         return;
721 }
722
723  static void __wfd_process_wps_done(wfd_manager_s *manager, wfd_oem_event_s *event)
724  {
725         __WDS_LOG_FUNC_ENTER__;
726
727         wfd_session_process_event(manager, event);
728
729         __WDS_LOG_FUNC_EXIT__;
730         return;
731  }
732
733 static void __wfd_process_key_neg_fail(wfd_manager_s *manager, wfd_oem_event_s *event)
734 {
735         __WDS_LOG_FUNC_ENTER__;
736
737         wfd_session_s *session = NULL;
738         wifi_direct_client_noti_s noti;
739         unsigned char *peer_addr = NULL;
740
741         if (event == NULL || manager == NULL) {
742                 WDS_LOGE("Invalid parameter");
743                 __WDS_LOG_FUNC_EXIT__;
744                 return;
745         }
746
747         session = (wfd_session_s*) manager->session;
748         if (!session) {
749                 WDS_LOGE("Unexpected event. Session not exist");
750                 __WDS_LOG_FUNC_EXIT__;
751                 return;
752         }
753
754         peer_addr = wfd_session_get_peer_addr(session);
755         if (!peer_addr) {
756                 WDS_LOGE("Session do not has peer");
757                 __WDS_LOG_FUNC_EXIT__;
758                 return;
759         }
760
761         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
762         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
763         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
764         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
765         wfd_client_send_event(manager, &noti);
766
767         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
768                 wfd_group_s *group = (wfd_group_s*) manager->group;
769                 if (group && !group->member_count && (wfd_group_is_autonomous(group) == FALSE)) {
770                         wfd_destroy_group(manager, GROUP_IFNAME);
771
772                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
773                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
774                 } else {
775                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
776                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
777                 }
778         } else {
779                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
780                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
781         }
782
783         wfd_destroy_session(manager);
784
785         wfd_oem_refresh(manager->oem_ops);
786 #if 0
787         /* After connection failed, scan again */
788         wfd_oem_scan_param_s param;
789         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
790         param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
791         param.scan_time = 2;
792         param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
793         wfd_oem_start_scan(manager->oem_ops, &param);
794         manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
795 #endif
796         __WDS_LOG_FUNC_EXIT__;
797         return;
798 }
799
800 static void __wfd_process_key_neg_done(wfd_manager_s *manager, wfd_oem_event_s *event)
801 {
802         __WDS_LOG_FUNC_ENTER__;
803
804         __WDS_LOG_FUNC_EXIT__;
805         return;
806 }
807
808 static void __wfd_process_conn_fail(wfd_manager_s *manager, wfd_oem_event_s *event)
809 {
810         __WDS_LOG_FUNC_ENTER__;
811
812         __WDS_LOG_FUNC_EXIT__;
813         return;
814 }
815
816 static void __wfd_process_conn_done(wfd_manager_s *manager, wfd_oem_event_s *event)
817 {
818         __WDS_LOG_FUNC_ENTER__;
819
820         __WDS_LOG_FUNC_EXIT__;
821         return;
822 }
823
824 static void __wfd_process_group_created(wfd_manager_s *manager, wfd_oem_event_s *event)
825 {
826         __WDS_LOG_FUNC_ENTER__;
827
828         wfd_group_s *group = NULL;
829         wfd_session_s *session = NULL;
830         wifi_direct_client_noti_s noti;
831
832         if (event == NULL || manager == NULL) {
833                 WDS_LOGE("Invalid parameter");
834                 __WDS_LOG_FUNC_EXIT__;
835                 return;
836         }
837
838         group = (wfd_group_s*) manager->group;
839         session = (wfd_session_s*)manager->session;
840 #ifdef CTRL_IFACE_DBUS
841         if(event->dev_role == WFD_DEV_ROLE_GC && !group) {
842
843                 group = wfd_create_pending_group(manager, event->intf_addr);
844                 if (!group) {
845                         WDS_LOGE("Failed to create pending group");
846                         __WDS_LOG_FUNC_EXIT__;
847                         return;
848                 }
849                 manager->group = group;
850         }
851 #endif /* CTRL_IFACE_DBUS */
852         if (!group) {
853                 if (!session) {
854                         WDS_LOGE("Unexpected Event. Group should be removed(Client)");
855                         wfd_oem_destroy_group(manager->oem_ops, event->ifname);
856                         __WDS_LOG_FUNC_EXIT__;
857                         return;
858                 }
859
860                 group = wfd_create_group(manager, event);
861                 if (!group) {
862                         WDS_LOGE("Failed to create group");
863                         __WDS_LOG_FUNC_EXIT__;
864                         return;
865                 }
866         } else {
867                 if (!session && !(group->flags & WFD_GROUP_FLAG_AUTONOMOUS)) {
868                         WDS_LOGE("Unexpected Event. Group should be removed(Owner)");
869                         wfd_oem_destroy_group(manager->oem_ops, group->ifname);
870                         __WDS_LOG_FUNC_EXIT__;
871                         return;
872                 }
873
874                 if (group->pending) {
875                         wfd_group_complete(manager, event);
876                 } else {
877                         WDS_LOGE("Unexpected event. Group already exist");
878                         __WDS_LOG_FUNC_EXIT__;
879                         return;
880                 }
881         }
882
883         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
884         if (group->role == WFD_DEV_ROLE_GC && session) {
885 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
886                 wfd_device_s *peer = session->peer;
887                 if(peer == NULL) {
888                         WDS_LOGE("Unexpected event. Peer doesn't exist");
889                         return;
890                 }
891
892                 wfd_update_peer(manager, peer);
893
894                 if(peer->ip_type == WFD_IP_TYPE_OVER_EAPOL) {
895
896                         wfd_util_ip_over_eap_assign(peer, event->ifname);
897
898                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
899                         noti.error = WIFI_DIRECT_ERROR_NONE;
900                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
901                         wfd_client_send_event(manager, &noti);
902
903                         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
904                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
905
906                         wfd_destroy_session(manager);
907                 }
908 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
909                 wfd_peer_clear_all(manager);
910         } else {
911                 if (group->flags & WFD_GROUP_FLAG_AUTONOMOUS) {
912                         noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_CREATE_RSP;
913                         wfd_client_send_event(manager, &noti);
914                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
915                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
916                 }
917         }
918         __WDS_LOG_FUNC_EXIT__;
919         return;
920 }
921
922 static void __wfd_process_group_destroyed(wfd_manager_s *manager, wfd_oem_event_s *event)
923 {
924         __WDS_LOG_FUNC_ENTER__;
925
926         wifi_direct_client_noti_s noti;
927
928         if (event == NULL || manager == NULL) {
929                 WDS_LOGE("Invalid parameter");
930                 __WDS_LOG_FUNC_EXIT__;
931                 return;
932         }
933
934         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
935         if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
936                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
937                 noti.error = WIFI_DIRECT_ERROR_NONE;
938         } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING && manager->session){
939                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
940                 noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
941                 unsigned char *peer_addr = wfd_session_get_peer_addr(manager->session);
942                 if(peer_addr != NULL)
943                         g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
944         } else if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
945 #if defined (CTRL_IFACE_DBUS)
946                 if(manager->local->dev_role != WFD_DEV_ROLE_GO)
947                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
948                 else
949 #endif
950                 noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_DESTROY_RSP;
951                 noti.error = WIFI_DIRECT_ERROR_NONE;
952         } else {
953                 WDS_LOGD("Unexpected event(GROUP_DESTROYED). Ignore it");
954                 __WDS_LOG_FUNC_EXIT__;
955                 return;
956         }
957         wfd_client_send_event(manager, &noti);
958
959         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
960         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
961         wfd_destroy_group(manager, event->ifname);
962         wfd_destroy_session(manager);
963         manager->local->dev_role = WFD_DEV_ROLE_NONE;
964
965         __WDS_LOG_FUNC_EXIT__;
966         return;
967 }
968
969 static void __wfd_process_invitation_req(wfd_manager_s *manager, wfd_oem_event_s *event)
970 {
971         __WDS_LOG_FUNC_ENTER__;
972
973         wfd_device_s *peer = NULL;
974         wfd_session_s *session = NULL;
975         wfd_oem_invite_data_s *edata = NULL;
976         wifi_direct_client_noti_s noti;
977         int res = 0;
978
979         if (event == NULL || manager == NULL) {
980                 WDS_LOGE("Invalid parameter");
981                 __WDS_LOG_FUNC_EXIT__;
982                 return;
983         }
984
985         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
986         if (!peer) {
987                 WDS_LOGD("Invitation from unknown peer. Add new peer");
988                 peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
989                 if (!peer) {
990                         WDS_LOGE("Failed to add peer for invitation");
991                         __WDS_LOG_FUNC_EXIT__;
992                         return;
993                 }
994         }
995         peer->dev_role = WFD_DEV_ROLE_GO;
996
997         edata = (wfd_oem_invite_data_s*) event->edata;
998         memcpy(peer->intf_addr, edata->bssid, MACADDR_LEN);
999         wfd_update_peer_time(manager, event->dev_addr);
1000
1001         session = wfd_create_session(manager, event->dev_addr,
1002                                         manager->req_wps_mode, SESSION_DIRECTION_INCOMING);
1003         if (!session) {
1004                 WDS_LOGE("Failed to create session");
1005                 __WDS_LOG_FUNC_EXIT__;
1006                 return;
1007         }
1008         session->type = SESSION_TYPE_INVITE;
1009         wfd_session_timer(session, 1);
1010
1011         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
1012
1013         res = wfd_session_start(session);
1014         if (res < 0) {
1015                 WDS_LOGE("Failed to start session");
1016                 __WDS_LOG_FUNC_EXIT__;
1017                 return;
1018         }
1019
1020         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
1021         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
1022         noti.error = WIFI_DIRECT_ERROR_NONE;
1023         snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
1024         wfd_client_send_event(manager, &noti);
1025
1026         __WDS_LOG_FUNC_EXIT__;
1027         return;
1028 }
1029
1030 static void __wfd_process_invitation_res(wfd_manager_s *manager, wfd_oem_event_s *event)
1031 {
1032         __WDS_LOG_FUNC_ENTER__;
1033
1034         __WDS_LOG_FUNC_EXIT__;
1035         return;
1036 }
1037
1038 static void __wfd_process_sta_connected(wfd_manager_s *manager, wfd_oem_event_s *event)
1039 {
1040         __WDS_LOG_FUNC_ENTER__;
1041
1042         wfd_session_s *session = NULL;
1043         wfd_device_s *peer = NULL;
1044         wfd_group_s *group = NULL;
1045         wifi_direct_client_noti_s noti;
1046
1047         if (event == NULL || manager == NULL) {
1048                 WDS_LOGE("Invalid parameter");
1049                 __WDS_LOG_FUNC_EXIT__;
1050                 return;
1051         }
1052
1053         // FIXME: Move this code to plugin
1054         if (!memcmp(event->intf_addr, manager->local->intf_addr, MACADDR_LEN)) {
1055                 WDS_LOGD("Ignore this event");
1056                 __WDS_LOG_FUNC_EXIT__;
1057                 return;
1058         }
1059
1060         session = (wfd_session_s*) manager->session;
1061         if (!session) {
1062                 WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1063                                                                         MAC2SECSTR(event->dev_addr));
1064                 wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
1065                 wfd_destroy_group(manager, GROUP_IFNAME);
1066                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1067                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1068                 __WDS_LOG_FUNC_EXIT__;
1069                 return;
1070         }
1071
1072         peer = wfd_session_get_peer(session);
1073         if (!peer) {
1074                 WDS_LOGE("Peer not found");
1075                 __WDS_LOG_FUNC_EXIT__;
1076                 return;
1077         }
1078
1079         group = (wfd_group_s*) manager->group;
1080         if (!group) {
1081                 group = wfd_create_pending_group(manager, event->intf_addr);
1082                 if (!group) {
1083                         WDS_LOGE("Failed to create pending group");
1084                         __WDS_LOG_FUNC_EXIT__;
1085                         return;
1086                 }
1087                 manager->group = group;
1088         }
1089         wfd_group_add_member(group, peer->dev_addr);
1090
1091         session->state = SESSION_STATE_COMPLETED;
1092 #ifndef CTRL_IFACE_DBUS
1093         memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
1094 #endif /* CTRL_IFACE_DBUS */
1095         peer->state = WFD_PEER_STATE_CONNECTED;
1096
1097         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1098         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1099
1100         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
1101         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
1102         noti.error = WIFI_DIRECT_ERROR_NONE;
1103         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1104         wfd_client_send_event(manager, &noti);
1105 #ifdef CTRL_IFACE_DBUS
1106         wfd_update_peer(manager, peer);
1107 #endif /* CTRL_IFACE_DBUS */
1108 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
1109         if (event->ip_addr_peer[3]) {
1110                 peer->ip_type = WFD_IP_TYPE_OVER_EAPOL;
1111                 memcpy(peer->client_ip_addr, event->ip_addr_peer, IPADDR_LEN);
1112                 WDS_LOGE("Peer's client IP [" IPSTR "]", IP2STR((char*) &peer->client_ip_addr));
1113                 memcpy(peer->go_ip_addr, manager->local->ip_addr, IPADDR_LEN);
1114                 WDS_LOGE("Peer's GO IP [" IPSTR "]", IP2STR((char*) &peer->go_ip_addr));
1115         }
1116         if(peer->ip_type == WFD_IP_TYPE_OVER_EAPOL) {
1117                 memcpy(peer->ip_addr, peer->client_ip_addr, IPADDR_LEN);
1118
1119                 wifi_direct_client_noti_s noti;
1120                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
1121                 noti.event = WIFI_DIRECT_CLI_EVENT_IP_LEASED_IND;
1122                 noti.error = WIFI_DIRECT_ERROR_NONE;
1123                 snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1124                 snprintf(noti.param2, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1125                 wfd_client_send_event(manager, &noti);
1126         } else
1127 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
1128         wfd_util_dhcps_wait_ip_leased(peer);
1129         wfd_destroy_session(manager);
1130
1131         __WDS_LOG_FUNC_EXIT__;
1132         return;
1133 }
1134
1135 static void __wfd_process_sta_disconnected(wfd_manager_s *manager, wfd_oem_event_s *event)
1136 {
1137         __WDS_LOG_FUNC_ENTER__;
1138
1139         wfd_group_s *group = NULL;
1140         wfd_device_s *peer = NULL;
1141         wifi_direct_client_noti_s noti;
1142         unsigned char peer_addr[MACADDR_LEN] = {0, };
1143
1144         if (event == NULL || manager == NULL) {
1145                 WDS_LOGE("Invalid parameter");
1146                 __WDS_LOG_FUNC_EXIT__;
1147                 return;
1148         }
1149
1150         group = (wfd_group_s*) manager->group;
1151         if (!group) {
1152                 WDS_LOGE("Group not found");
1153                 __WDS_LOG_FUNC_EXIT__;
1154                 return;
1155         }
1156
1157 #ifdef CTRL_IFACE_DBUS
1158         peer = wfd_group_find_member_by_addr(group, event->dev_addr);
1159 #else /* CTRL_IFACE_DBUS */
1160         peer = wfd_group_find_member_by_addr(group, event->intf_addr);
1161 #endif /* DBUS_IFACE */
1162         if (!peer) {
1163                 WDS_LOGE("Failed to find connected peer");
1164                 peer = wfd_session_get_peer(manager->session);
1165                 if (!peer) {
1166                         WDS_LOGE("Failed to find connecting peer");
1167                         __WDS_LOG_FUNC_EXIT__;
1168                         return;
1169                 }
1170
1171 #ifdef CTRL_IFACE_DBUS
1172                 /**
1173                  * If no peer connected and
1174                  * disconnected event is not for connecting peer
1175                  * then event should be ignored.
1176                  * This situation can arrise when TV is GO and
1177                  * some connected peer sent disassociation.
1178                  */
1179                 if (memcmp(peer_addr, event->dev_addr, MACADDR_LEN)) {
1180                         WDS_LOGE("Unexpected event, Ignore it...");
1181                         __WDS_LOG_FUNC_EXIT__;
1182                         return;
1183                 }
1184 #endif /* CTRL_DBUS_IFACE */
1185         }
1186         memcpy(peer_addr, peer->dev_addr, MACADDR_LEN);
1187         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
1188
1189         /* If state is not DISCONNECTING, connection is finished by peer */
1190         if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
1191                 wfd_group_remove_member(group, peer_addr);
1192                 if (group->member_count)
1193                         noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
1194                 else
1195                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_IND;
1196                 noti.error = WIFI_DIRECT_ERROR_NONE;
1197                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1198                 /* If there is no member, GO should be destroyed */
1199 #ifdef TIZEN_TV
1200                 /* If GO is Auto GO, then it should not be removed when no member left */
1201                 if (!group->member_count && (wfd_group_is_autonomous(group) == FALSE)) {
1202 #else /* TIZEN_TV */
1203                 if (!group->member_count) {
1204 #endif /* TIZEN_TV */
1205                         wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1206                         wfd_destroy_group(manager, group->ifname);
1207                         wfd_peer_clear_all(manager);
1208                 }
1209         } else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
1210                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
1211                 noti.error = WIFI_DIRECT_ERROR_NONE;
1212                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1213         } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
1214                         /* Some devices(GO) send disconnection message before connection completed.
1215                          * This message should be ignored when device is not GO */
1216                         manager->local->dev_role == WFD_DEV_ROLE_GO) {
1217                 if (WFD_PEER_STATE_CONNECTED == peer->state) {
1218                         WDS_LOGD("Peer is already Connected !!!");
1219                         noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
1220                         noti.error = WIFI_DIRECT_ERROR_NONE;
1221                 } else if (WFD_PEER_STATE_CONNECTING == peer->state) {
1222                         WDS_LOGD("Peer is Connecting...");
1223                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
1224                         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
1225                 } else {
1226                         WDS_LOGE("Unexpected Peer State. Ignore it");
1227                         __WDS_LOG_FUNC_EXIT__;
1228                         return;
1229                 }
1230                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1231         } else {
1232                 WDS_LOGE("Unexpected event. Ignore it");
1233                 __WDS_LOG_FUNC_EXIT__;
1234                 return;
1235         }
1236         wfd_client_send_event(manager, &noti);
1237
1238         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1239         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1240         wfd_destroy_session(manager);
1241
1242         __WDS_LOG_FUNC_EXIT__;
1243         return;
1244  }
1245
1246  static void __wfd_process_connected(wfd_manager_s *manager, wfd_oem_event_s *event)
1247  {
1248         __WDS_LOG_FUNC_ENTER__;
1249
1250         wfd_session_s *session = NULL;
1251         wfd_device_s *peer = NULL;
1252         wfd_group_s *group = NULL;
1253
1254         if (event == NULL || manager == NULL) {
1255                 WDS_LOGE("Invalid parameter");
1256                 __WDS_LOG_FUNC_EXIT__;
1257                 return;
1258         }
1259
1260         // FIXME: Move this code to plugin
1261         if (!memcmp(event->intf_addr, manager->local->intf_addr, MACADDR_LEN)) {
1262                 WDS_LOGD("Ignore this event");
1263                 __WDS_LOG_FUNC_EXIT__;
1264                 return;
1265         }
1266
1267         session = (wfd_session_s*) manager->session;
1268         if (!session) {
1269                 WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1270                                                                         MAC2SECSTR(event->dev_addr));
1271                 wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
1272                 wfd_destroy_group(manager, GROUP_IFNAME);
1273                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1274                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1275                 __WDS_LOG_FUNC_EXIT__;
1276                 return;
1277         }
1278
1279         peer = wfd_session_get_peer(session);
1280         if (!peer) {
1281                 WDS_LOGE("Peer not found");
1282                 __WDS_LOG_FUNC_EXIT__;
1283                 return;
1284         }
1285
1286         group = (wfd_group_s*) manager->group;
1287         if (!group) {
1288                 group = wfd_create_pending_group(manager, event->intf_addr);
1289                 if (!group) {
1290                         WDS_LOGE("Failed to create pending group");
1291                         __WDS_LOG_FUNC_EXIT__;
1292                         return;
1293                 }
1294                 manager->group = group;
1295         }
1296         wfd_group_add_member(group, peer->dev_addr);
1297
1298         session->state = SESSION_STATE_COMPLETED;
1299 #ifndef CTRL_IFACE_DBUS
1300         memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
1301 #endif /* CTRL_IFACE_DBUS */
1302         peer->state = WFD_PEER_STATE_CONNECTED;
1303
1304         __WDS_LOG_FUNC_EXIT__;
1305         return;
1306  }
1307
1308  static void __wfd_process_disconnected(wfd_manager_s *manager, wfd_oem_event_s *event)
1309  {
1310         __WDS_LOG_FUNC_ENTER__;
1311
1312         wfd_group_s *group = NULL;
1313         wfd_device_s *peer = NULL;
1314         wifi_direct_client_noti_s noti;
1315         unsigned char peer_addr[MACADDR_LEN] = {0, };
1316
1317         if (event == NULL || manager == NULL) {
1318                 WDS_LOGE("Invalid parameter");
1319                 __WDS_LOG_FUNC_EXIT__;
1320                 return;
1321         }
1322
1323         group = (wfd_group_s*) manager->group;
1324         if (!group) {
1325                 WDS_LOGE("Group not found");
1326                 __WDS_LOG_FUNC_EXIT__;
1327                 return;
1328         }
1329
1330 #ifdef CTRL_IFACE_DBUS
1331         peer = wfd_group_find_member_by_addr(group, event->dev_addr);
1332 #else /* CTRL_IFACE_DBUS */
1333         peer = wfd_group_find_member_by_addr(group, event->intf_addr);
1334 #endif /* DBUS_IFACE */
1335         if (!peer) {
1336                 WDS_LOGE("Failed to find connected peer");
1337                 peer = wfd_session_get_peer(manager->session);
1338                 if (!peer) {
1339                         WDS_LOGE("Failed to find connecting peer");
1340                         __WDS_LOG_FUNC_EXIT__;
1341                         return;
1342                 }
1343         }
1344         memcpy(peer_addr, peer->dev_addr, MACADDR_LEN);
1345         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
1346
1347         /* If state is not DISCONNECTING, connection is finished by peer */
1348         if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
1349                 wfd_group_remove_member(group, peer_addr);
1350                 if (group->member_count)
1351                         noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
1352                 else
1353                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_IND;
1354                 noti.error = WIFI_DIRECT_ERROR_NONE;
1355                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1356                 /* If there is no member, GO should be destroyed */
1357 #ifdef TIZEN_TV
1358                 /* If GO is Auto GO, then it should not be removed when no member left */
1359                 if (!group->member_count && (wfd_group_is_autonomous(group) == FALSE)) {
1360 #else /* TIZEN_TV */
1361                 if (!group->member_count) {
1362 #endif /* TIZEN_TV */
1363                         wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1364                         wfd_destroy_group(manager, group->ifname);
1365                 }
1366         } else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
1367                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
1368                 noti.error = WIFI_DIRECT_ERROR_NONE;
1369                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1370         } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
1371                         /* Some devices(GO) send disconnection message before connection completed.
1372                          * This message should be ignored when device is not GO */
1373                         manager->local->dev_role == WFD_DEV_ROLE_GO) {
1374                 if (WFD_PEER_STATE_CONNECTED == peer->state) {
1375                         WDS_LOGD("Peer is already Connected !!!");
1376                         noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
1377                         noti.error = WIFI_DIRECT_ERROR_NONE;
1378                 } else if (WFD_PEER_STATE_CONNECTING == peer->state) {
1379                         WDS_LOGD("Peer is Connecting...");
1380                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
1381                         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
1382                 } else {
1383                         WDS_LOGE("Unexpected Peer State. Ignore it");
1384                         return;
1385                 }
1386                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1387         } else {
1388                 WDS_LOGE("Unexpected event. Ignore it");
1389                 __WDS_LOG_FUNC_EXIT__;
1390                 return;
1391         }
1392         wfd_client_send_event(manager, &noti);
1393
1394         wfd_destroy_group(manager, GROUP_IFNAME);
1395         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1396         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1397         wfd_destroy_session(manager);
1398
1399         __WDS_LOG_FUNC_EXIT__;
1400         return;
1401  }
1402
1403  static void __wfd_process_terminating(wfd_manager_s *manager, wfd_oem_event_s *event)
1404  {
1405         __WDS_LOG_FUNC_ENTER__;
1406
1407         __WDS_LOG_FUNC_EXIT__;
1408         return;
1409  }
1410
1411 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1412 static void __wfd_process_serv_disc_resp(wfd_manager_s *manager, wfd_oem_event_s *event)
1413 {
1414         __WDS_LOG_FUNC_ENTER__;
1415
1416         wifi_direct_client_noti_s noti;
1417
1418         if (event == NULL || manager == NULL) {
1419                 WDS_LOGE("Invalid parameter");
1420                 __WDS_LOG_FUNC_EXIT__;
1421                 return;
1422         }
1423
1424         wfd_update_peer_time(manager, event->dev_addr);
1425
1426         if (event->edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE) {
1427                 wfd_oem_new_service_s *service = NULL;;
1428                 GList *temp = NULL;
1429                 GList *services = (GList*) event->edata;
1430                 int count = 0;
1431
1432                 WDS_LOGD("%d service data found", event->dev_role);
1433
1434                 temp = g_list_first(services);
1435                 while(temp && count < event->dev_role) {
1436                         service = (wfd_oem_new_service_s*) temp->data;
1437                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
1438                         noti.event = WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FOUND;
1439                         noti.type = service->protocol;
1440                         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
1441                                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1442                                 g_snprintf(noti.param2, 256, "%s|%s", service->data.bonjour.query, service->data.bonjour.rdata);
1443                                 WDS_LOGD("Found service: [%d: %s] - [" MACSECSTR "]", service->protocol,
1444                                                         service->data.bonjour.query, MAC2SECSTR(event->dev_addr));
1445                         } else {
1446                                 WDS_LOGD("Found service is not supported");
1447                                 goto next;
1448                         }
1449                         wfd_client_send_event(manager, &noti);
1450 next:
1451                         temp = g_list_next(temp);
1452                         service = NULL;
1453                         count++;
1454                 }
1455         } else if (event->edata_type == WFD_OEM_EDATA_TYPE_SERVICE) {
1456                 wfd_oem_service_data_s *edata = (wfd_oem_service_data_s*) event->edata;
1457
1458                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
1459                 noti.event = WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FOUND;
1460                 if(!edata) {
1461                         noti.type = -1;
1462                 } else {
1463                         noti.type = edata->type;
1464                         g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1465                         switch(edata->type) {
1466                                 WDS_LOGE("Unknown type [type ID: %d]", edata->type);
1467                         }
1468                 }
1469                 wfd_client_send_event(manager, &noti);
1470         }
1471
1472         __WDS_LOG_FUNC_EXIT__;
1473         return;
1474 }
1475
1476 static void __wfd_process_serv_disc_started(wfd_manager_s *manager, wfd_oem_event_s *event)
1477 {
1478         __WDS_LOG_FUNC_ENTER__;
1479
1480         __WDS_LOG_FUNC_EXIT__;
1481         return;
1482 }
1483 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1484
1485 static struct {
1486  const int event_id;
1487  void (*function) (wfd_manager_s *manager, wfd_oem_event_s *event);
1488 } wfd_oem_event_map[] = {
1489         {
1490                 WFD_OEM_EVENT_DEACTIVATED,
1491                 __wfd_process_deactivated
1492         },
1493         {
1494                 WFD_OEM_EVENT_PEER_FOUND,
1495                 __wfd_process_peer_found
1496         },
1497         {
1498                 WFD_OEM_EVENT_PEER_DISAPPEARED,
1499                 __wfd_process_peer_disappeared
1500         },
1501         {
1502                 WFD_OEM_EVENT_DISCOVERY_FINISHED,
1503                 __wfd_process_discovery_finished
1504         },
1505         {
1506                 WFD_OEM_EVENT_PROV_DISC_REQ,
1507                 __wfd_process_prov_disc_req
1508         },
1509         {
1510                 WFD_OEM_EVENT_PROV_DISC_RESP,
1511                 __wfd_process_prov_disc_resp
1512         },
1513         {
1514                 WFD_OEM_EVENT_PROV_DISC_FAIL,
1515                 __wfd_process_prov_disc_fail
1516         },
1517         {
1518                 WFD_OEM_EVENT_GO_NEG_REQ,
1519                 __wfd_process_go_neg_req
1520         },
1521         {
1522                 WFD_OEM_EVENT_GO_NEG_FAIL,
1523                 __wfd_process_go_neg_fail
1524         },
1525         {
1526                 WFD_OEM_EVENT_GO_NEG_DONE,
1527                 __wfd_process_go_neg_done
1528         },
1529         {
1530                 WFD_OEM_EVENT_WPS_FAIL,
1531                 __wfd_process_wps_fail
1532         },
1533         {
1534                 WFD_OEM_EVENT_WPS_DONE,
1535                 __wfd_process_wps_done
1536         },
1537         {
1538                 WFD_OEM_EVENT_KEY_NEG_FAIL,
1539                 __wfd_process_key_neg_fail
1540         },
1541         {
1542                 WFD_OEM_EVENT_KEY_NEG_DONE,
1543                 __wfd_process_key_neg_done
1544         },
1545         {
1546                 WFD_OEM_EVENT_CONN_FAIL,
1547                 __wfd_process_conn_fail
1548         },
1549         {
1550                 WFD_OEM_EVENT_CONN_DONE,
1551                 __wfd_process_conn_done
1552         },
1553         {
1554                 WFD_OEM_EVENT_GROUP_CREATED,
1555                 __wfd_process_group_created
1556         },
1557         {
1558                 WFD_OEM_EVENT_GROUP_DESTROYED,
1559                 __wfd_process_group_destroyed
1560         },
1561         {
1562                 WFD_OEM_EVENT_INVITATION_REQ,
1563                 __wfd_process_invitation_req
1564         },
1565         {
1566                 WFD_OEM_EVENT_INVITATION_RES,
1567                 __wfd_process_invitation_res
1568         },
1569         {
1570                 WFD_OEM_EVENT_STA_CONNECTED,
1571                 __wfd_process_sta_connected
1572         },
1573         {
1574                 WFD_OEM_EVENT_STA_DISCONNECTED,
1575                 __wfd_process_sta_disconnected
1576         },
1577         {
1578                 WFD_OEM_EVENT_CONNECTED,
1579                 __wfd_process_connected
1580         },
1581         {
1582                 WFD_OEM_EVENT_DISCONNECTED,
1583                 __wfd_process_disconnected
1584         },
1585         {
1586                 WFD_OEM_EVENT_TERMINATING,
1587                 __wfd_process_terminating
1588         },
1589 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1590         {
1591                 WFD_OEM_EVENT_SERV_DISC_RESP,
1592                 __wfd_process_serv_disc_resp
1593         },
1594         {
1595                 WFD_OEM_EVENT_SERV_DISC_STARTED,
1596                 __wfd_process_serv_disc_started
1597         },
1598 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1599         {
1600                 WFD_OEM_EVENT_MAX,
1601                 NULL
1602         }
1603  };
1604
1605  int wfd_process_event(void *user_data, void *data)
1606  {
1607         __WDS_LOG_FUNC_ENTER__;
1608         wfd_manager_s *manager = NULL;
1609         wfd_oem_event_s *event = NULL;
1610         int i = 0;
1611
1612         if (!user_data || !data) {
1613                 WDS_LOGE("Invalid parameter");
1614                 __WDS_LOG_FUNC_EXIT__;
1615                 return -1;
1616         }
1617
1618         manager = (wfd_manager_s*) user_data;
1619         event = (wfd_oem_event_s*) data;
1620         WDS_LOGD("Event[%d] from " MACSECSTR, event->event_id,
1621                                                 MAC2SECSTR(event->dev_addr));
1622         for(i = 0; wfd_oem_event_map[i].function != NULL; i++) {
1623                 if(event->event_id == wfd_oem_event_map[i].event_id)
1624                  wfd_oem_event_map[i].function(manager, event);
1625         }
1626
1627         __WDS_LOG_FUNC_EXIT__;
1628         return 0;
1629  }