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