* Modifiy Provision Discovery Request/Response Event
[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 <time.h>
32 #include <unistd.h>
33 #include <errno.h>
34
35 #include <glib.h>
36
37 #include <wifi-direct-internal.h>
38
39 #include "wifi-direct-manager.h"
40 #include "wifi-direct-oem.h"
41 #include "wifi-direct-peer.h"
42 #include "wifi-direct-group.h"
43 #include "wifi-direct-session.h"
44 #include "wifi-direct-event.h"
45 #include "wifi-direct-client.h"
46 #include "wifi-direct-state.h"
47 #include "wifi-direct-util.h"
48
49
50 static int _wfd_event_check_socket(int sock)
51 {
52         struct pollfd p_fd;
53         int res = 0;
54
55         p_fd.fd = sock;
56         p_fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP | POLLNVAL;
57         res = poll((struct pollfd *) &p_fd, 1, 1);
58
59         if (res < 0) {
60                 WDS_LOGE("Polling error from socket[%d]. [%s]", sock, strerror(errno));
61                 return -1;
62         } else if (res == 0) {
63                 WDS_LOGD( "poll timeout. socket is busy\n");
64                 return 1;
65         } else {
66
67                 if (p_fd.revents & POLLERR) {
68                         WDS_LOGE("Error! POLLERR from socket[%d]", sock);
69                         return -1;
70                 } else if (p_fd.revents & POLLHUP) {
71                         WDS_LOGE("Error! POLLHUP from socket[%d]", sock);
72                         return -1;
73                 } else if (p_fd.revents & POLLNVAL) {
74                         WDS_LOGE("Error! POLLNVAL from socket[%d]", sock);
75                         return -1;
76                 } else if (p_fd.revents & POLLIN) {
77                         WDS_LOGD("POLLIN from socket [%d]", sock);
78                         return 0;
79                 } else if (p_fd.revents & POLLOUT) {
80                         WDS_LOGD("POLLOUT from socket [%d]", sock);
81                         return 0;
82                 }
83         }
84
85         WDS_LOGD("Unknown poll event [%d]", p_fd.revents);
86         return -1;
87 }
88
89 static int _wfd_event_send_to_client(int sock, char *data, int data_len)
90 {
91         __WDS_LOG_FUNC_ENTER__;
92         int wbytes = 0;
93         int left_len = data_len;
94         char *ptr = data;
95         int res = 0;
96
97         if (sock < SOCK_FD_MIN || !data || data_len < 0) {
98                 WDS_LOGE("Invalid parameter");
99                 __WDS_LOG_FUNC_EXIT__;
100                 return -1;
101         }
102
103         res = _wfd_event_check_socket(sock);
104         if (res < 0) {
105                 WDS_LOGE("Socket error");
106                 return -1;
107         } else if (res > 0) {
108                 WDS_LOGE("Socket is busy");
109                 return -2;
110         }
111
112         errno = 0;
113         while (left_len) {
114                 wbytes = write(sock, ptr, left_len);
115                 if (wbytes <= 0) {
116                         WDS_LOGE("Failed to write data into socket[%d]. [%s]", sock, strerror(errno));
117                         break;
118                 }else if (wbytes < left_len) {
119                         WDS_LOGD("%d bytes left. Continue sending...", left_len - wbytes);
120                         left_len -= wbytes;
121                         ptr += wbytes;
122                 } else if (wbytes == left_len) {
123                         WDS_LOGD("Succeeded to write data[%d bytes] into socket [%d]", wbytes, sock);
124                         left_len = 0;
125                 } else {
126                         WDS_LOGE("Unknown error occurred. [%s]", strerror(errno));
127                         break;
128                 }
129         }
130
131         __WDS_LOG_FUNC_EXIT__;
132         if (left_len)
133                 return -1;
134         else
135                 return 0;
136 }
137
138 static int _wfd_event_update_peer(wfd_manager_s *manager, wfd_oem_dev_data_s *data)
139 {
140         __WDS_LOG_FUNC_ENTER__;
141         wfd_device_s *peer = NULL;
142
143         if (!manager || !data) {
144                 WDS_LOGE("Invalid parameter");
145                 return -1;
146         }
147
148         peer = wfd_peer_find_by_dev_addr(manager, data->p2p_dev_addr);
149         if (!peer) {
150                 peer = wfd_add_peer(manager, data->p2p_dev_addr, data->name);
151                 if (!peer) {
152                         WDS_LOGE("Failed to add peer");
153                         return -1;
154                 }
155         } else {
156                 if (strcmp(peer->dev_name, data->name)) {
157                         strncpy(peer->dev_name, data->name, DEV_NAME_LEN);
158                         peer->dev_name[DEV_NAME_LEN] = '\0';
159                         WDS_LOGD("Device name is changed [" MACSTR ": %s]", MAC2STR(peer->dev_addr), peer->dev_name);
160                 }
161         }
162         memcpy(peer->intf_addr, data->p2p_intf_addr, MACADDR_LEN);
163         peer->pri_dev_type = data->pri_dev_type;
164         peer->sec_dev_type = data->sec_dev_type;
165         peer->config_methods = data->config_methods;
166         peer->dev_flags = data->dev_flags;
167         peer->group_flags = data->group_flags;
168         peer->dev_role = data->dev_role;
169
170         if(!peer->wifi_display)
171                 peer->wifi_display = calloc(1, sizeof(wfd_display_info_s));
172         memcpy(peer->wifi_display, &data->wifi_display, sizeof(wfd_display_info_s));
173
174         struct timeval tval;
175         gettimeofday(&tval, NULL);
176         peer->time = tval.tv_sec;
177
178         WDS_LOGI("Update time [%s - %ld]", peer->dev_name, peer->time);
179
180         __WDS_LOG_FUNC_EXIT__;
181         return 0;
182 }
183
184 static int hex2num(const char c)
185 {
186         if (c >= '0' && c <= '9')
187                 return c - '0';
188         if (c >= 'a' && c <= 'f')
189                 return c - 'a' + 10;
190         if (c >= 'A' && c <= 'F')
191                 return c - 'A' + 10;
192         return -1;
193 }
194
195 static int hex2byte(const char *hex)
196 {
197         int a, b;
198         a = hex2num(*hex++);
199         if (a < 0)
200                 return -1;
201         b = hex2num(*hex++);
202         if (b < 0)
203                 return -1;
204         return (a << 4) | b;
205 }
206
207 int hexstr2bin(const char *hex, int len, char *buf)
208 {
209         int i;
210         int a;
211         const char *ipos = hex;
212         char *opos = buf;
213
214         for (i = 0; i < len; i++) {
215                 a = hex2byte(ipos);
216                 if (a < 0)
217                         return -1;
218                 *opos++ = a;
219                 ipos += 2;
220         }
221         return 0;
222 }
223
224 static int _wfd_get_stlv_len(const char* value)
225 {
226         int a, b;
227         a = hex2byte(value +2);
228         b = hex2byte(value);
229
230         if( a >= 0 && b >= 0)
231                 return ( a << 8) | b;
232         else
233                 return -1;
234 }
235
236 static int _wfd_service_add(wfd_device_s *device, wifi_direct_service_type_e type, char *data)
237 {
238         __WDS_LOG_FUNC_ENTER__;
239         wfd_service_s *service = NULL;
240         GList *temp = NULL;
241         int res = 0;
242
243         temp = g_list_first(device->services);
244         while (temp) {
245                 service = temp->data;
246
247                 if(type == service->service_type &&
248                                 !strcmp(data, service->service_string))
249                 {
250                         WDS_LOGD("Service found");
251                         break;
252                 }
253                 temp = g_list_next(temp);
254                 service = NULL;
255         }
256
257         if (service) {
258                 WDS_LOGE("service already exist");
259                 free(data);
260                 __WDS_LOG_FUNC_EXIT__;
261                 return res;
262         }
263         service = (wfd_service_s*) calloc(1, sizeof(wfd_service_s));
264         service->service_string = data;
265         service->service_str_length = strlen(data);
266         service->service_type = type;
267         device->services = g_list_prepend(device->services, service);
268
269         __WDS_LOG_FUNC_EXIT__;
270         return res;
271 }
272
273 static int _wfd_update_service(wfd_device_s *peer, char * data, wifi_direct_service_type_e  type, int length)
274 {
275         wfd_service_s * service;
276         int res = 0;
277         char *temp = NULL;
278         char *ptr = NULL;
279
280         if (!peer || !data) {
281                 WDS_LOGE("Invalid parameter");
282                 return -1;
283         }
284         switch (type)
285         {
286                 case WIFI_DIRECT_SERVICE_BONJOUR:
287                 {
288                         temp = strndup(data, length*2);
289                         res = _wfd_service_add(peer, type, temp);
290                         break;
291                 }
292                 case WIFI_DIRECT_SERVICE_UPNP:
293                 {
294                         temp = calloc(1, length);
295                         hexstr2bin(data +2, length - 1, temp);
296                         temp[length - 1] = '\0';
297
298                         ptr = strtok(temp, ",");
299
300                         while(ptr != NULL)
301                         {
302                                 res = _wfd_service_add(peer, type, strndup(ptr, strlen(ptr)));
303                                 ptr = strtok(NULL, ",");
304                         }
305
306                         if(temp)
307                                 free(temp);
308                         break;
309                 }
310                 case WIFI_DIRECT_SERVICE_VENDORSPEC:
311                 {
312                         temp = calloc(1, length + 1);
313                         hexstr2bin(data, length, temp);
314                         temp[length] = '\0';
315
316                         res = _wfd_service_add(peer, type, temp);
317                         break;
318                 }
319                 default:
320                 {
321                         res = -1;
322                         break;
323                 }
324         }
325         return res;
326 }
327
328 static int _wfd_event_update_service(wfd_manager_s *manager, wfd_device_s *peer, char *data)
329 {
330         __WDS_LOG_FUNC_ENTER__;
331         int res = 0;
332         int s_len = 0;
333         char *pos = data;
334         char *end = NULL;
335         wifi_direct_service_type_e  service_tlv_type;
336         int status = 0;
337
338         if (!peer || !data) {
339                 WDS_LOGE("Invalid parameter");
340                 return -1;
341         }
342         end = data + strlen(data);
343
344         while(pos <= end -10){// This is raw data that is not passed any exception handling ex> length, value, ...
345
346                 s_len = _wfd_get_stlv_len(pos);
347                 pos += 4;
348                 if (pos + s_len*2 > end || s_len < 3) {
349                         WDS_LOGD("Unexpected Response Data or length: %d", s_len);
350                         break;
351                 }
352
353                 service_tlv_type = hex2byte(pos);
354                 if (service_tlv_type < 0) {
355                         WDS_LOGD("Unexpected Response service type: %d", service_tlv_type);
356                         pos+=(s_len)*2;
357                         continue;
358                 }else if (service_tlv_type == 255)
359                         service_tlv_type = WIFI_DIRECT_SERVICE_VENDORSPEC;
360
361                 pos += 4;
362                 status = hex2byte(pos);
363                 pos += 2;
364
365                 if (status == 0)
366                 {
367                         res = _wfd_update_service(peer, pos, service_tlv_type, s_len -3);
368                         if (res != 0) {
369                                 WDS_LOGE("Invalid type");
370                         }
371                 } else
372                         WDS_LOGD("Service Reaponse TLV status is not vaild status: %d", status);
373                 pos+=(s_len-3)*2;
374         }
375         __WDS_LOG_FUNC_EXIT__;
376         return 0;
377 }
378
379 int wfd_process_event(void *user_data, void *data)
380 {
381         __WDS_LOG_FUNC_ENTER__;
382         wfd_manager_s *manager = (wfd_manager_s*) user_data;
383         wfd_oem_event_s *event = (wfd_oem_event_s*) data;
384         int res = 0;
385
386         if (!manager || !event) {
387                 WDS_LOGE("Invalid parameter");
388                 return -1;
389         }
390
391         WDS_LOGD("Event[%d] from " MACSTR, event->event_id, MAC2STR(event->dev_addr));
392
393         switch (event->event_id) {
394         case WFD_OEM_EVENT_DEACTIVATED:
395                 manager->req_wps_mode = WFD_WPS_MODE_PBC;
396                 break;
397         case WFD_OEM_EVENT_PEER_FOUND:
398         {
399                 wfd_oem_dev_data_s *edata = (wfd_oem_dev_data_s*) event->edata;
400                 res = _wfd_event_update_peer(manager, edata);
401                 if (res < 0) {
402                         WDS_LOGE("Failed to update peer data");
403                         break;
404                 }
405
406                 if (manager->state > WIFI_DIRECT_STATE_ACTIVATING &&
407                                 manager->state != WIFI_DIRECT_STATE_CONNECTING &&
408                                 manager->state != WIFI_DIRECT_STATE_DISCONNECTING) {
409                         wifi_direct_client_noti_s noti;
410                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
411                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_FOUND_PEERS;
412                         noti.error = WIFI_DIRECT_ERROR_NONE;
413                         wfd_client_send_event(manager, &noti);
414                 }
415         }
416         break;
417         case WFD_OEM_EVENT_PROV_DISC_REQ:
418         case WFD_OEM_EVENT_PROV_DISC_RESP:
419         {
420                 wfd_group_s *group = (wfd_group_s*) manager->group;
421                 if ((group && group->member_count >= manager->max_station) ||
422                                 (wfd_manager_access_control(manager, event->dev_addr) == WFD_DEV_DENIED)) {
423                         WDS_LOGD("Provision discovery is not granted");
424                         break;
425                 }
426
427                 wfd_device_s *peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
428                 if (!peer) {
429                         WDS_LOGD("Porv_disc from unknown peer. Add new peer");
430                         peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
431                         if (!peer) {
432                                 WDS_LOGE("Failed to add peer for invitation");
433                                 return -1;
434                         }
435                         peer->state = WFD_PEER_STATE_CONNECTING;
436                         wfd_update_peer(manager, peer);
437                 }
438                 wfd_update_peer_time(manager, event->dev_addr);
439
440                 res = wfd_session_process_event(manager, event);
441                 if (res < 0) {
442                         WDS_LOGE("Failed to process event of session");
443                         break;
444                 }
445         }
446         break;
447         case WFD_OEM_EVENT_PEER_DISAPPEARED:
448         {
449                 wfd_remove_peer(manager, event->dev_addr);
450                 wifi_direct_client_noti_s noti;
451                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
452                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_FOUND_PEERS;
453                 noti.error = WIFI_DIRECT_ERROR_NONE;
454                 wfd_client_send_event(manager, &noti);
455         }
456         break;
457         case WFD_OEM_EVENT_DISCOVERY_FINISHED:
458         {
459                 if (manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
460                                 manager->state != WIFI_DIRECT_STATE_ACTIVATED) {
461                         WDS_LOGE("Notify finding stoped when discovering or activated. [%d]", manager->state);
462                         break;
463                 }
464
465                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
466                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
467                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
468                 } else {
469                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
470                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
471                 }
472                 manager->scan_mode = WFD_SCAN_MODE_NONE;
473
474                 wifi_direct_client_noti_s noti;
475                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
476                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCOVER_END;
477                 noti.error = WIFI_DIRECT_ERROR_NONE;
478                 wfd_client_send_event(manager, &noti);
479         }
480         break;
481         case WFD_OEM_EVENT_INVITATION_REQ:
482         {
483                 wfd_dev_connection_flag_e flag = 0;
484                 flag = wfd_manager_access_control(manager, event->dev_addr);
485                 if (flag == WFD_DEV_DENIED) {
486                         WDS_LOGD("Invitation request is not granted");
487                         break;
488                 }
489                 wfd_device_s *peer = NULL;
490                 wfd_session_s *session = NULL;
491                 wfd_oem_invite_data_s *edata = (wfd_oem_invite_data_s*) event->edata;
492
493                 peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
494                 if (!peer) {
495                         WDS_LOGD("Invitation from unknown peer. Add new peer");
496                         peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
497                         if (!peer) {
498                                 WDS_LOGE("Failed to add peer for invitation");
499                                 return -1;
500                         }
501                 }
502                 peer->dev_role = WFD_DEV_ROLE_GO;
503                 memcpy(peer->intf_addr, edata->bssid, MACADDR_LEN);
504                 wfd_update_peer_time(manager, event->dev_addr);
505
506                 session = wfd_create_session(manager, event->dev_addr,
507                                                 manager->req_wps_mode, SESSION_DIRECTION_INCOMING);
508                 if (!session) {
509                         WDS_LOGE("Failed to create session");
510                         return -1;
511                 }
512                 session->type = SESSION_TYPE_INVITE;
513                 wfd_session_timer(session, 1);
514
515                 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
516                 if(flag == WFD_DEV_UNKNOWN)
517                 {
518                         WDS_LOGD("device is not in access/deny list");
519                         wifi_direct_client_noti_s noti;
520                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
521                         noti.event = WIFI_DIRECT_CLI_EVENT_INVITATION_REQ;
522                         noti.error = WIFI_DIRECT_ERROR_NONE;
523                         snprintf(noti.param1, sizeof(noti.param1), MACSTR, MAC2STR(event->dev_addr));
524                         wfd_client_send_event(manager, &noti);
525                 }else {
526                         WDS_LOGD("device is allowed");
527                         wfd_session_start(session);
528                 }
529         }
530         break;
531         case WFD_OEM_EVENT_GO_NEG_REQ:
532         {
533                 if (wfd_manager_access_control(manager, event->dev_addr) == WFD_DEV_DENIED) {
534                         WDS_LOGD("GO negotiation is not granted");
535                         break;
536                 }
537         }
538         case WFD_OEM_EVENT_GO_NEG_DONE:
539         case WFD_OEM_EVENT_WPS_DONE:
540                 wfd_session_process_event(manager, event);
541         break;
542         case WFD_OEM_EVENT_CONNECTED:
543         case WFD_OEM_EVENT_STA_CONNECTED:
544         {
545                 // FIXME: Move this code to plugin
546                 if (!memcmp(event->intf_addr, manager->local->intf_addr, MACADDR_LEN)) {
547                         WDS_LOGD("Ignore this event");
548                         break;
549                 }
550
551                 if(wfd_manager_find_connected_peer(manager, event->intf_addr)) {
552                         WDS_LOGD("Ignore this event");
553                         break;
554                 }
555
556                 wfd_session_s *session = (wfd_session_s*) manager->session;
557                 if (!session) {
558                         WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]",
559                                                                                 MAC2STR(event->dev_addr));
560                         wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
561                         wfd_destroy_group(manager, GROUP_IFNAME);
562                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
563                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
564                         break;
565                 } 
566
567                 wfd_device_s *peer = wfd_session_get_peer(session);
568                 if (!peer) {
569                         WDS_LOGE("Peer not found");
570                         break;
571                 }
572
573                 wfd_group_s *group = (wfd_group_s*) manager->group;
574                 if (!group) {
575                         group = wfd_create_pending_group(manager, event->intf_addr);
576                         if (!group) {
577                                 WDS_LOGE("Failed to create pending group");
578                                 break;
579                         }
580                         manager->group = group;
581                 }
582                 wfd_group_add_member(group, peer->dev_addr);
583
584                 session->state = SESSION_STATE_COMPLETED;
585                 memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
586                 peer->state = WFD_PEER_STATE_CONNECTED;
587
588                 if (event->event_id == WFD_OEM_EVENT_STA_CONNECTED) {   // GO
589                         wifi_direct_client_noti_s noti;
590                         memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
591                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
592                         noti.error = WIFI_DIRECT_ERROR_NONE;
593                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
594                         wfd_client_send_event(manager, &noti);
595
596                         wfd_util_dhcps_wait_ip_leased(peer);
597                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
598                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
599                         wfd_destroy_session(manager);
600                 }
601         }
602         break;
603         case WFD_OEM_EVENT_DISCONNECTED:
604         case WFD_OEM_EVENT_STA_DISCONNECTED:
605         {
606                 wfd_group_s *group = (wfd_group_s*) manager->group;
607                 wfd_session_s *session = (wfd_session_s*) manager->session;
608                 wfd_device_s *peer = NULL;
609                 unsigned char peer_addr[MACADDR_LEN] = {0, };
610                 wifi_direct_client_noti_s noti;
611                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
612
613                 peer = wfd_group_find_member_by_addr(group, event->intf_addr);
614                 if (!peer) {
615                         WDS_LOGE("Failed to find connected peer");
616                         peer = wfd_session_get_peer(session);
617                         if (!peer) {
618                                 WDS_LOGE("Failed to find connecting peer");
619                                 break;
620                         }
621                 }
622                 memcpy(peer_addr, peer->dev_addr, MACADDR_LEN);
623
624                 /* If state is not DISCONNECTING, connection is finished by peer */
625                 if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
626                         wfd_group_remove_member(group, peer_addr);
627                         if (group->member_count)
628                                 noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
629                         else
630                                 noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_IND;
631                         noti.error = WIFI_DIRECT_ERROR_NONE;
632                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
633                         /* If there is no member, GO should be destroyed */
634                         if (!group->member_count) {
635                                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
636                                 wfd_destroy_group(manager, group->ifname);
637                         }
638                 } else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
639                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
640                         noti.error = WIFI_DIRECT_ERROR_NONE;
641                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
642                 } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
643                                         /* Some devices(GO) send disconnection message before connection completed.
644                                          * This message should be ignored when device is not GO */
645                                         manager->local->dev_role == WFD_DEV_ROLE_GO) {
646                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
647                         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
648                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
649                 } else {
650                         WDS_LOGE("Unexpected event. Ignore it");
651                         break;
652                 }
653                 wfd_client_send_event(manager, &noti);
654
655                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
656                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
657                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
658                 } else {
659                         wfd_destroy_group(manager, GROUP_IFNAME);
660                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
661                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
662                 }
663                 wfd_destroy_session(manager);
664         }
665         break;
666         case WFD_OEM_EVENT_GROUP_CREATED:
667         {
668                 wfd_oem_group_data_s *edata = event->edata;
669                 wfd_group_s *group = (wfd_group_s*) manager->group;
670
671                 if (!group) {
672                         if (!manager->session) {
673                                 WDS_LOGE("Unexpected Event. Group should be removed(Client)");
674                                 wfd_oem_destroy_group(manager->oem_ops, event->ifname);
675                                 break;
676                         }
677
678                         group = wfd_create_group(manager, event->ifname, event->dev_role, edata->go_dev_addr);
679                         if (!group) {
680                                 WDS_LOGE("Failed to create group");
681                                 break;
682                         }
683                 } else {
684                         if (!manager->session && !(group->flags & WFD_GROUP_FLAG_AUTONOMOUS)) {
685                                 WDS_LOGE("Unexpected Event. Group should be removed(Owner)");
686                                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
687                                 break;
688                         }
689
690                         if (group->pending) {
691                                 wfd_group_complete(manager, event->ifname, event->dev_role, edata->go_dev_addr);
692                         } else {
693                                 WDS_LOGE("Unexpected event. Group already exist");
694                                 break;
695                         }
696                 }
697
698                 strncpy(group->ssid, edata->ssid, DEV_NAME_LEN);
699                 group->ssid[DEV_NAME_LEN-1] = '\0';
700                 strncpy(group->pass,edata->pass, PASSPHRASE_LEN);
701                 group->pass[PASSPHRASE_LEN] = '\0';
702                 group->freq = edata->freq;
703                 manager->group = group;
704                 manager->local->dev_role = event->dev_role;
705
706                 wifi_direct_client_noti_s noti;
707                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
708                 if (group->role == WFD_DEV_ROLE_GC) {
709                         wfd_destroy_session(manager);
710                         wfd_peer_clear_all(manager);
711                 } else {
712                         if (group->flags & WFD_GROUP_FLAG_AUTONOMOUS) {
713                                 noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_CREATE_RSP;
714                                 wfd_client_send_event(manager, &noti);
715                                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
716                                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
717                         }
718                 }
719         }
720         break;
721         case WFD_OEM_EVENT_GROUP_DESTROYED:
722         {
723                 wifi_direct_client_noti_s noti;
724                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
725                 if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
726                         noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
727                         noti.error = WIFI_DIRECT_ERROR_NONE;
728                 } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING && manager->session){
729                         noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
730                         noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
731                         unsigned char *peer_addr = wfd_session_get_peer_addr(manager->session);
732                         snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
733                 } else if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
734                         noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_DESTROY_RSP;
735                         noti.error = WIFI_DIRECT_ERROR_NONE;
736                 } else {
737                         WDS_LOGD("Unexpected event(GROUP_DESTROYED). Ignore it");
738                         break;
739                 }
740                 wfd_client_send_event(manager, &noti);
741
742                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
743                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
744                 wfd_destroy_group(manager, event->ifname);
745                 wfd_destroy_session(manager);
746                 manager->local->dev_role = WFD_DEV_ROLE_NONE;
747         }
748         break;
749         case WFD_OEM_EVENT_PROV_DISC_FAIL:
750         case WFD_OEM_EVENT_GO_NEG_FAIL:
751         case WFD_OEM_EVENT_WPS_FAIL:
752         case WFD_OEM_EVENT_KEY_NEG_FAIL:
753         {
754                 wfd_session_s *session = (wfd_session_s*) manager->session;
755                 if (!session) {
756                         WDS_LOGE("Unexpected event. Session not exist");
757                         break;
758                 }
759
760                 unsigned char *peer_addr = wfd_session_get_peer_addr(session);
761                 if (!peer_addr) {
762                         WDS_LOGE("Session do not has peer");
763                         break;
764                 }
765
766                 wifi_direct_client_noti_s noti;
767                 memset(&noti, 0x0, sizeof(wifi_direct_client_noti_s));
768                 noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
769                 noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
770                 snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
771                 wfd_client_send_event(manager, &noti);
772
773                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
774                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
775                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
776                 } else {
777                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
778                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
779                 }
780
781                 wfd_destroy_session(manager);
782
783                 /* After connection failed, scan again */
784                 wfd_oem_scan_param_s param;
785                 memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
786                 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
787                 param.scan_time = 2;
788                 param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
789                 wfd_oem_start_scan(manager->oem_ops, &param);
790                 manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
791         }
792         break;
793         case WFD_OEM_EVENT_SERV_DISC_RESP:
794         {
795                 wfd_device_s *peer = NULL;
796                 if(event->edata_type != WFD_OEM_EDATA_TYPE_SERVICE)
797                 {
798                         WDS_LOGD("There is no service to register");
799                         break;
800                 }
801                 peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
802                 if (!peer) {
803                         WDS_LOGD("serv_disc_resp from unknown peer. Discard it");
804                         break;
805                 }
806                 res = _wfd_event_update_service(manager, peer, (char*) event->edata);
807                 if (res < 0) {
808                         WDS_LOGE("Failed to update peer service data");
809                 }
810         }
811         break;
812         default:
813                 WDS_LOGE("Unknown event [event ID: %d]", event->event_id);
814         break;
815         }
816
817         __WDS_LOG_FUNC_EXIT__;
818         return 0;
819 }
820