[wifi-direct-manager]Merge Tizen 2.4 for sync
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-event.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /**
21  * This file implements wifi direct event functions.
22  *
23  * @file                wifi-direct-event.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <poll.h>
31 #include <unistd.h>
32 #include <time.h>
33 #include <errno.h>
34
35 #include <glib.h>
36
37 #include <wifi-direct.h>
38
39 #include "wifi-direct-ipc.h"
40 #include "wifi-direct-manager.h"
41 #include "wifi-direct-oem.h"
42 #include "wifi-direct-peer.h"
43 #include "wifi-direct-group.h"
44 #include "wifi-direct-session.h"
45 #include "wifi-direct-event.h"
46 #include "wifi-direct-client.h"
47 #include "wifi-direct-state.h"
48 #include "wifi-direct-util.h"
49
50
51 static int _wfd_event_update_peer(wfd_manager_s *manager, wfd_oem_dev_data_s *data)
52 {
53         __WDS_LOG_FUNC_ENTER__;
54         wfd_device_s *peer = NULL;
55
56         if (!manager || !data) {
57                 WDS_LOGE("Invalid parameter");
58                 return -1;
59         }
60
61         peer = wfd_peer_find_by_dev_addr(manager, data->p2p_dev_addr);
62         if (!peer) {
63                 peer = wfd_add_peer(manager, data->p2p_dev_addr, data->name);
64                 if (!peer) {
65                         WDS_LOGE("Failed to add peer");
66                         return -1;
67                 }
68         } else {
69                 if (strcmp(peer->dev_name, data->name)) {
70                         g_strlcpy(peer->dev_name, data->name, DEV_NAME_LEN + 1);
71                         WDS_LOGD("Device name is changed [" MACSECSTR ": %s]",
72                                         MAC2SECSTR(peer->dev_addr), peer->dev_name);
73                 }
74         }
75 #ifndef CTRL_IFACE_DBUS
76         memcpy(peer->intf_addr, data->p2p_intf_addr, MACADDR_LEN);
77 #endif /* CTRL_IFACE_DBUS */
78         peer->pri_dev_type = data->pri_dev_type;
79         peer->sec_dev_type = data->sec_dev_type;
80         peer->config_methods = data->config_methods;
81         peer->dev_flags = data->dev_flags;
82         peer->group_flags = data->group_flags;
83         peer->dev_role = data->dev_role;
84 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
85         memcpy(&(peer->display), &(data->display), sizeof(wfd_display_s));
86 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
87
88 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
89         wfd_util_get_current_time(&peer->time);
90 #else
91         struct timeval tval;
92         gettimeofday(&tval, NULL);
93         peer->time = tval.tv_sec;
94 #endif
95         WDS_LOGI("Update time [%s - %ld]", peer->dev_name, peer->time);
96
97         __WDS_LOG_FUNC_EXIT__;
98         return 0;
99 }
100
101  gboolean _wfd_connection_retry(gpointer *data)
102 {
103         wfd_session_s *session = (wfd_session_s*) data;
104         if (!session) {
105                 WDS_LOGE("Session is NULL");
106                 return G_SOURCE_REMOVE;
107         }
108
109         switch (session->state) {
110                 case SESSION_STATE_STARTED:
111                         WDS_LOGD("PD again");
112                         wfd_session_start(session);
113                         break;
114                 case SESSION_STATE_GO_NEG:
115                         WDS_LOGD("Negotiation again");
116                         wfd_session_connect(session);
117                         break;
118                 case SESSION_STATE_WPS:
119                         WDS_LOGD("WPS again");
120                         wfd_session_wps(session);
121                         break;
122                 default:
123                         WDS_LOGE("Invalid session state [%d]", session->state);
124                         break;
125         }
126
127         return G_SOURCE_REMOVE;
128 }
129
130 int wfd_process_event(void *user_data, void *data)
131 {
132         __WDS_LOG_FUNC_ENTER__;
133         wfd_manager_s *manager = (wfd_manager_s*) user_data;
134         wfd_oem_event_s *event = (wfd_oem_event_s*) data;
135         int res = 0;
136
137         if (!manager || !event) {
138                 WDS_LOGE("Invalid parameter");
139                 return -1;
140         }
141
142         WDS_LOGD("Event[%d] from " MACSECSTR, event->event_id, MAC2SECSTR(event->dev_addr));
143
144         switch (event->event_id) {
145         case WFD_OEM_EVENT_DEACTIVATED:
146         {
147                 // TODO: notify app
148                 wifi_direct_client_noti_s noti;
149                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
150                 noti.event = WIFI_DIRECT_CLI_EVENT_DEACTIVATION;
151                 noti.error = WIFI_DIRECT_ERROR_NONE;
152                 wfd_client_send_event(manager, &noti);
153
154                 // TODO: remove group, session, all peers
155                 wfd_destroy_group(manager, GROUP_IFNAME);
156                 wfd_destroy_session(manager);
157                 wfd_peer_clear_all(manager);
158                 wfd_local_reset_data(manager);
159
160                 wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
161                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
162                 manager->req_wps_mode = WFD_WPS_MODE_PBC;
163         }
164         break;
165         case WFD_OEM_EVENT_PEER_FOUND:
166         {
167                 wfd_oem_dev_data_s *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                         break;
171                 }
172
173                 res = _wfd_event_update_peer(manager, edata);
174                 if (res < 0) {
175                         WDS_LOGE("Failed to update peer data");
176                         break;
177                 }
178
179                 if (manager->state > WIFI_DIRECT_STATE_ACTIVATING &&
180                                 manager->state != WIFI_DIRECT_STATE_CONNECTING &&
181                                 manager->state != WIFI_DIRECT_STATE_DISCONNECTING) {
182                         wifi_direct_client_noti_s noti;
183                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
184                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(edata->p2p_dev_addr));
185                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_FOUND_PEERS;
186                         noti.error = WIFI_DIRECT_ERROR_NONE;
187                         wfd_client_send_event(manager, &noti);
188                 }
189         }
190         break;
191         case WFD_OEM_EVENT_PROV_DISC_REQ:
192         case WFD_OEM_EVENT_PROV_DISC_RESP:
193         {
194                 wfd_device_s *peer = NULL;
195 #ifdef CTRL_IFACE_DBUS
196                 wfd_oem_dev_data_s *edata = (wfd_oem_dev_data_s*) event->edata;
197                 if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
198                         WDS_LOGE("Invalid event data");
199                         break;
200                 }
201
202                 res = _wfd_event_update_peer(manager, edata);
203                 peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
204                 peer->state = WFD_PEER_STATE_CONNECTING;
205 #else /* CTRL_IFACE_DBUS */
206                 peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
207                 if (!peer) {
208                         WDS_LOGD("Porv_disc from unknown peer. Add new peer");
209                         peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
210                         if (!peer) {
211                                 WDS_LOGE("Failed to add peer for invitation");
212                                 return -1;
213                         }
214                         peer->state = WFD_PEER_STATE_CONNECTING;
215                         wfd_update_peer(manager, peer);
216                 }
217                 wfd_update_peer_time(manager, event->dev_addr);
218 #endif /* CTRL_IFACE_DBUS */
219                 res = wfd_session_process_event(manager, event);
220                 if (res < 0) {
221                         WDS_LOGE("Failed to process event of session");
222                         break;
223                 }
224         }
225         break;
226         case WFD_OEM_EVENT_PEER_DISAPPEARED:
227         {
228                 wfd_remove_peer(manager, event->dev_addr);
229                 wifi_direct_client_noti_s noti;
230                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
231                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_FOUND_PEERS;
232                 noti.error = WIFI_DIRECT_ERROR_NONE;
233                 wfd_client_send_event(manager, &noti);
234         }
235         break;
236         case WFD_OEM_EVENT_DISCOVERY_FINISHED:
237         {
238                 if (manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
239                                 manager->state != WIFI_DIRECT_STATE_ACTIVATED) {
240                         WDS_LOGE("Notify finding stoped when discovering or activated. [%d]", manager->state);
241                         break;
242                 }
243
244                 if (manager->scan_mode == WFD_SCAN_MODE_PASSIVE) {
245                         WDS_LOGE("During passive scan, Discover Finished event will not notified");
246                         break;
247                 }
248
249                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
250                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
251                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
252                 } else {
253                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
254                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
255                 }
256                 manager->scan_mode = WFD_SCAN_MODE_NONE;
257
258                 wifi_direct_client_noti_s noti;
259                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
260                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_END;
261                 noti.error = WIFI_DIRECT_ERROR_NONE;
262                 wfd_client_send_event(manager, &noti);
263         }
264         break;
265         case WFD_OEM_EVENT_INVITATION_REQ:
266         {
267                 wfd_device_s *peer = NULL;
268                 wfd_session_s *session = NULL;
269                 wfd_oem_invite_data_s *edata = (wfd_oem_invite_data_s*) event->edata;
270
271                 peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
272                 if (!peer) {
273                         WDS_LOGD("Invitation from unknown peer. Add new peer");
274                         peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
275                         if (!peer) {
276                                 WDS_LOGE("Failed to add peer for invitation");
277                                 return -1;
278                         }
279                 }
280                 peer->dev_role = WFD_DEV_ROLE_GO;
281                 memcpy(peer->intf_addr, edata->bssid, MACADDR_LEN);
282                 wfd_update_peer_time(manager, event->dev_addr);
283
284                 session = wfd_create_session(manager, event->dev_addr,
285                                                 manager->req_wps_mode, SESSION_DIRECTION_INCOMING);
286                 if (!session) {
287                         WDS_LOGE("Failed to create session");
288                         return -1;
289                 }
290                 session->type = SESSION_TYPE_INVITE;
291                 wfd_session_timer(session, 1);
292
293                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
294
295                 wifi_direct_client_noti_s noti;
296                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
297                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
298                 noti.error = WIFI_DIRECT_ERROR_NONE;
299                 snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
300                 wfd_client_send_event(manager, &noti);
301         }
302         break;
303         case WFD_OEM_EVENT_GO_NEG_REQ:
304         {
305                 wfd_session_s *session = (wfd_session_s*) manager->session;
306 #ifdef CTRL_IFACE_DBUS
307                 wfd_oem_dev_data_s *edata = (wfd_oem_dev_data_s*) event->edata;
308                 if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
309                         WDS_LOGE("Invalid event data");
310                         break;
311                 }
312
313                 res = _wfd_event_update_peer(manager, edata);
314                 if (res < 0) {
315                         WDS_LOGE("Failed to update peer data");
316                         break;
317                 }
318 #else /* CTRL_IFACE_DBUS */
319                 wfd_device_s *peer = NULL;
320                 wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
321
322                 if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_CONN) {
323                         WDS_LOGE("Invalid connection event data");
324                         break;
325                 }
326
327                 peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
328                 if (!peer) {
329                         WDS_LOGD("Invitation from unknown peer. Add new peer");
330                         peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
331                         if (!peer) {
332                                 WDS_LOGE("Failed to add peer for invitation");
333                                 break;
334                         }
335                 }
336
337                 if (edata->wps_mode == 0)
338                         edata->wps_mode = 1;
339 #endif /* CTRL_IFACE_DBUS */
340                 if (!session) {
341                         session = wfd_create_session(manager, event->dev_addr,
342 #ifdef CTRL_IFACE_DBUS
343                                                         event->wps_mode, SESSION_DIRECTION_INCOMING);
344 #else /* CTRL_IFACE_DBUS */
345                                                         edata->wps_mode, SESSION_DIRECTION_INCOMING);
346 #endif /* CTRL_IFACE_DBUS */
347                         if (!session) {
348                                 WDS_LOGE("Failed to create session");
349                                 return -1;
350                         }
351                         session->type = SESSION_TYPE_NORMAL;
352                         session->state = SESSION_STATE_GO_NEG;
353                         wfd_session_timer(session, 1);
354                         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
355
356                         wifi_direct_client_noti_s noti;
357                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
358                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ;
359                         noti.error = WIFI_DIRECT_ERROR_NONE;
360                         g_snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
361                         wfd_client_send_event(manager, &noti);
362                 } else {
363                         wfd_session_process_event(manager, event);
364                 }
365         }
366         break;
367         case WFD_OEM_EVENT_GO_NEG_DONE:
368 #ifdef CTRL_IFACE_DBUS
369         {
370                 wfd_session_s *session = (wfd_session_s*) manager->session;
371                 wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
372                 wfd_device_s *peer = NULL;
373
374                 if (event == NULL || edata == NULL) {
375                         WDS_LOGE("Invalid event data");
376                         break;
377                 }
378
379                 if(session && session->peer) {
380                         peer = session->peer;
381                         memcpy(peer->intf_addr, edata->peer_intf_addr, MACADDR_LEN);
382                 }
383                 manager->local->dev_role = event->dev_role;
384                 wfd_session_process_event(manager, event);
385         }
386         break;
387 #endif /* CTRL_IFACE_DBUS */
388         case WFD_OEM_EVENT_WPS_DONE:
389                 wfd_session_process_event(manager, event);
390         break;
391         case WFD_OEM_EVENT_CONNECTED:
392         case WFD_OEM_EVENT_STA_CONNECTED:
393         {
394                 // FIXME: Move this code to plugin
395                 if (!memcmp(event->intf_addr, manager->local->intf_addr, MACADDR_LEN)) {
396                         WDS_LOGD("Ignore this event");
397                         break;
398                 }
399
400                 wfd_session_s *session = (wfd_session_s*) manager->session;
401                 if (!session) {
402                         WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
403                                                                                 MAC2SECSTR(event->dev_addr));
404                         wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
405                         wfd_destroy_group(manager, GROUP_IFNAME);
406                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
407                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
408                         break;
409                 }
410
411                 wfd_device_s *peer = wfd_session_get_peer(session);
412                 if (!peer) {
413                         WDS_LOGE("Peer not found");
414                         break;
415                 }
416
417                 wfd_group_s *group = (wfd_group_s*) manager->group;
418                 if (!group) {
419                         group = wfd_create_pending_group(manager, event->intf_addr);
420                         if (!group) {
421                                 WDS_LOGE("Failed to create pending group");
422                                 break;
423                         }
424                         manager->group = group;
425                 }
426                 wfd_group_add_member(group, peer->dev_addr);
427
428                 session->state = SESSION_STATE_COMPLETED;
429 #ifndef CTRL_IFACE_DBUS
430                 memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
431 #endif /* CTRL_IFACE_DBUS */
432                 peer->state = WFD_PEER_STATE_CONNECTED;
433
434                 if (event->event_id == WFD_OEM_EVENT_STA_CONNECTED) {   // GO
435                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
436                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
437
438                         wifi_direct_client_noti_s noti;
439                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
440                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
441                         noti.error = WIFI_DIRECT_ERROR_NONE;
442                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
443                         wfd_client_send_event(manager, &noti);
444 #ifdef CTRL_IFACE_DBUS
445                         wfd_update_peer(manager, peer);
446 #endif /* CTRL_IFACE_DBUS */
447
448                         wfd_util_dhcps_wait_ip_leased(peer);
449                         wfd_destroy_session(manager);
450                 }
451         }
452         break;
453         case WFD_OEM_EVENT_DISCONNECTED:
454         case WFD_OEM_EVENT_STA_DISCONNECTED:
455         {
456                 wfd_group_s *group = (wfd_group_s*) manager->group;
457                 wfd_session_s *session = (wfd_session_s*) manager->session;
458                 wfd_device_s *peer = NULL;
459                 unsigned char peer_addr[MACADDR_LEN] = {0, };
460                 wifi_direct_client_noti_s noti;
461                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
462
463                 if (!group) {
464                         WDS_LOGE("Group not found");
465                         break;
466                 }
467
468 #ifdef CTRL_IFACE_DBUS
469                 peer = wfd_group_find_member_by_addr(group, event->dev_addr);
470 #else /* CTRL_IFACE_DBUS */
471                 peer = wfd_group_find_member_by_addr(group, event->intf_addr);
472 #endif /* DBUS_IFACE */
473                 if (!peer) {
474                         WDS_LOGE("Failed to find connected peer");
475                         peer = wfd_session_get_peer(session);
476                         if (!peer) {
477                                 WDS_LOGE("Failed to find connecting peer");
478                                 break;
479                         }
480                 }
481                 memcpy(peer_addr, peer->dev_addr, MACADDR_LEN);
482
483                 /* If state is not DISCONNECTING, connection is finished by peer */
484                 if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
485                         wfd_group_remove_member(group, peer_addr);
486                         if (group->member_count)
487                                 noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
488                         else
489                                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_IND;
490                         noti.error = WIFI_DIRECT_ERROR_NONE;
491                         g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
492                         /* If there is no member, GO should be destroyed */
493                         if (!group->member_count) {
494                                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
495                                 wfd_destroy_group(manager, group->ifname);
496                         }
497                 } else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
498                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
499                         noti.error = WIFI_DIRECT_ERROR_NONE;
500                         g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
501                 } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
502                                 /* Some devices(GO) send disconnection message before connection completed.
503                                  * This message should be ignored when device is not GO */
504                                 manager->local->dev_role == WFD_DEV_ROLE_GO) {
505                         if (WFD_PEER_STATE_CONNECTED == peer->state) {
506                                 WDS_LOGD("Peer is already Connected !!!");
507                                 noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
508                                 noti.error = WIFI_DIRECT_ERROR_NONE;
509                         } else if (WFD_PEER_STATE_CONNECTING == peer->state) {
510                                 WDS_LOGD("Peer is Connecting...");
511                                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
512                                 noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
513                         } else {
514                                 WDS_LOGE("Unexpected Peer State. Ignore it");
515                                 break;
516                         }
517                         g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
518                 } else {
519                         WDS_LOGE("Unexpected event. Ignore it");
520                         break;
521                 }
522                 wfd_client_send_event(manager, &noti);
523
524                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
525                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
526                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
527                 } else {
528                         wfd_destroy_group(manager, GROUP_IFNAME);
529                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
530                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
531                 }
532                 wfd_destroy_session(manager);
533         }
534         break;
535         case WFD_OEM_EVENT_GROUP_CREATED:
536         {
537                 wfd_group_s *group = (wfd_group_s*) manager->group;
538 #ifdef CTRL_IFACE_DBUS
539                 if(event->dev_role == WFD_DEV_ROLE_GC && !group) {
540
541                         group = wfd_create_pending_group(manager, event->intf_addr);
542                         if (!group) {
543                                 WDS_LOGE("Failed to create pending group");
544                                 break;
545                         }
546                         manager->group = group;
547                 }
548 #endif /* CTRL_IFACE_DBUS */
549
550                 if (!group) {
551                         if (!manager->session) {
552                                 WDS_LOGE("Unexpected Event. Group should be removed(Client)");
553                                 wfd_oem_destroy_group(manager->oem_ops, event->ifname);
554                                 break;
555                         }
556
557                         group = wfd_create_group(manager, event);
558                         if (!group) {
559                                 WDS_LOGE("Failed to create group");
560                                 break;
561                         }
562                 } else {
563                         if (!manager->session && !(group->flags & WFD_GROUP_FLAG_AUTONOMOUS)) {
564                                 WDS_LOGE("Unexpected Event. Group should be removed(Owner)");
565                                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
566                                 break;
567                         }
568
569                         if (group->pending) {
570                                 wfd_group_complete(manager, event);
571                         } else {
572                                 WDS_LOGE("Unexpected event. Group already exist");
573                                 break;
574                         }
575                 }
576
577                 wifi_direct_client_noti_s noti;
578                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
579                 if (group->role == WFD_DEV_ROLE_GC) {
580 #ifndef CTRL_IFACE_DBUS
581                         wfd_destroy_session(manager);
582 #endif /* CTRL_IFACE_DBUS */
583                         wfd_peer_clear_all(manager);
584                 } else {
585                         if (group->flags & WFD_GROUP_FLAG_AUTONOMOUS) {
586                                 noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_CREATE_RSP;
587                                 wfd_client_send_event(manager, &noti);
588                                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
589                                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
590                         }
591                 }
592         }
593         break;
594         case WFD_OEM_EVENT_GROUP_DESTROYED:
595         {
596                 wifi_direct_client_noti_s noti;
597                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
598                 if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
599                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
600                         noti.error = WIFI_DIRECT_ERROR_NONE;
601                 } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING && manager->session){
602                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
603                         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
604                         unsigned char *peer_addr = wfd_session_get_peer_addr(manager->session);
605                         if(peer_addr != NULL)
606                                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
607                 } else if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
608                         noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_DESTROY_RSP;
609                         noti.error = WIFI_DIRECT_ERROR_NONE;
610                 } else {
611                         WDS_LOGD("Unexpected event(GROUP_DESTROYED). Ignore it");
612                         break;
613                 }
614                 wfd_client_send_event(manager, &noti);
615
616                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
617                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
618                 wfd_destroy_group(manager, event->ifname);
619                 wfd_destroy_session(manager);
620                 manager->local->dev_role = WFD_DEV_ROLE_NONE;
621         }
622         break;
623         case WFD_OEM_EVENT_GO_NEG_FAIL:
624         {
625                 wfd_session_s *session = (wfd_session_s*) manager->session;
626                 if (!session) {
627                         WDS_LOGE("Unexpected event. Session not exist");
628                         break;
629                 }
630
631                 unsigned char *peer_addr = wfd_session_get_peer_addr(session);
632                 if (!peer_addr) {
633                         WDS_LOGE("Session do not has peer");
634                         break;
635                 }
636
637                 if (event->event_id == WFD_OEM_EVENT_GO_NEG_FAIL) {
638                         wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
639                         if (edata && edata->status < 0 && session->connecting_120) {
640                                 if (session->retry_gsrc) {
641                                         g_source_remove(session->retry_gsrc);
642                                         session->retry_gsrc = 0;
643                                 }
644                                 session->retry_gsrc = g_idle_add((GSourceFunc) _wfd_connection_retry, session);
645                                 WDS_LOGD("Connection will be retried");
646                                 break;
647                         }
648                 }
649
650                 wifi_direct_client_noti_s noti;
651                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
652                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
653                 noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
654                 snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
655                 wfd_client_send_event(manager, &noti);
656
657                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
658                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
659                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
660                 } else {
661                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
662                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
663                 }
664
665                 wfd_destroy_session(manager);
666         }
667         break;
668         case WFD_OEM_EVENT_PROV_DISC_FAIL:
669         case WFD_OEM_EVENT_WPS_FAIL:
670         case WFD_OEM_EVENT_KEY_NEG_FAIL:
671         {
672                 wfd_session_s *session = (wfd_session_s*) manager->session;
673                 if (!session) {
674                         WDS_LOGE("Unexpected event. Session not exist");
675                         break;
676                 }
677
678                 unsigned char *peer_addr = wfd_session_get_peer_addr(session);
679                 if (!peer_addr) {
680                         WDS_LOGE("Session do not has peer");
681                         break;
682                 }
683
684                 if (event->event_id == WFD_OEM_EVENT_GO_NEG_FAIL) {
685                         wfd_oem_conn_data_s *edata = (wfd_oem_conn_data_s*) event->edata;
686                         if (edata && edata->status < 0 && session->connecting_120) {
687                                 if (session->retry_gsrc) {
688                                         g_source_remove(session->retry_gsrc);
689                                         session->retry_gsrc = 0;
690                                 }
691                                 session->retry_gsrc = g_idle_add((GSourceFunc) _wfd_connection_retry, session);
692                                 WDS_LOGD("Connection will be retried");
693                                 break;
694                         }
695                 }
696
697                 wifi_direct_client_noti_s noti;
698                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
699                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
700                 noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
701                 snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
702                 wfd_client_send_event(manager, &noti);
703
704                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
705                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
706                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
707                 } else {
708                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
709                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
710                 }
711
712                 wfd_destroy_session(manager);
713
714                 wfd_oem_refresh(manager->oem_ops);
715 #if 0
716                 /* After connection failed, scan again */
717                 wfd_oem_scan_param_s param;
718                 memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
719                 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
720                 param.scan_time = 2;
721                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
722                 wfd_oem_start_scan(manager->oem_ops, &param);
723                 manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
724 #endif
725         }
726         break;
727
728 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
729         case WFD_OEM_EVENT_SERV_DISC_RESP:
730         {
731                 wifi_direct_client_noti_s noti;
732                 wfd_update_peer_time(manager, event->dev_addr);
733
734                 if (event->edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE) {
735                         wfd_oem_new_service_s *service = NULL;;
736                         GList *temp = NULL;
737                         GList *services = (GList*) event->edata;
738                         int count = 0;
739
740                         WDS_LOGD("%d service data found", event->dev_role);
741
742                         temp = g_list_first(services);
743                         while(temp && count < event->dev_role) {
744                                 service = (wfd_oem_new_service_s*) temp->data;
745                                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
746                                 noti.event = WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FOUND;
747                                 noti.type = service->protocol;
748                                 if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
749                                         g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
750                                         g_snprintf(noti.param2, 256, "%s|%s", service->data.bonjour.query, service->data.bonjour.rdata);
751                                         WDS_LOGD("Found service: [%d: %s] - [" MACSECSTR "]", service->protocol,
752                                                                 service->data.bonjour.query, MAC2SECSTR(event->dev_addr));
753                                 } else if (service->protocol == WFD_OEM_SERVICE_TYPE_BT_ADDR) {
754                                         g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
755                                         g_snprintf(noti.param2, MACSTR_LEN, "%s", service->data.vendor.data2);
756                                         WDS_LOGD("Found service: [%d: %s] - [" MACSECSTR "]", service->protocol,
757                                                                 service->data.vendor.data2, MAC2SECSTR(event->dev_addr));
758                                 } else {
759                                         WDS_LOGD("Found service is not supported");
760                                         goto next;
761                                 }
762                                 wfd_client_send_event(manager, &noti);
763 next:
764                                 temp = g_list_next(temp);
765                                 service = NULL;
766                                 count++;
767                         }
768                 } else if (event->edata_type == WFD_OEM_EDATA_TYPE_SERVICE) {
769                         wfd_oem_service_data_s *edata = (wfd_oem_service_data_s*) event->edata;
770
771                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
772                         noti.event = WIFI_DIRECT_CLI_EVENT_SERVICE_DISCOVERY_FOUND;
773                         if(!edata) {
774                                 noti.type = -1;
775                         } else {
776                                 noti.type = edata->type;
777                                 g_snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
778                                 switch(edata->type) {
779                                         case WFD_OEM_SERVICE_TYPE_BT_ADDR:
780                                                 g_snprintf(noti.param2, MACSTR_LEN, MACSTR, MAC2STR(edata->data));
781                                                 break;
782                                         case WFD_OEM_SERVICE_TYPE_CONTACT_INFO:
783                                                 g_snprintf(noti.param2, MACSTR_LEN, "%s", edata->value);
784                                                 break;
785                                         default:
786                                                 WDS_LOGE("Unknown type [type ID: %d]", edata->type);
787                                 }
788                         }
789                         wfd_client_send_event(manager, &noti);
790                 }
791         }
792         break;
793 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
794
795         default:
796                 WDS_LOGE("Unknown event [event ID: %d]", event->event_id);
797         break;
798         }
799
800         __WDS_LOG_FUNC_EXIT__;
801         return 0;
802 }
803