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