0623e1458ced8ec5ed6f0f398bf40af97ea4c7c5
[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_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                 if (wfd_group_add_member(group, peer->dev_addr) == -1) {
976                         WDS_LOGE("Failed to add Legacy peer.");
977                         __WDS_LOG_FUNC_EXIT__;
978                         return;
979                 }
980
981                 memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
982                 peer->state = WFD_PEER_STATE_CONNECTED;
983                 peer->is_legacy = TRUE;
984
985                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
986                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
987                                              "Connection",
988                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
989                                                                     WFD_EVENT_CONNECTION_RSP,
990                                                                     peer_mac_address));
991
992                 wfd_util_dhcps_wait_ip_leased(peer);
993                 __WDS_LOG_FUNC_EXIT__;
994                 return;
995         }
996
997         session = (wfd_session_s*) manager->session;
998         if (!session) {
999                 WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1000                                                                         MAC2SECSTR(event->dev_addr));
1001                 wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
1002                 wfd_destroy_group(manager, GROUP_IFNAME);
1003                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1004                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1005                 __WDS_LOG_FUNC_EXIT__;
1006                 return;
1007         }
1008
1009         peer = wfd_session_get_peer(session);
1010         if (!peer) {
1011                 WDS_LOGE("Peer not found");
1012                 __WDS_LOG_FUNC_EXIT__;
1013                 return;
1014         }
1015
1016         group = (wfd_group_s*) manager->group;
1017         if (!group) {
1018                 group = wfd_create_pending_group(manager, event->intf_addr);
1019                 if (!group) {
1020                         WDS_LOGE("Failed to create pending group");
1021                         __WDS_LOG_FUNC_EXIT__;
1022                         return;
1023                 }
1024                 manager->group = group;
1025         }
1026         wfd_group_add_member(group, peer->dev_addr);
1027
1028         session->state = SESSION_STATE_COMPLETED;
1029 #ifndef CTRL_IFACE_DBUS
1030         memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
1031 #endif /* CTRL_IFACE_DBUS */
1032         peer->state = WFD_PEER_STATE_CONNECTED;
1033
1034         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1035         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1036
1037         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1038         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1039                                      "Connection",
1040                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1041                                                             WFD_EVENT_CONNECTION_RSP,
1042                                                             peer_mac_address));
1043
1044 #ifdef CTRL_IFACE_DBUS
1045         wfd_update_peer(manager, peer);
1046 #endif /* CTRL_IFACE_DBUS */
1047 #ifdef TIZEN_FEATURE_IP_OVER_EAPOL
1048         if (event->ip_addr_peer[3]) {
1049                 peer->ip_type = WFD_IP_TYPE_OVER_EAPOL;
1050                 memcpy(peer->client_ip_addr, event->ip_addr_peer, IPADDR_LEN);
1051                 WDS_LOGE("Peer's client IP [" IPSTR "]", IP2STR((char*) &peer->client_ip_addr));
1052                 memcpy(peer->go_ip_addr, manager->local->ip_addr, IPADDR_LEN);
1053                 WDS_LOGE("Peer's GO IP [" IPSTR "]", IP2STR((char*) &peer->go_ip_addr));
1054         }
1055         if (peer->ip_type == WFD_IP_TYPE_OVER_EAPOL) {
1056                 char peer_mac_address[MACSTR_LEN+1] = {0,};
1057                 char assigned_ip_address[IPSTR_LEN+1] = {0,};
1058
1059                 memcpy(peer->ip_addr, peer->client_ip_addr, IPADDR_LEN);
1060
1061                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1062                 g_snprintf(assigned_ip_address, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1063                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1064                                      "PeerIPAssigned",
1065                                      g_variant_new("(ss)", peer_mac_address,
1066                                                            assigned_ip_address));
1067         } else
1068 #endif /* TIZEN_FEATURE_IP_OVER_EAPOL */
1069         wfd_util_dhcps_wait_ip_leased(peer);
1070         wfd_destroy_session(manager);
1071
1072         __WDS_LOG_FUNC_EXIT__;
1073         return;
1074 }
1075
1076 static void __wfd_process_sta_disconnected(wfd_manager_s *manager, wfd_oem_event_s *event)
1077 {
1078         __WDS_LOG_FUNC_ENTER__;
1079
1080         wfd_group_s *group = NULL;
1081         wfd_device_s *peer = NULL;
1082         unsigned char peer_addr[MACADDR_LEN] = {0, };
1083         char peer_mac_address[MACSTR_LEN+1] = {0, };
1084
1085         group = (wfd_group_s*) manager->group;
1086         if (!group) {
1087                 WDS_LOGE("Group not found");
1088                 __WDS_LOG_FUNC_EXIT__;
1089                 return;
1090         }
1091
1092         if (ISZEROMACADDR(event->dev_addr)) {
1093                 WDS_LOGD("Legacy Peer Disconnected [Peer: " MACSTR "]", MAC2STR(event->intf_addr));
1094                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->intf_addr));
1095                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1096                                              "Disconnection",
1097                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1098                                                                     WFD_EVENT_DISCONNECTION_IND,
1099                                                                     peer_mac_address));
1100
1101                 wfd_group_remove_member(group, event->intf_addr);
1102
1103                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1104                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1105                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1106                 } else {
1107                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1108                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1109                 }
1110                 __WDS_LOG_FUNC_EXIT__;
1111                 return;
1112         }
1113
1114 #ifdef CTRL_IFACE_DBUS
1115         peer = wfd_group_find_member_by_addr(group, event->dev_addr);
1116 #else /* CTRL_IFACE_DBUS */
1117         peer = wfd_group_find_member_by_addr(group, event->intf_addr);
1118 #endif /* DBUS_IFACE */
1119         if (!peer) {
1120                 WDS_LOGE("Failed to find connected peer");
1121                 peer = wfd_session_get_peer(manager->session);
1122                 if (!peer) {
1123                         WDS_LOGE("Failed to find connecting peer");
1124                         __WDS_LOG_FUNC_EXIT__;
1125                         return;
1126                 }
1127
1128 #ifdef CTRL_IFACE_DBUS
1129                 /**
1130                  * If no peer connected and
1131                  * disconnected event is not for connecting peer
1132                  * then event should be ignored.
1133                  * This situation can arrise when TV is GO and
1134                  * some connected peer sent disassociation.
1135                  */
1136                 if (memcmp(peer_addr, event->dev_addr, MACADDR_LEN)) {
1137                         WDS_LOGE("Unexpected event, Ignore it...");
1138                         __WDS_LOG_FUNC_EXIT__;
1139                         return;
1140                 }
1141 #endif /* CTRL_DBUS_IFACE */
1142         }
1143         memcpy(peer_addr, peer->dev_addr, MACADDR_LEN);
1144
1145         /**
1146          * If state is not DISCONNECTING, connection is finished by peer.
1147          *  Required the check also, when Device is Group Owner and state is DISCOVERING.
1148          */
1149         if (manager->state >= WIFI_DIRECT_STATE_CONNECTED ||
1150                                 (manager->state == WIFI_DIRECT_STATE_DISCOVERING &&
1151                                  manager->local->dev_role == WFD_DEV_ROLE_GO)) {
1152                 wfd_group_remove_member(group, peer_addr);
1153                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1154                 if (group->member_count) {
1155                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1156                                                      "Disconnection",
1157                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1158                                                                             WFD_EVENT_DISASSOCIATION_IND,
1159                                                                             peer_mac_address));
1160                 } else {
1161                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1162                                                      "Disconnection",
1163                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1164                                                                             WFD_EVENT_DISCONNECTION_IND,
1165                                                                             peer_mac_address));
1166                 }
1167
1168         } else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
1169                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1170                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1171                                              "Disconnection",
1172                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1173                                                                     WFD_EVENT_DISCONNECTION_RSP,
1174                                                                     peer_mac_address));
1175
1176         } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
1177                         /* Some devices(GO) send disconnection message before connection completed.
1178                          * This message should be ignored when device is not GO */
1179                         manager->local->dev_role == WFD_DEV_ROLE_GO) {
1180                 if (WFD_PEER_STATE_CONNECTED == peer->state) {
1181                         WDS_LOGD("Peer is already Connected !!!");
1182                         wfd_group_remove_member(group, peer_addr);
1183                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1184                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1185                                                      "Disconnection",
1186                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1187                                                                             WFD_EVENT_DISASSOCIATION_IND,
1188                                                                             peer_mac_address));
1189
1190                 } else if (WFD_PEER_STATE_CONNECTING == peer->state) {
1191                         WDS_LOGD("Peer is Connecting...");
1192                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1193                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1194                                                      "Connection",
1195                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
1196                                                                             WFD_EVENT_CONNECTION_RSP,
1197                                                                             peer_mac_address));
1198                 } else {
1199                         WDS_LOGE("Unexpected Peer State. Ignore it");
1200                         __WDS_LOG_FUNC_EXIT__;
1201                         return;
1202                 }
1203         } else {
1204                 WDS_LOGE("Unexpected event. Ignore it");
1205                 __WDS_LOG_FUNC_EXIT__;
1206                 return;
1207         }
1208
1209         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1210                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1211                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1212         } else {
1213                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1214                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1215         }
1216
1217         /* If there is no member, GO should be destroyed */
1218         if (!group->member_count) {
1219                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1220                 wfd_destroy_group(manager, group->ifname);
1221                 wfd_peer_clear_all(manager);
1222         }
1223
1224         wfd_destroy_session(manager);
1225
1226         __WDS_LOG_FUNC_EXIT__;
1227         return;
1228 }
1229
1230 static void __wfd_process_terminating(wfd_manager_s *manager, wfd_oem_event_s *event)
1231 {
1232         __WDS_LOG_FUNC_ENTER__;
1233
1234         __WDS_LOG_FUNC_EXIT__;
1235         return;
1236 }
1237
1238 static void __wfd_process_group_formation_failure(wfd_manager_s *manager, wfd_oem_event_s *event)
1239 {
1240         __WDS_LOG_FUNC_ENTER__;
1241
1242         wfd_session_s *session = (wfd_session_s*) manager->session;
1243         if (!session) {
1244                 WDS_LOGE("Unexpected event. Session not exist");
1245                 __WDS_LOG_FUNC_EXIT__;
1246                 return;
1247         }
1248
1249         unsigned char *peer_addr = wfd_session_get_peer_addr(session);
1250         if (!peer_addr) {
1251                 WDS_LOGE("Session do not has peer");
1252                 __WDS_LOG_FUNC_EXIT__;
1253                 return;
1254         }
1255
1256         char peer_mac_address[MACSTR_LEN+1] = {0, };
1257         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1258         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1259                                      "Connection",
1260                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
1261                                                             WFD_EVENT_CONNECTION_RSP,
1262                                                             peer_mac_address));
1263
1264         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1265         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1266         wfd_destroy_session(manager);
1267         manager->local->dev_role = WFD_DEV_ROLE_NONE;
1268
1269         wfd_oem_refresh(manager->oem_ops);
1270
1271         __WDS_LOG_FUNC_EXIT__;
1272         return;
1273 }
1274
1275 /**
1276  * This event is generated by supplicant when persitent invite is auto accepted
1277  * so that wfd-manager can get indication that a peer will be connected in near future.
1278  * session is started for that peer, so that it is not ignored when connected.
1279  */
1280 static void __wfd_process_invitation_accepted(wfd_manager_s *manager, wfd_oem_event_s *event)
1281 {
1282
1283         __WDS_LOG_FUNC_ENTER__;
1284
1285         wfd_session_s *session = (wfd_session_s*) manager->session;
1286         wfd_device_s *peer = NULL;
1287         char peer_mac_address[MACSTR_LEN+1] = {0, };
1288
1289         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
1290         if (!peer) {
1291                 WDS_LOGI("Invitation from unknown peer. Add new peer");
1292                 peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
1293                 if (!peer) {
1294                         WDS_LOGE("Failed to add peer for invitation");
1295                         __WDS_LOG_FUNC_EXIT__;
1296                         return;
1297                 }
1298         }
1299         /**By default, peer device information is complete but there's some exception
1300         * if DEV-FOUND event was not preceding before connection start event.
1301         */
1302         wfd_update_peer(manager, peer);
1303         peer->dev_role = WFD_DEV_ROLE_GO;
1304
1305         if (!session) {
1306                 session = wfd_create_session(manager, event->dev_addr,
1307                                         event->wps_mode, SESSION_DIRECTION_INCOMING);
1308                 if (!session) {
1309                         WDS_LOGE("Failed to create session with peer [" MACSTR "]",
1310                                                         MAC2STR(event->dev_addr));
1311                         __WDS_LOG_FUNC_EXIT__;
1312                         return;
1313                 }
1314         }
1315
1316         session->state = SESSION_STATE_WPS;
1317         wfd_session_timer(session, 1);
1318
1319         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1320         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1321                                          "Connection",
1322                                          g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1323                                                                 WFD_EVENT_CONNECTION_IN_PROGRESS,
1324                                                                 peer_mac_address));
1325
1326         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
1327         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
1328
1329         __WDS_LOG_FUNC_EXIT__;
1330 }
1331
1332 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1333 static void __wfd_process_serv_disc_resp(wfd_manager_s *manager, wfd_oem_event_s *event)
1334 {
1335         __WDS_LOG_FUNC_ENTER__;
1336         int service_type;
1337         char response_data[256] = {0, };
1338         char peer_mac_address[MACSTR_LEN+1] = {0, };
1339
1340         wfd_update_peer_time(manager, event->dev_addr);
1341
1342         if (event->edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE) {
1343                 wfd_oem_new_service_s *service = NULL;;
1344                 GList *temp = NULL;
1345                 GList *services = (GList*) event->edata;
1346                 int count = 0;
1347
1348                 WDS_LOGD("%d service data found", event->dev_role);
1349
1350                 temp = g_list_first(services);
1351                 while (temp && count < event->dev_role) {
1352                         service = (wfd_oem_new_service_s*) temp->data;
1353                         service_type = service->protocol;
1354                         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
1355                                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1356                                 g_snprintf(response_data, 256, "%s|%s", service->data.bonjour.query, service->data.bonjour.rdata);
1357                                 WDS_LOGD("Found service: [%d: %s] - [" MACSECSTR "]", service->protocol,
1358                                                         service->data.bonjour.query, MAC2SECSTR(event->dev_addr));
1359                         } else {
1360                                 WDS_LOGD("Found service is not supported");
1361                                 goto next;
1362                         }
1363
1364                         wfd_manager_dbus_emit_signal(WFD_MANAGER_SERVICE_INTERFACE,
1365                                                      "DiscoveryFound",
1366                                                      g_variant_new("(iss)", service_type,
1367                                                                             response_data,
1368                                                                             peer_mac_address));
1369 next:
1370                         temp = g_list_next(temp);
1371                         service = NULL;
1372                         count++;
1373                 }
1374         } else if (event->edata_type == WFD_OEM_EDATA_TYPE_SERVICE) {
1375                 wfd_oem_service_data_s *edata = (wfd_oem_service_data_s*) event->edata;
1376
1377                 if (!edata) {
1378                         service_type = -1;
1379                 } else {
1380                         service_type = edata->type;
1381                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1382                         switch (edata->type) {
1383                                 WDS_LOGE("Unknown type [type ID: %d]", edata->type);
1384                         }
1385                 }
1386
1387                 wfd_manager_dbus_emit_signal(WFD_MANAGER_SERVICE_INTERFACE,
1388                                              "DiscoveryFound",
1389                                              g_variant_new("(iss)", service_type,
1390                                                                     response_data,
1391                                                                     peer_mac_address));
1392         }
1393
1394         __WDS_LOG_FUNC_EXIT__;
1395         return;
1396 }
1397
1398 static void __wfd_process_serv_disc_started(wfd_manager_s *manager, wfd_oem_event_s *event)
1399 {
1400         __WDS_LOG_FUNC_ENTER__;
1401
1402         __WDS_LOG_FUNC_EXIT__;
1403         return;
1404 }
1405 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1406
1407
1408 #if defined(TIZEN_FEATURE_ASP)
1409 static void __wfd_process_asp_serv_resp(wfd_manager_s *manager, wfd_oem_event_s *event)
1410 {
1411         __WDS_LOG_FUNC_ENTER__;
1412
1413         wfd_oem_asp_service_s *service = NULL;
1414         GVariantBuilder *builder = NULL;
1415         GVariant *params = NULL;
1416
1417         service = (wfd_oem_asp_service_s *)event->edata;
1418         if (service == NULL) {
1419                 WDS_LOGE("P2P service found event has NULL information");
1420                 __WDS_LOG_FUNC_EXIT__;
1421                 return;
1422         }
1423
1424         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1425         g_variant_builder_add(builder, "{sv}", "search_id", g_variant_new("u", service->search_id));
1426         g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", event->dev_addr));
1427         g_variant_builder_add(builder, "{sv}", "advertisement_id", g_variant_new("u", service->adv_id));
1428         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", service->config_method));
1429         if (service->service_type)
1430                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
1431         if (service->service_info)
1432                 g_variant_builder_add(builder, "{sv}", "service_info", g_variant_new("s", service->service_info));
1433         g_variant_builder_add(builder, "{sv}", "status", g_variant_new("y", service->status));
1434         params = g_variant_new("(a{sv})", builder);
1435         g_variant_builder_unref(builder);
1436
1437         wfd_manager_dbus_emit_signal(WFD_MANAGER_ASP_INTERFACE,
1438                                      "SearchResult",
1439                                      params);
1440
1441         __WDS_LOG_FUNC_EXIT__;
1442         return;
1443 }
1444
1445 static void __wfd_process_asp_prov_start(wfd_manager_s *manager, wfd_oem_event_s *event)
1446 {
1447         __WDS_LOG_FUNC_ENTER__;
1448
1449         __WDS_LOG_FUNC_EXIT__;
1450         return;
1451 }
1452
1453 static void __wfd_process_asp_prov_done(wfd_manager_s *manager, wfd_oem_event_s *event)
1454 {
1455         __WDS_LOG_FUNC_ENTER__;
1456
1457         __WDS_LOG_FUNC_EXIT__;
1458         return;
1459 }
1460 #endif /* TIZEN_FEATURE_ASP */
1461
1462 static struct {
1463         const int event_id;
1464         void (*function) (wfd_manager_s *manager, wfd_oem_event_s *event);
1465 } wfd_oem_event_map[] = {
1466         {
1467                 WFD_OEM_EVENT_NONE,
1468                 NULL
1469         },
1470         {
1471                 WFD_OEM_EVENT_DEACTIVATED,
1472                 __wfd_process_deactivated
1473         },
1474         {
1475                 WFD_OEM_EVENT_PEER_FOUND,
1476                 __wfd_process_peer_found
1477         },
1478         {
1479                 WFD_OEM_EVENT_PEER_DISAPPEARED,
1480                 __wfd_process_peer_disappeared
1481         },
1482         {
1483                 WFD_OEM_EVENT_DISCOVERY_FINISHED,
1484                 __wfd_process_discovery_finished
1485         },
1486         {
1487                 WFD_OEM_EVENT_PROV_DISC_REQ,
1488                 __wfd_process_prov_disc_req
1489         },
1490         {
1491                 WFD_OEM_EVENT_PROV_DISC_RESP,
1492                 __wfd_process_prov_disc_resp
1493         },
1494         {
1495                 WFD_OEM_EVENT_PROV_DISC_FAIL,
1496                 __wfd_process_prov_disc_fail
1497         },
1498         {
1499                 WFD_OEM_EVENT_GO_NEG_REQ,
1500                 __wfd_process_go_neg_req
1501         },
1502         {
1503                 WFD_OEM_EVENT_GO_NEG_FAIL,
1504                 __wfd_process_go_neg_fail
1505         },
1506         {
1507                 WFD_OEM_EVENT_GO_NEG_DONE,
1508                 __wfd_process_go_neg_done
1509         },
1510         {
1511                 WFD_OEM_EVENT_WPS_FAIL,
1512                 __wfd_process_wps_fail
1513         },
1514         {
1515                 WFD_OEM_EVENT_WPS_DONE,
1516                 __wfd_process_wps_done
1517         },
1518         {
1519                 WFD_OEM_EVENT_KEY_NEG_FAIL,
1520                 __wfd_process_key_neg_fail
1521         },
1522         {
1523                 WFD_OEM_EVENT_KEY_NEG_DONE,
1524                 __wfd_process_key_neg_done
1525         },
1526         {
1527                 WFD_OEM_EVENT_CONN_FAIL,
1528                 __wfd_process_conn_fail
1529         },
1530         {
1531                 WFD_OEM_EVENT_CONN_DONE,
1532                 __wfd_process_conn_done
1533         },
1534         {
1535                 WFD_OEM_EVENT_GROUP_CREATED,
1536                 __wfd_process_group_created
1537         },
1538         {
1539                 WFD_OEM_EVENT_GROUP_DESTROYED,
1540                 __wfd_process_group_destroyed
1541         },
1542         {
1543                 WFD_OEM_EVENT_INVITATION_REQ,
1544                 __wfd_process_invitation_req
1545         },
1546         {
1547                 WFD_OEM_EVENT_INVITATION_RES,
1548                 __wfd_process_invitation_res
1549         },
1550         {
1551                 WFD_OEM_EVENT_STA_CONNECTED,
1552                 __wfd_process_sta_connected
1553         },
1554         {
1555                 WFD_OEM_EVENT_STA_DISCONNECTED,
1556                 __wfd_process_sta_disconnected
1557         },
1558         {
1559                 WFD_OEM_EVENT_TERMINATING,
1560                 __wfd_process_terminating
1561         },
1562
1563 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1564         {
1565                 WFD_OEM_EVENT_SERV_DISC_RESP,
1566                 __wfd_process_serv_disc_resp
1567         },
1568         {
1569                 WFD_OEM_EVENT_SERV_DISC_STARTED,
1570                 __wfd_process_serv_disc_started
1571         },
1572 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1573         {
1574                 WFD_OEM_EVENT_GROUP_FORMATION_FAILURE,
1575                 __wfd_process_group_formation_failure
1576         },
1577         {
1578                 WFD_OEM_EVENT_INVITATION_ACCEPTED,
1579                 __wfd_process_invitation_accepted
1580         },
1581 #if defined(TIZEN_FEATURE_ASP)
1582         {
1583                 WFD_OEM_EVENT_ASP_SERV_RESP,
1584                 __wfd_process_asp_serv_resp,
1585         },
1586         {
1587                 WFD_OEM_EVENT_ASP_PROV_START,
1588                 __wfd_process_asp_prov_start
1589         },
1590         {
1591                 WFD_OEM_EVENT_ASP_PROV_DONE,
1592                 __wfd_process_asp_prov_done
1593         },
1594 #endif /* TIZEN_FEATURE_ASP */
1595         {
1596                 WFD_OEM_EVENT_MAX,
1597                 NULL
1598         }
1599 };
1600
1601 int wfd_process_event(void *user_data, void *data)
1602 {
1603         __WDS_LOG_FUNC_ENTER__;
1604         wfd_manager_s *manager = NULL;
1605         wfd_oem_event_s *event = NULL;
1606
1607         manager = (wfd_manager_s*) user_data;
1608         event = (wfd_oem_event_s*) data;
1609         if (!manager || !event) {
1610                 WDS_LOGE("Invalid parameter");
1611                 __WDS_LOG_FUNC_EXIT__;
1612                 return -1;
1613         }
1614
1615         WDS_LOGD("Event[%d] from " MACSECSTR, event->event_id,
1616                                                 MAC2SECSTR(event->dev_addr));
1617
1618         if (event->event_id > WFD_OEM_EVENT_NONE &&
1619                         event->event_id < WFD_OEM_EVENT_MAX)
1620                  wfd_oem_event_map[event->event_id].function(manager, event);
1621         else
1622                 WDS_LOGE("Invalid event ID");
1623
1624         __WDS_LOG_FUNC_EXIT__;
1625         return 0;
1626 }