Destroy session first, and destroy group later
[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 #include "wifi-direct-asp.h"
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         peer->pri_dev_type = data->pri_dev_type;
81         peer->sec_dev_type = data->sec_dev_type;
82         peer->config_methods = data->config_methods;
83         peer->dev_flags = data->dev_flags;
84         peer->group_flags = data->group_flags;
85         peer->dev_role = data->dev_role;
86         peer->rssi =  data->rssi;
87         WDS_LOGD("Peer RSSI value is %d", peer->rssi);
88
89         if (manager->is_wifi_display_supported)
90                 memcpy(&(peer->display), &(data->display), sizeof(wfd_display_s));
91
92 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
93         wfd_util_get_current_time(&peer->time);
94 #else
95         struct timeval tval;
96         gettimeofday(&tval, NULL);
97         peer->time = tval.tv_sec;
98 #endif
99         WDS_LOGI("Update time [%s - %ld]", peer->dev_name, peer->time);
100
101         __WDS_LOG_FUNC_EXIT__;
102         return 0;
103 }
104
105 gboolean _wfd_connection_retry(gpointer *data)
106 {
107         wfd_session_s *session = (wfd_session_s*) data;
108         if (!session) {
109                 WDS_LOGE("Session is NULL");
110                 __WDS_LOG_FUNC_EXIT__;
111                 return G_SOURCE_REMOVE;
112         }
113
114         switch (session->state) {
115         case SESSION_STATE_STARTED:
116                 WDS_LOGD("PD again");
117                 wfd_session_start(session);
118         break;
119         case SESSION_STATE_GO_NEG:
120                 WDS_LOGD("Negotiation again");
121                 wfd_session_connect(session);
122         break;
123         case SESSION_STATE_WPS:
124                 WDS_LOGD("WPS again");
125                 wfd_session_wps(session);
126         break;
127         default:
128                 WDS_LOGE("Invalid session state [%d]", session->state);
129         break;
130         }
131         __WDS_LOG_FUNC_EXIT__;
132         return G_SOURCE_REMOVE;
133 }
134
135 void wfd_event_deactivated(wfd_oem_event_s *event)
136 {
137         __WDS_LOG_FUNC_ENTER__;
138
139         wfd_manager_s *manager = wfd_get_manager();
140
141         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
142                                      "Deactivation",
143                                      g_variant_new("(i)", WIFI_DIRECT_ERROR_NONE));
144
145         wfd_destroy_session(manager);
146         wfd_destroy_group(manager);
147         wfd_peer_clear_all(manager);
148         wfd_local_reset_data(manager);
149
150         wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
151         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
152         manager->req_wps_mode = WFD_WPS_MODE_PBC;
153
154         if (manager->is_connection_agent)
155                 wfd_util_stop_wifi_direct_popup();
156
157         __WDS_LOG_FUNC_EXIT__;
158         return;
159 }
160
161 void wfd_event_peer_found(wfd_oem_event_s *event)
162 {
163         __WDS_LOG_FUNC_ENTER__;
164
165         wfd_manager_s *manager = wfd_get_manager();
166         wfd_oem_dev_data_s *edata = NULL;
167         char peer_mac_address[MACSTR_LEN+1] = {0, };
168         int res = 0;
169
170         edata = (wfd_oem_dev_data_s*) event->edata;
171         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
172                 WDS_LOGE("Invalid event data");
173                 __WDS_LOG_FUNC_EXIT__;
174                 return;
175         }
176
177         res = _wfd_event_update_peer(manager, edata);
178         if (res < 0) {
179                 WDS_LOGE("Failed to update peer data");
180                 __WDS_LOG_FUNC_EXIT__;
181                 return;
182         }
183
184         if (manager->state > WIFI_DIRECT_STATE_ACTIVATING &&
185                         manager->state != WIFI_DIRECT_STATE_CONNECTING &&
186                         manager->state != WIFI_DIRECT_STATE_DISCONNECTING) {
187                 snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(edata->p2p_dev_addr));
188                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
189                                              "PeerFound",
190                                              g_variant_new("(s)", peer_mac_address));
191         }
192
193         if (manager->is_asp_supported) {
194                 GList *list;
195                 GVariantBuilder *builder = NULL;
196                 GVariant *params = NULL;
197                 wfd_oem_advertise_service_s *service;
198
199                 for (list = (GList *)event->asp_services; list != NULL; list = list->next) {
200                         service = (wfd_oem_advertise_service_s *)list->data;
201
202                         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
203                         g_variant_builder_add(builder, "{sv}", "search_id", g_variant_new("t", service->search_id));
204                         g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", peer_mac_address));
205                         g_variant_builder_add(builder, "{sv}", "device_name", g_variant_new("s", edata->name));
206                         g_variant_builder_add(builder, "{sv}", "advertisement_id", g_variant_new("u", service->adv_id));
207                         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", service->config_method));
208                         if (service->service_type)
209                                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
210                         params = g_variant_new("(a{sv})", builder);
211                         g_variant_builder_unref(builder);
212
213                         wfd_manager_dbus_emit_signal(WFD_MANAGER_ASP_INTERFACE,
214                                                          "SearchResult",
215                                                          params);
216                 }
217
218                 for (list = (GList *)event->asp2_services; list != NULL; list = list->next) {
219                         service = (wfd_oem_advertise_service_s *)list->data;
220
221                         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
222                         g_variant_builder_add(builder, "{sv}", "search_id", g_variant_new("t", service->search_id));
223                         g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", peer_mac_address));
224                         g_variant_builder_add(builder, "{sv}", "device_name", g_variant_new("s", edata->name));
225                         g_variant_builder_add(builder, "{sv}", "advertisement_id", g_variant_new("u", service->adv_id));
226                         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", service->config_method));
227                         if (service->service_type)
228                                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
229                         if (service->instance_name)
230                                 g_variant_builder_add(builder, "{sv}", "instance_name", g_variant_new("s", service->instance_name));
231                         params = g_variant_new("(a{sv})", builder);
232                         g_variant_builder_unref(builder);
233
234                         wfd_manager_dbus_emit_signal(WFD_MANAGER_ASP_INTERFACE,
235                                                          "SearchResult",
236                                                          params);
237                 }
238         }
239         __WDS_LOG_FUNC_EXIT__;
240         return;
241 }
242
243 void wfd_event_peer_disappeared(wfd_oem_event_s *event)
244 {
245         __WDS_LOG_FUNC_ENTER__;
246
247         wfd_manager_s *manager = wfd_get_manager();
248         wfd_session_s *session = NULL;
249         wfd_device_s *peer = NULL;
250         char peer_mac_address[MACSTR_LEN+1] = {0, };
251
252         session = manager->session;
253         if (session != NULL && session->peer != NULL) {
254                 peer = session->peer;
255                 WDS_LOGD("session peer [" MACSTR "] lost peer ["  MACSTR "]", MAC2STR(peer->dev_addr),
256                                                 MAC2STR(event->dev_addr));
257                 if (memcmp(peer->dev_addr, event->dev_addr, MACADDR_LEN) == 0) {
258                         WDS_LOGD("peer already in connection");
259                         return;
260                 }
261         }
262
263         wfd_remove_peer(manager, event->dev_addr);
264
265         snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
266         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
267                                      "PeerLost",
268                                      g_variant_new("(s)", peer_mac_address));
269
270         __WDS_LOG_FUNC_EXIT__;
271         return;
272 }
273
274 void wfd_event_discovery_finished(wfd_oem_event_s *event)
275 {
276         __WDS_LOG_FUNC_ENTER__;
277
278         wfd_manager_s *manager = wfd_get_manager();
279
280         if (manager->state != WIFI_DIRECT_STATE_DISCOVERING &&
281                         manager->state != WIFI_DIRECT_STATE_ACTIVATED) {
282                 WDS_LOGE("Notify finding stopped when discovering or activated. [%d]", manager->state);
283                 __WDS_LOG_FUNC_EXIT__;
284                 return;
285         }
286
287         if (manager->scan_mode == WFD_SCAN_MODE_PASSIVE) {
288                 WDS_LOGE("During passive scan, Discover Finished event will not notified");
289                 __WDS_LOG_FUNC_EXIT__;
290                 return;
291         }
292
293         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
294                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
295                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
296         } else {
297                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
298                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
299         }
300         manager->scan_mode = WFD_SCAN_MODE_NONE;
301
302         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
303                                      "DiscoveryFinished",
304                                      NULL);
305
306         __WDS_LOG_FUNC_EXIT__;
307         return;
308 }
309
310 void wfd_event_prov_disc_req(wfd_oem_event_s *event)
311 {
312         __WDS_LOG_FUNC_ENTER__;
313
314         wfd_manager_s *manager = wfd_get_manager();
315         wfd_device_s *peer = NULL;
316         wfd_device_s *member = NULL;
317         int res = 0;
318         wfd_group_s *group = (wfd_group_s*) manager->group;
319
320         if (group && group->role == WFD_DEV_ROLE_GC) {
321                 WDS_LOGD("Device has GC role - ignore this provision request");
322                 __WDS_LOG_FUNC_EXIT__;
323                 return;
324         }
325
326         member = wfd_group_find_member_by_addr(group,  event->dev_addr);
327         if (member) {
328                 /* PD request can be arrived from peer device
329                  * when connection is timeout to close connection */
330                 WDS_LOGE("Unexpected Event - Member already exist");
331                 __WDS_LOG_FUNC_EXIT__;
332                 return;
333         }
334
335         wfd_oem_dev_data_s *edata = NULL;
336
337         edata = (wfd_oem_dev_data_s*) event->edata;
338         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
339                 WDS_LOGE("Invalid event data");
340                 __WDS_LOG_FUNC_EXIT__;
341                 return;
342         }
343
344         res = _wfd_event_update_peer(manager, edata);
345         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
346
347         if (WFD_DEV_ROLE_GO != manager->local->dev_role) {
348                 WDS_LOGI("TV is not GO, updated peer data only.");
349
350                 manager->local->wps_mode = event->wps_mode;
351                 if (event->wps_mode == WFD_WPS_MODE_PBC ||
352                                 event->wps_mode == WFD_WPS_MODE_KEYPAD) {
353                         __WDS_LOG_FUNC_EXIT__;
354                         return;
355                 }
356         }
357
358         if (peer)
359                 peer->state = WFD_PEER_STATE_CONNECTING;
360
361         res = wfd_session_process_event(manager, event);
362         if (res < 0)
363                 WDS_LOGE("Failed to process event of session");
364
365         __WDS_LOG_FUNC_EXIT__;
366         return;
367 }
368
369 void wfd_event_prov_disc_resp(wfd_oem_event_s *event)
370 {
371         __WDS_LOG_FUNC_ENTER__;
372
373         wfd_manager_s *manager = wfd_get_manager();
374         wfd_device_s *peer = NULL;
375         int res = 0;
376
377         wfd_oem_dev_data_s *edata = NULL;
378
379         edata = (wfd_oem_dev_data_s*) event->edata;
380         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
381                 WDS_LOGE("Invalid event data");
382                 __WDS_LOG_FUNC_EXIT__;
383                 return;
384         }
385
386         res = _wfd_event_update_peer(manager, edata);
387         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
388         if (peer)
389                 peer->state = WFD_PEER_STATE_CONNECTING;
390
391         res = wfd_session_process_event(manager, event);
392         if (res < 0)
393                 WDS_LOGE("Failed to process event of session");
394
395         __WDS_LOG_FUNC_EXIT__;
396         return;
397 }
398
399 static bool __asp_prov_disc_deferred(wfd_session_s *session, void *event_data)
400 {
401         wfd_oem_asp_prov_s *prov_params = (wfd_oem_asp_prov_s *)event_data;
402         bool is_deferred = false;
403
404         if (prov_params && !ISZEROMACADDR(session->session_mac)) {
405                 /* This connection is for ASP session */
406                 if (prov_params->status == WFD_OEM_SC_FAIL_INVALID_PARAMS) {
407                         WDS_LOGD("ASP prov disc deferred. wait response.");
408                         wfd_asp_connect_status(session->session_mac,
409                                                                 session->session_id,
410                                                                 ASP_CONNECT_STATUS_REQUEST_DEFERRED,
411                                                                 NULL);
412                         is_deferred = true;
413                 }
414         }
415         __WDS_LOG_FUNC_EXIT__;
416         return is_deferred;
417 }
418
419 void wfd_event_prov_disc_fail(wfd_oem_event_s *event)
420 {
421         __WDS_LOG_FUNC_ENTER__;
422
423         wfd_manager_s *manager = wfd_get_manager();
424         wfd_session_s *session = NULL;
425         unsigned char *peer_addr = NULL;
426         char peer_mac_address[MACSTR_LEN+1] = {0, };
427
428         session = (wfd_session_s*) manager->session;
429         if (!session) {
430                 WDS_LOGE("Unexpected event. Session not exist");
431                 __WDS_LOG_FUNC_EXIT__;
432                 return;
433         }
434
435         peer_addr = wfd_session_get_peer_addr(session);
436         if (!peer_addr) {
437                 WDS_LOGE("Session do not have peer");
438                 __WDS_LOG_FUNC_EXIT__;
439                 return;
440         }
441
442         if (manager->is_asp_supported) {
443                 if (__asp_prov_disc_deferred(session, event->edata)) {
444                         /* start listen to wait for provision discovery request from peer */
445                         wfd_oem_scan_param_s param;
446                         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
447                         param.scan_mode = WFD_OEM_SCAN_MODE_PASSIVE;
448                         wfd_oem_start_scan(manager->oem_ops, &param);
449                         __WDS_LOG_FUNC_EXIT__;
450                         return;
451                 }
452         }
453
454         snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
455         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
456                                      "Connection",
457                                      g_variant_new("(iis)",
458                                                    WIFI_DIRECT_ERROR_CONNECTION_FAILED,
459                                                    WFD_EVENT_CONNECTION_RSP,
460                                                    peer_mac_address));
461         if (wfd_asp_is_asp_session(session)) {
462                 WDS_LOGD("ASP prov disc failed. remove session.");
463                 wfd_asp_connect_status(session->session_mac,
464                                                         session->session_id,
465                                                         ASP_CONNECT_STATUS_REQUEST_FAILED,
466                                                         NULL);
467         }
468
469         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
470                 wfd_group_s *group = (wfd_group_s*) manager->group;
471                 if (group && !group->member_count &&
472                     wfd_util_is_remove_group_allowed()) {
473                         wfd_destroy_group(manager);
474
475                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
476                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
477                 } else {
478                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
479                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
480                 }
481         } else {
482                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
483                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
484         }
485
486         wfd_destroy_session(manager);
487
488         wfd_oem_refresh(manager->oem_ops);
489 #if 0
490         /* After connection failed, scan again */
491         wfd_oem_scan_param_s param;
492         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
493         param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
494         param.scan_time = 2;
495         param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
496         wfd_oem_start_scan(manager->oem_ops, &param);
497         manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
498 #endif
499         __WDS_LOG_FUNC_EXIT__;
500         return;
501 }
502
503 void wfd_event_go_neg_req(wfd_oem_event_s *event)
504 {
505         __WDS_LOG_FUNC_ENTER__;
506
507         wfd_manager_s *manager = wfd_get_manager();
508         wfd_group_s *group = (wfd_group_s*) manager->group;
509         if (group && group->role == WFD_DEV_ROLE_GC) {
510                 WDS_LOGD("Device has GC role - ignore this go neg request");
511                 __WDS_LOG_FUNC_EXIT__;
512                 return;
513         }
514
515         wfd_oem_dev_data_s *edata = NULL;
516         int res = 0;
517
518         edata = (wfd_oem_dev_data_s*) event->edata;
519         if (!edata || event->edata_type != WFD_OEM_EDATA_TYPE_DEVICE) {
520                 WDS_LOGE("Invalid event data");
521                 __WDS_LOG_FUNC_EXIT__;
522                 return;
523         }
524
525         res = _wfd_event_update_peer(manager, edata);
526         if (res < 0) {
527                 WDS_LOGE("Failed to update peer data");
528                 __WDS_LOG_FUNC_EXIT__;
529                 return;
530         }
531
532         wfd_session_process_event(manager, event);
533         __WDS_LOG_FUNC_EXIT__;
534         return;
535 }
536
537 void wfd_event_go_neg_fail(wfd_oem_event_s *event)
538 {
539         __WDS_LOG_FUNC_ENTER__;
540
541         wfd_manager_s *manager = wfd_get_manager();
542         wfd_session_s *session = NULL;
543         wfd_oem_conn_data_s *edata = NULL;
544         unsigned char *peer_addr = NULL;
545         char peer_mac_address[MACSTR_LEN] = {0, };
546
547         session = (wfd_session_s*) manager->session;
548         if (!session) {
549                 WDS_LOGE("Unexpected event. Session not exist");
550                 __WDS_LOG_FUNC_EXIT__;
551                 return;
552         }
553
554         peer_addr = wfd_session_get_peer_addr(session);
555         if (!peer_addr) {
556                 WDS_LOGE("Session do not have peer");
557                 __WDS_LOG_FUNC_EXIT__;
558                 return;
559         }
560
561         edata = (wfd_oem_conn_data_s*) event->edata;
562         if (!edata) {
563                 WDS_LOGE("Invalid p2p connection data");
564                 __WDS_LOG_FUNC_EXIT__;
565                 return;
566         }
567
568         if (edata->status < 0 && session->connecting_120) {
569                 if (session->retry_gsrc) {
570                         g_source_remove(session->retry_gsrc);
571                         session->retry_gsrc = 0;
572                 }
573                 session->retry_gsrc = g_idle_add((GSourceFunc) _wfd_connection_retry, session);
574                 WDS_LOGD("Connection will be retried");
575                 __WDS_LOG_FUNC_EXIT__;
576                 return;
577         }
578
579         snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
580         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
581                                      "Connection",
582                                      g_variant_new("(iis)",
583                                                    WIFI_DIRECT_ERROR_CONNECTION_FAILED,
584                                                    WFD_EVENT_CONNECTION_RSP,
585                                                    peer_mac_address));
586
587         if (wfd_asp_is_asp_session(session)) {
588                 wfd_asp_connect_status(session->session_mac,
589                                 session->session_id,
590                                 ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
591                                 NULL);
592         }
593
594         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
595         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
596
597         wfd_destroy_session(manager);
598         wfd_destroy_group(manager);
599         manager->local->dev_role = WFD_DEV_ROLE_NONE;
600         __WDS_LOG_FUNC_EXIT__;
601         return;
602 }
603
604 void wfd_event_go_neg_done(wfd_oem_event_s *event)
605 {
606         __WDS_LOG_FUNC_ENTER__;
607
608         wfd_manager_s *manager = wfd_get_manager();
609         wfd_session_s *session = NULL;
610         wfd_oem_conn_data_s *edata = NULL;
611         wfd_device_s *peer = NULL;
612
613         edata = (wfd_oem_conn_data_s*) event->edata;
614         if (edata == NULL) {
615                 WDS_LOGE("Invalid event data");
616                 __WDS_LOG_FUNC_EXIT__;
617                 return;
618         }
619
620         session = (wfd_session_s*) manager->session;
621         if (session && session->peer) {
622                 peer = session->peer;
623                 memcpy(peer->intf_addr, edata->peer_intf_addr, MACADDR_LEN);
624         }
625
626         wfd_session_process_event(manager, event);
627         __WDS_LOG_FUNC_EXIT__;
628         return;
629 }
630
631 void wfd_event_wps_fail(wfd_oem_event_s *event)
632 {
633         __WDS_LOG_FUNC_ENTER__;
634
635         wfd_manager_s *manager = wfd_get_manager();
636         wfd_session_s *session = NULL;
637         unsigned char *peer_addr = NULL;
638
639         session = (wfd_session_s*) manager->session;
640         if (!session) {
641                 WDS_LOGE("Unexpected event. Session not exist");
642                 __WDS_LOG_FUNC_EXIT__;
643                 return;
644         }
645
646         peer_addr = wfd_session_get_peer_addr(session);
647         if (!peer_addr) {
648                 WDS_LOGE("Session do not have peer");
649                 __WDS_LOG_FUNC_EXIT__;
650                 return;
651         }
652
653         char peer_mac_address[MACSTR_LEN+1] = {0, };
654         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
655         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
656                                      "Connection",
657                                      g_variant_new("(iis)",
658                                                    WIFI_DIRECT_ERROR_CONNECTION_FAILED,
659                                                    WFD_EVENT_CONNECTION_RSP,
660                                                    peer_mac_address));
661         if (wfd_asp_is_asp_session(session)) {
662                 wfd_asp_connect_status(session->session_mac,
663                                                         session->session_id,
664                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
665                                                         NULL);
666         }
667
668         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
669                 wfd_group_s *group = (wfd_group_s*) manager->group;
670                 if (group && !group->member_count &&
671                     wfd_util_is_remove_group_allowed()) {
672                         wfd_destroy_group(manager);
673
674                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
675                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
676                 } else {
677                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
678                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
679                 }
680         } else {
681                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
682                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
683         }
684
685         wfd_destroy_session(manager);
686
687         wfd_oem_refresh(manager->oem_ops);
688 #if 0
689         /* After connection failed, scan again */
690         wfd_oem_scan_param_s param;
691         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
692         param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
693         param.scan_time = 2;
694         param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
695         wfd_oem_start_scan(manager->oem_ops, &param);
696         manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
697 #endif
698         __WDS_LOG_FUNC_EXIT__;
699         return;
700 }
701
702 void wfd_event_wps_done(wfd_oem_event_s *event)
703 {
704         __WDS_LOG_FUNC_ENTER__;
705
706         wfd_manager_s *manager = wfd_get_manager();
707         wfd_session_process_event(manager, event);
708
709         __WDS_LOG_FUNC_EXIT__;
710         return;
711 }
712
713 void wfd_event_key_neg_fail(wfd_oem_event_s *event)
714 {
715         __WDS_LOG_FUNC_ENTER__;
716
717         wfd_manager_s *manager = wfd_get_manager();
718         wfd_session_s *session = NULL;
719         unsigned char *peer_addr = NULL;
720         char peer_mac_address[MACSTR_LEN+1] = {0, };
721
722         session = (wfd_session_s*) manager->session;
723         if (!session) {
724                 WDS_LOGE("Unexpected event. Session not exist");
725                 __WDS_LOG_FUNC_EXIT__;
726                 return;
727         }
728
729         peer_addr = wfd_session_get_peer_addr(session);
730         if (!peer_addr) {
731                 WDS_LOGE("Session do not has peer");
732                 __WDS_LOG_FUNC_EXIT__;
733                 return;
734         }
735
736         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
737         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
738                                      "Connection",
739                                      g_variant_new("(iis)",
740                                                    WIFI_DIRECT_ERROR_CONNECTION_FAILED,
741                                                    WFD_EVENT_CONNECTION_RSP,
742                                                    peer_mac_address));
743         if (wfd_asp_is_asp_session(session)) {
744                 wfd_asp_connect_status(session->session_mac,
745                                                         session->session_id,
746                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
747                                                         NULL);
748         }
749
750         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
751                 wfd_group_s *group = (wfd_group_s*) manager->group;
752                 if (group && !group->member_count &&
753                     wfd_util_is_remove_group_allowed()) {
754                         wfd_destroy_group(manager);
755
756                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
757                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
758                 } else {
759                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
760                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
761                 }
762         } else {
763                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
764                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
765         }
766
767         wfd_destroy_session(manager);
768
769         wfd_oem_refresh(manager->oem_ops);
770 #if 0
771         /* After connection failed, scan again */
772         wfd_oem_scan_param_s param;
773         memset(&param, 0x0, sizeof(wfd_oem_scan_param_s));
774         param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
775         param.scan_time = 2;
776         param.scan_type = WFD_OEM_SCAN_TYPE_SOCIAL;
777         wfd_oem_start_scan(manager->oem_ops, &param);
778         manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
779 #endif
780         __WDS_LOG_FUNC_EXIT__;
781         return;
782 }
783
784 void wfd_event_key_neg_done(wfd_oem_event_s *event)
785 {
786         __WDS_LOG_FUNC_ENTER__;
787
788         __WDS_LOG_FUNC_EXIT__;
789         return;
790 }
791
792 void wfd_event_conn_fail(wfd_oem_event_s *event)
793 {
794         __WDS_LOG_FUNC_ENTER__;
795
796         __WDS_LOG_FUNC_EXIT__;
797         return;
798 }
799
800 void wfd_event_conn_done(wfd_oem_event_s *event)
801 {
802         __WDS_LOG_FUNC_ENTER__;
803
804         __WDS_LOG_FUNC_EXIT__;
805         return;
806 }
807
808 void wfd_event_group_created(wfd_oem_event_s *event)
809 {
810         __WDS_LOG_FUNC_ENTER__;
811
812         wfd_manager_s *manager = wfd_get_manager();
813         wfd_group_s *group = (wfd_group_s*) manager->group;
814         wfd_session_s *session = (wfd_session_s*) manager->session;
815
816         if (!group) {
817                 group = wfd_create_pending_group(manager, event->intf_addr);
818                 if (!group) {
819                         WDS_LOGE("Failed to create pending group");
820                         __WDS_LOG_FUNC_EXIT__;
821                         return;
822                 }
823
824                 manager->group = group;
825         }
826
827         wfd_group_complete(manager, event);
828
829         if (group->role == WFD_DEV_ROLE_GC && session) {
830                 wfd_device_s *peer = session->peer;
831                 if (peer == NULL) {
832                         WDS_LOGE("Unexpected event. Peer doesn't exist");
833                         return;
834                 }
835
836                 wfd_update_peer(manager, peer);
837
838                 if (peer->ip_type == WFD_IP_TYPE_OVER_EAPOL) {
839                         char peer_mac_address[MACSTR_LEN+1] = {0, };
840
841                         wfd_util_ip_over_eap_assign(peer, event->ifname);
842
843                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
844                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
845                                                      "Connection",
846                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
847                                                                             WFD_EVENT_CONNECTION_RSP,
848                                                                             peer_mac_address));
849                         if (wfd_asp_is_asp_session(session)) {
850                                 wfd_asp_connect_status(session->session_mac,
851                                                                         session->session_id,
852                                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
853                                                                         NULL);
854                                 wfd_asp_session_peer_ip(session->session_mac, session->session_id,
855                                                 session->service_mac, peer->ip_addr);
856                         }
857                         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
858                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
859
860                         wfd_destroy_session(manager);
861                 }
862                 wfd_peer_clear_all(manager);
863         } else {
864                 if (group->flags & WFD_GROUP_FLAG_AUTONOMOUS) {
865                         wfd_manager_dbus_emit_signal(WFD_MANAGER_GROUP_INTERFACE,
866                                                      "Created", NULL);
867                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
868                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
869                 }
870         }
871         __WDS_LOG_FUNC_EXIT__;
872         return;
873 }
874
875 void wfd_event_group_destroyed(wfd_oem_event_s *event)
876 {
877         __WDS_LOG_FUNC_ENTER__;
878
879         wfd_manager_s *manager = wfd_get_manager();
880         char peer_mac_address[MACSTR_LEN+1] = {0, };
881         unsigned char *peer_addr = wfd_session_get_peer_addr(manager->session);
882
883         if (peer_addr != NULL)
884                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
885         else
886                 g_snprintf(peer_mac_address, MACSTR_LEN, "%s", "");
887
888         if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
889                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
890                                              "Disconnection",
891                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
892                                                                     WFD_EVENT_DISCONNECTION_RSP,
893                                                                     peer_mac_address));
894
895         } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING && manager->session) {
896                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
897                                              "Connection",
898                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
899                                                                     WFD_EVENT_CONNECTION_RSP,
900                                                                     peer_mac_address));
901                 wfd_session_s *session = manager->session;
902                 if (wfd_asp_is_asp_session(session)) {
903                         wfd_asp_connect_status(session->session_mac,
904                                         session->session_id,
905                                         ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
906                                         NULL);
907                 }
908         } else if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
909                 if (manager->local->dev_role != WFD_DEV_ROLE_GO) {
910                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
911                                                      "Disconnection",
912                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
913                                                                             WFD_EVENT_DISCONNECTION_RSP,
914                                                                             peer_mac_address));
915                 } else {
916                         wfd_manager_dbus_emit_signal(WFD_MANAGER_GROUP_INTERFACE,
917                                                      "Destroyed", NULL);
918                 }
919         } else {
920                 WDS_LOGD("Unexpected event(GROUP_DESTROYED). Ignore it");
921                 __WDS_LOG_FUNC_EXIT__;
922                 return;
923         }
924
925         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
926         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
927         wfd_destroy_session(manager);
928         wfd_destroy_group(manager);
929         manager->local->dev_role = WFD_DEV_ROLE_NONE;
930
931         __WDS_LOG_FUNC_EXIT__;
932         return;
933 }
934
935 void wfd_event_invitation_req(wfd_oem_event_s *event)
936 {
937         __WDS_LOG_FUNC_ENTER__;
938
939         wfd_manager_s *manager = wfd_get_manager();
940         wfd_device_s *peer = NULL;
941         wfd_session_s *session = NULL;
942         wfd_oem_invite_data_s *edata = NULL;
943         int res = 0;
944         char peer_mac_address[MACSTR_LEN+1] = {0, };
945
946         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
947         if (!peer) {
948                 WDS_LOGD("Invitation from unknown peer. Add new peer");
949                 peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
950                 if (!peer) {
951                         WDS_LOGE("Failed to add peer for invitation");
952                         __WDS_LOG_FUNC_EXIT__;
953                         return;
954                 }
955         }
956         peer->dev_role = WFD_DEV_ROLE_GO;
957
958         edata = (wfd_oem_invite_data_s*) event->edata;
959         memcpy(peer->intf_addr, edata->bssid, MACADDR_LEN);
960         wfd_update_peer_time(manager, event->dev_addr);
961
962         if (!ISZEROMACADDR(edata->go_dev_addr))
963                 session = wfd_create_session(manager, edata->go_dev_addr,
964                                              manager->req_wps_mode,
965                                              SESSION_DIRECTION_INCOMING);
966         else
967                 session = wfd_create_session(manager, event->dev_addr,
968                                              manager->req_wps_mode,
969                                              SESSION_DIRECTION_INCOMING);
970         if (!session) {
971                 WDS_LOGE("Failed to create session");
972                 __WDS_LOG_FUNC_EXIT__;
973                 return;
974         }
975         session->type = SESSION_TYPE_INVITE;
976         wfd_session_timer(session, 1);
977
978         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
979         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
980
981         res = wfd_session_start(session);
982         if (res < 0) {
983                 WDS_LOGE("Failed to start session");
984                 __WDS_LOG_FUNC_EXIT__;
985                 return;
986         }
987
988         if (!ISZEROMACADDR(edata->go_dev_addr))
989                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR,
990                            MAC2STR(edata->go_dev_addr));
991         else
992                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR,
993                            MAC2STR(event->dev_addr));
994
995         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
996                                      "Connection",
997                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
998                                                             WFD_EVENT_CONNECTION_REQ,
999                                                             peer_mac_address));
1000
1001         __WDS_LOG_FUNC_EXIT__;
1002         return;
1003 }
1004
1005 void wfd_event_invitation_res(wfd_oem_event_s *event)
1006 {
1007         __WDS_LOG_FUNC_ENTER__;
1008
1009         __WDS_LOG_FUNC_EXIT__;
1010         return;
1011 }
1012
1013 void wfd_event_sta_connected(wfd_oem_event_s *event)
1014 {
1015         __WDS_LOG_FUNC_ENTER__;
1016
1017         wfd_manager_s *manager = wfd_get_manager();
1018         wfd_session_s *session = (wfd_session_s*) manager->session;
1019         wfd_group_s *group = (wfd_group_s*) manager->group;
1020         wfd_device_s *peer = NULL;
1021         char peer_mac_address[MACSTR_LEN+1] = {0, };
1022
1023         /* FIXME: Move this code to plugin */
1024         if (!memcmp(event->intf_addr, manager->local->intf_addr, MACADDR_LEN)) {
1025                 WDS_LOGD("Ignore this event");
1026                 __WDS_LOG_FUNC_EXIT__;
1027                 return;
1028         }
1029
1030         if (ISZEROMACADDR(event->dev_addr)) {
1031                 WDS_LOGD("Legacy Peer Connected [Peer: " MACSTR "]", MAC2STR(event->intf_addr));
1032
1033                 peer = wfd_peer_find_by_addr(manager, event->intf_addr);
1034                 if (!peer) {
1035                         WDS_LOGI("Add legacy peer");
1036                         peer = wfd_add_peer(manager, event->intf_addr, "LEGACY-PEER");
1037                         if (!peer) {
1038                                 WDS_LOGE("Failed to add Legacy peer.");
1039                                 __WDS_LOG_FUNC_EXIT__;
1040                                 return;
1041                         }
1042                 }
1043
1044                 if (wfd_group_add_member(group, peer->dev_addr) == -1) {
1045                         WDS_LOGE("Failed to add Legacy peer.");
1046                         __WDS_LOG_FUNC_EXIT__;
1047                         return;
1048                 }
1049
1050                 memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
1051                 peer->state = WFD_PEER_STATE_CONNECTED;
1052                 peer->is_p2p = FALSE;
1053
1054                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1055                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1056                                              "Connection",
1057                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1058                                                                     WFD_EVENT_CONNECTION_RSP,
1059                                                                     peer_mac_address));
1060
1061                 wfd_util_dhcps_wait_ip_leased(peer);
1062                 __WDS_LOG_FUNC_EXIT__;
1063                 return;
1064         }
1065
1066         session = (wfd_session_s*) manager->session;
1067         if (!session && group) {
1068                 if (group->flags & WFD_GROUP_FLAG_PERSISTENT) {
1069                         session = wfd_create_session(manager, event->dev_addr,
1070                                                      event->wps_mode,
1071                                                      SESSION_DIRECTION_INCOMING);
1072                         if (!session) {
1073                                 WDS_LOGE("Failed to create session with peer [" MACSTR "]",
1074                                          MAC2STR(event->dev_addr));
1075                                 __WDS_LOG_FUNC_EXIT__;
1076                                 return;
1077                         }
1078                 } else {
1079                         WDS_LOGD("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1080                                  MAC2SECSTR(event->dev_addr));
1081                         if (group) {
1082                                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1083                                 wfd_destroy_group(manager);
1084                         }
1085
1086                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1087                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1088                         __WDS_LOG_FUNC_EXIT__;
1089                         return;
1090                 }
1091         }
1092
1093         peer = wfd_session_get_peer(session);
1094         if (!peer) {
1095                 WDS_LOGE("Peer not found");
1096                 __WDS_LOG_FUNC_EXIT__;
1097                 return;
1098         }
1099
1100         group = (wfd_group_s*) manager->group;
1101         if (!group) {
1102                 group = wfd_create_pending_group(manager, event->intf_addr);
1103                 if (!group) {
1104                         WDS_LOGE("Failed to create pending group");
1105                         __WDS_LOG_FUNC_EXIT__;
1106                         return;
1107                 }
1108                 manager->group = group;
1109         }
1110         wfd_group_add_member(group, peer->dev_addr);
1111
1112         session->state = SESSION_STATE_COMPLETED;
1113         peer->state = WFD_PEER_STATE_CONNECTED;
1114
1115         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1116         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1117
1118         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1119         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1120                                      "Connection",
1121                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1122                                                             WFD_EVENT_CONNECTION_RSP,
1123                                                             peer_mac_address));
1124
1125         wfd_update_peer(manager, peer);
1126         if (event->ip_addr_peer[3]) {
1127                 peer->ip_type = WFD_IP_TYPE_OVER_EAPOL;
1128                 memcpy(peer->client_ip_addr, event->ip_addr_peer, IPADDR_LEN);
1129                 WDS_LOGE("Peer's client IP [" IPSTR "]", IP2STR((char*) &peer->client_ip_addr));
1130                 memcpy(peer->go_ip_addr, manager->local->ip_addr, IPADDR_LEN);
1131                 WDS_LOGE("Peer's GO IP [" IPSTR "]", IP2STR((char*) &peer->go_ip_addr));
1132         }
1133         if (peer->ip_type == WFD_IP_TYPE_OVER_EAPOL) {
1134                 char peer_mac_address[MACSTR_LEN+1] = {0,};
1135                 char assigned_ip_address[IPSTR_LEN+1] = {0,};
1136
1137                 memcpy(peer->ip_addr, peer->client_ip_addr, IPADDR_LEN);
1138
1139                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1140                 g_snprintf(assigned_ip_address, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1141                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1142                                      "PeerIPAssigned",
1143                                      g_variant_new("(ss)", peer_mac_address,
1144                                                            assigned_ip_address));
1145                 if (wfd_asp_is_asp_session(session)) {
1146                         wfd_asp_connect_status(session->session_mac,
1147                                                                 session->session_id,
1148                                                                 ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
1149                                                                 NULL);
1150
1151                         wfd_asp_session_peer_ip(session->session_mac, session->session_id,
1152                                         session->service_mac, peer->ip_addr);
1153                 }
1154         } else {
1155                 wfd_util_dhcps_wait_ip_leased(peer);
1156         }
1157         wfd_destroy_session(manager);
1158
1159         __WDS_LOG_FUNC_EXIT__;
1160         return;
1161 }
1162
1163 void wfd_event_sta_disconnected(wfd_oem_event_s *event)
1164 {
1165         __WDS_LOG_FUNC_ENTER__;
1166
1167         wfd_manager_s *manager = wfd_get_manager();
1168         wfd_group_s *group = NULL;
1169         wfd_device_s *peer = NULL;
1170         unsigned char peer_addr[MACADDR_LEN] = {0, };
1171         char peer_mac_address[MACSTR_LEN+1] = {0, };
1172
1173         group = (wfd_group_s*) manager->group;
1174         if (!group) {
1175                 WDS_LOGE("Group not found");
1176                 __WDS_LOG_FUNC_EXIT__;
1177                 return;
1178         }
1179
1180         if (ISZEROMACADDR(event->dev_addr)) {
1181                 WDS_LOGD("Legacy Peer Disconnected [Peer: " MACSTR "]", MAC2STR(event->intf_addr));
1182                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->intf_addr));
1183                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1184                                              "Disconnection",
1185                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1186                                                                     WFD_EVENT_DISCONNECTION_IND,
1187                                                                     peer_mac_address));
1188
1189                 wfd_group_remove_member(group, event->intf_addr);
1190
1191                 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1192                         wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1193                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1194                 } else {
1195                         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1196                         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1197                 }
1198                 __WDS_LOG_FUNC_EXIT__;
1199                 return;
1200         }
1201
1202         peer = wfd_group_find_member_by_addr(group, event->dev_addr);
1203         if (!peer) {
1204                 WDS_LOGE("Failed to find connected peer");
1205                 peer = wfd_session_get_peer(manager->session);
1206                 if (!peer) {
1207                         WDS_LOGE("Failed to find connecting peer");
1208                         __WDS_LOG_FUNC_EXIT__;
1209                         return;
1210                 }
1211
1212                 /**
1213                  * If no peer connected and
1214                  * disconnected event is not for connecting peer
1215                  * then event should be ignored.
1216                  * This situation can arrise when TV is GO and
1217                  * some connected peer sent disassociation.
1218                  */
1219                 if (memcmp(peer_addr, event->dev_addr, MACADDR_LEN)) {
1220                         WDS_LOGE("Unexpected event, Ignore it...");
1221                         __WDS_LOG_FUNC_EXIT__;
1222                         return;
1223                 }
1224         }
1225         memcpy(peer_addr, peer->dev_addr, MACADDR_LEN);
1226
1227         /**
1228          * If state is not DISCONNECTING, connection is finished by peer.
1229          *  Required the check also, when Device is Group Owner and state is DISCOVERING.
1230          */
1231         if (manager->state >= WIFI_DIRECT_STATE_CONNECTED ||
1232                                 (manager->state == WIFI_DIRECT_STATE_DISCOVERING &&
1233                                  manager->local->dev_role == WFD_DEV_ROLE_GO)) {
1234                 wfd_group_remove_member(group, peer_addr);
1235                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1236                 if (group->member_count) {
1237                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1238                                                      "Disconnection",
1239                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1240                                                                             WFD_EVENT_DISASSOCIATION_IND,
1241                                                                             peer_mac_address));
1242                 } else {
1243                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1244                                                      "Disconnection",
1245                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1246                                                                             WFD_EVENT_DISCONNECTION_IND,
1247                                                                             peer_mac_address));
1248                 }
1249
1250         } else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
1251                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1252                 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1253                                              "Disconnection",
1254                                              g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1255                                                                     WFD_EVENT_DISCONNECTION_RSP,
1256                                                                     peer_mac_address));
1257
1258         } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
1259                         /* Some devices(GO) send disconnection message before connection completed.
1260                          * This message should be ignored when device is not GO */
1261                         manager->local->dev_role == WFD_DEV_ROLE_GO) {
1262                 if (WFD_PEER_STATE_CONNECTED == peer->state) {
1263                         WDS_LOGD("Peer is already Connected !!!");
1264                         wfd_group_remove_member(group, peer_addr);
1265                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1266                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1267                                                      "Disconnection",
1268                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1269                                                                             WFD_EVENT_DISASSOCIATION_IND,
1270                                                                             peer_mac_address));
1271
1272                 } else if (WFD_PEER_STATE_CONNECTING == peer->state) {
1273                         WDS_LOGD("Peer is Connecting...");
1274                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1275                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1276                                                      "Connection",
1277                                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
1278                                                                             WFD_EVENT_CONNECTION_RSP,
1279                                                                             peer_mac_address));
1280                         wfd_session_s *session = manager->session;
1281                         if (wfd_asp_is_asp_session(session)) {
1282                                 wfd_asp_connect_status(session->session_mac,
1283                                                                         session->session_id,
1284                                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
1285                                                                         NULL);
1286                         }
1287                 } else {
1288                         WDS_LOGE("Unexpected Peer State. Ignore it");
1289                         __WDS_LOG_FUNC_EXIT__;
1290                         return;
1291                 }
1292         } else {
1293                 WDS_LOGE("Unexpected event. Ignore it");
1294                 __WDS_LOG_FUNC_EXIT__;
1295                 return;
1296         }
1297
1298         if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1299                 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
1300                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
1301         } else {
1302                 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1303                 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1304         }
1305
1306         /* If there is no member, GO should be destroyed */
1307         if (!group->member_count) {
1308                 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
1309                 wfd_destroy_group(manager);
1310                 wfd_peer_clear_all(manager);
1311         }
1312
1313         wfd_destroy_session(manager);
1314
1315         __WDS_LOG_FUNC_EXIT__;
1316         return;
1317 }
1318
1319 void wfd_event_terminating(wfd_oem_event_s *event)
1320 {
1321         __WDS_LOG_FUNC_ENTER__;
1322
1323         __WDS_LOG_FUNC_EXIT__;
1324         return;
1325 }
1326
1327 void wfd_event_group_formation_failure(wfd_oem_event_s *event)
1328 {
1329         __WDS_LOG_FUNC_ENTER__;
1330
1331         wfd_manager_s *manager = wfd_get_manager();
1332         wfd_session_s *session = (wfd_session_s*) manager->session;
1333         if (!session) {
1334                 WDS_LOGE("Unexpected event. Session not exist");
1335                 __WDS_LOG_FUNC_EXIT__;
1336                 return;
1337         }
1338
1339         unsigned char *peer_addr = wfd_session_get_peer_addr(session);
1340         if (!peer_addr) {
1341                 WDS_LOGE("Session do not has peer");
1342                 __WDS_LOG_FUNC_EXIT__;
1343                 return;
1344         }
1345
1346         char peer_mac_address[MACSTR_LEN+1] = {0, };
1347         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
1348         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1349                                      "Connection",
1350                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
1351                                                             WFD_EVENT_CONNECTION_RSP,
1352                                                             peer_mac_address));
1353
1354         if (wfd_asp_is_asp_session(session)) {
1355                 wfd_asp_connect_status(session->session_mac,
1356                                                         session->session_id,
1357                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
1358                                                         NULL);
1359         }
1360
1361         wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
1362         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
1363         wfd_destroy_session(manager);
1364         manager->local->dev_role = WFD_DEV_ROLE_NONE;
1365
1366         wfd_oem_refresh(manager->oem_ops);
1367
1368         __WDS_LOG_FUNC_EXIT__;
1369         return;
1370 }
1371
1372 /**
1373  * This event is generated by supplicant when persitent invite is auto accepted
1374  * so that wfd-manager can get indication that a peer will be connected in near future.
1375  * session is started for that peer, so that it is not ignored when connected.
1376  */
1377 void wfd_event_invitation_accepted(wfd_oem_event_s *event)
1378 {
1379
1380         __WDS_LOG_FUNC_ENTER__;
1381
1382         wfd_manager_s *manager = wfd_get_manager();
1383         wfd_session_s *session = (wfd_session_s*) manager->session;
1384         wfd_device_s *peer = NULL;
1385         char peer_mac_address[MACSTR_LEN+1] = {0, };
1386
1387         peer = wfd_peer_find_by_dev_addr(manager, event->dev_addr);
1388         if (!peer) {
1389                 WDS_LOGI("Invitation from unknown peer. Add new peer");
1390                 peer = wfd_add_peer(manager, event->dev_addr, "DIRECT-");
1391                 if (!peer) {
1392                         WDS_LOGE("Failed to add peer for invitation");
1393                         __WDS_LOG_FUNC_EXIT__;
1394                         return;
1395                 }
1396         }
1397         /**By default, peer device information is complete but there's some exception
1398         * if DEV-FOUND event was not preceding before connection start event.
1399         */
1400         wfd_update_peer(manager, peer);
1401         peer->dev_role = WFD_DEV_ROLE_GO;
1402
1403         if (!session) {
1404                 session = wfd_create_session(manager, event->dev_addr,
1405                                         event->wps_mode, SESSION_DIRECTION_INCOMING);
1406                 if (!session) {
1407                         WDS_LOGE("Failed to create session with peer [" MACSTR "]",
1408                                                         MAC2STR(event->dev_addr));
1409                         __WDS_LOG_FUNC_EXIT__;
1410                         return;
1411                 }
1412         }
1413
1414         session->state = SESSION_STATE_WPS;
1415         wfd_session_timer(session, 1);
1416
1417         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1418         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1419                                          "Connection",
1420                                          g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1421                                                                 WFD_EVENT_CONNECTION_IN_PROGRESS,
1422                                                                 peer_mac_address));
1423
1424         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
1425         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
1426
1427         __WDS_LOG_FUNC_EXIT__;
1428 }
1429
1430 void wfd_event_serv_disc_resp(wfd_oem_event_s *event)
1431 {
1432         __WDS_LOG_FUNC_ENTER__;
1433
1434         wfd_manager_s *manager = wfd_get_manager();
1435         int service_type;
1436         char response_data[256] = {0, };
1437         char peer_mac_address[MACSTR_LEN+1] = {0, };
1438
1439         if (!manager->is_service_discovery_supported) {
1440                 WDS_LOGD("service discovery not supported");
1441                 return;
1442         }
1443
1444         wfd_update_peer_time(manager, event->dev_addr);
1445
1446         if (event->edata_type == WFD_OEM_EDATA_TYPE_NEW_SERVICE) {
1447                 wfd_oem_new_service_s *service = NULL;;
1448                 GList *temp = NULL;
1449                 GList *services = (GList*) event->edata;
1450                 int count = 0;
1451
1452                 WDS_LOGD("%d service data found", event->dev_role);
1453
1454                 temp = g_list_first(services);
1455                 while (temp && count < event->dev_role) {
1456                         service = (wfd_oem_new_service_s*) temp->data;
1457                         service_type = service->protocol;
1458                         if (service->protocol == WFD_OEM_SERVICE_TYPE_BONJOUR) {
1459                                 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1460                                 g_snprintf(response_data, 256, "%s|%s", service->data.bonjour.query, service->data.bonjour.rdata);
1461                                 WDS_LOGD("Found service: [%d: %s] - [" MACSECSTR "]", service->protocol,
1462                                                         service->data.bonjour.query, MAC2SECSTR(event->dev_addr));
1463                         } else {
1464                                 WDS_LOGD("Found service is not supported");
1465                                 goto next;
1466                         }
1467
1468                         wfd_manager_dbus_emit_signal(WFD_MANAGER_SERVICE_INTERFACE,
1469                                                      "DiscoveryFound",
1470                                                      g_variant_new("(iss)", service_type,
1471                                                                             response_data,
1472                                                                             peer_mac_address));
1473 next:
1474                         temp = g_list_next(temp);
1475                         service = NULL;
1476                         count++;
1477                 }
1478         } else if (event->edata_type == WFD_OEM_EDATA_TYPE_SERVICE) {
1479                 wfd_oem_service_data_s *edata = (wfd_oem_service_data_s*) event->edata;
1480
1481                 if (!edata) {
1482                         service_type = -1;
1483                 } else {
1484                         service_type = edata->type;
1485                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1486                         switch (edata->type) {
1487                                 WDS_LOGE("Unknown type [type ID: %d]", edata->type);
1488                         }
1489                 }
1490
1491                 wfd_manager_dbus_emit_signal(WFD_MANAGER_SERVICE_INTERFACE,
1492                                              "DiscoveryFound",
1493                                              g_variant_new("(iss)", service_type,
1494                                                                     response_data,
1495                                                                     peer_mac_address));
1496         }
1497
1498         __WDS_LOG_FUNC_EXIT__;
1499         return;
1500 }
1501
1502 void wfd_event_serv_disc_started(wfd_oem_event_s *event)
1503 {
1504         __WDS_LOG_FUNC_ENTER__;
1505
1506         __WDS_LOG_FUNC_EXIT__;
1507         return;
1508 }
1509
1510
1511 void wfd_event_asp_serv_resp(wfd_oem_event_s *event)
1512 {
1513         __WDS_LOG_FUNC_ENTER__;
1514
1515         wfd_manager_s *manager = wfd_get_manager();
1516         wfd_oem_asp_service_s *service = NULL;
1517         GVariantBuilder *builder = NULL;
1518         GVariant *params = NULL;
1519
1520         if (manager && !manager->is_asp_supported) {
1521                 WDS_LOGD("ASP is not supported.");
1522                 __WDS_LOG_FUNC_EXIT__;
1523                 return;
1524         }
1525
1526         service = (wfd_oem_asp_service_s *)event->edata;
1527         if (service == NULL) {
1528                 WDS_LOGE("P2P service found event has NULL information");
1529                 __WDS_LOG_FUNC_EXIT__;
1530                 return;
1531         }
1532
1533         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1534         g_variant_builder_add(builder, "{sv}", "search_id", g_variant_new("u", service->search_id));
1535         g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", event->dev_addr));
1536         g_variant_builder_add(builder, "{sv}", "advertisement_id", g_variant_new("u", service->adv_id));
1537         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", service->config_method));
1538         if (service->service_type)
1539                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
1540         if (service->service_info)
1541                 g_variant_builder_add(builder, "{sv}", "service_info", g_variant_new("s", service->service_info));
1542         g_variant_builder_add(builder, "{sv}", "status", g_variant_new("y", service->status));
1543         params = g_variant_new("(a{sv})", builder);
1544         g_variant_builder_unref(builder);
1545
1546         wfd_manager_dbus_emit_signal(WFD_MANAGER_ASP_INTERFACE,
1547                                      "SearchResult",
1548                                      params);
1549
1550         __WDS_LOG_FUNC_EXIT__;
1551         return;
1552 }
1553
1554 int __wfd_handle_asp_prov(wfd_manager_s *manager, wfd_oem_event_s *event)
1555 {
1556         __WDS_LOG_FUNC_ENTER__;
1557
1558         wfd_session_s *session = NULL;
1559         wfd_oem_asp_prov_s *prov_params = NULL;
1560         int res = 0;
1561
1562         prov_params = (wfd_oem_asp_prov_s *)event->edata;
1563         if (prov_params == NULL) {
1564                 WDS_LOGE("Invalid parameter");
1565                 __WDS_LOG_FUNC_EXIT__;
1566                 return -1;
1567         }
1568
1569         res = wfd_session_process_event(manager, event);
1570         session = (wfd_session_s *)manager->session;
1571         if (res < 0 || session == NULL) {
1572                 WDS_LOGE("Failed to process event of session");
1573                 __WDS_LOG_FUNC_EXIT__;
1574                 return -1;
1575         }
1576         session->session_id = prov_params->session_id;
1577         memcpy(session->session_mac, prov_params->session_mac, MACADDR_LEN);
1578         memcpy(session->service_mac, prov_params->service_mac, MACADDR_LEN);
1579
1580         __WDS_LOG_FUNC_EXIT__;
1581         return 0;
1582 }
1583
1584 int __wfd_handle_asp_prov_done(wfd_session_s *session, wfd_oem_event_s *event)
1585 {
1586         __WDS_LOG_FUNC_ENTER__;
1587
1588         wfd_oem_asp_prov_s *prov_params = NULL;
1589         prov_params = (wfd_oem_asp_prov_s *)event->edata;
1590         int res = 0;
1591
1592         if (prov_params->persist &&
1593         (prov_params->network_role || prov_params->network_config)) {
1594                 WDS_LOGE("Persistent group is used but "
1595                                 "conncap/dev_passwd_id are present");
1596                 __WDS_LOG_FUNC_EXIT__;
1597                 return -1;
1598         }
1599
1600         if (!prov_params->persist &&
1601         (!prov_params->network_role && !prov_params->network_config)) {
1602                 WDS_LOGE("Persistent group not used but "
1603                                 "conncap/dev_passwd_id are missing");
1604                 __WDS_LOG_FUNC_EXIT__;
1605                 return -1;
1606         }
1607
1608         if (session->wps_mode == WFD_OEM_WPS_MODE_P2PS)
1609                 g_strlcpy(session->wps_pin, OEM_DEFAULT_P2PS_PIN, OEM_PINSTR_LEN + 1);
1610
1611         if (prov_params->persist) {
1612                 res = wfd_session_asp_persistent_connect(session, prov_params->persistent_group_id);
1613         } else if (prov_params->network_role == WFD_OEM_ASP_SESSION_ROLE_NEW) {
1614                 res = wfd_session_asp_connect(session, WFD_OEM_ASP_SESSION_ROLE_NEW);
1615         } else if (prov_params->network_role == WFD_OEM_ASP_SESSION_ROLE_CLIENT) {
1616                 res = wfd_session_asp_connect(session, WFD_OEM_ASP_SESSION_ROLE_CLIENT);
1617         } else if (prov_params->network_role == WFD_OEM_ASP_SESSION_ROLE_GO) {
1618                 res = wfd_session_asp_connect(session, WFD_OEM_ASP_SESSION_ROLE_GO);
1619                 WDS_LOGD("don't need to take action.");
1620
1621         } else {
1622                 WDS_LOGE("Unhandled event");
1623                 __WDS_LOG_FUNC_EXIT__;
1624                 res = -1;
1625         }
1626
1627         __WDS_LOG_FUNC_EXIT__;
1628         return res;
1629 }
1630
1631 void wfd_event_asp_prov_start(wfd_oem_event_s *event)
1632 {
1633         __WDS_LOG_FUNC_ENTER__;
1634
1635         wfd_manager_s *manager = wfd_get_manager();
1636         wfd_session_s *session = NULL;
1637         wfd_oem_asp_prov_s *prov_params = NULL;
1638         int res = 0;
1639
1640         if (manager == NULL || event == NULL || event->edata == NULL) {
1641                 WDS_LOGE("Invalid parameter");
1642                 __WDS_LOG_FUNC_EXIT__;
1643                 return;
1644         }
1645
1646         if (!manager->is_asp_supported) {
1647                 WDS_LOGD("ASP is not supported.");
1648                 __WDS_LOG_FUNC_EXIT__;
1649                 return;
1650         }
1651
1652         prov_params = (wfd_oem_asp_prov_s *)event->edata;
1653         res = __wfd_handle_asp_prov(manager, event);
1654         session = (wfd_session_s *)manager->session;
1655         if (res < 0 || session == NULL) {
1656                 WDS_LOGE("Failed to process event of session");
1657                 __WDS_LOG_FUNC_EXIT__;
1658                 return;
1659         }
1660
1661         WDS_LOGD("created session [%u] with peer [" MACSTR "]", session->session_id,
1662                         MAC2STR(session->session_mac));
1663
1664         /* Incomming Session, auto_accept = TRUE emit request Received */
1665         /* generate SessionConfigRequest if event->wps_mode is not P2PS  and return*/
1666
1667         wfd_session_timer(session, 1);
1668         wfd_asp_session_request(prov_params);
1669         wfd_asp_connect_status(prov_params->session_mac,
1670                                                 prov_params->session_id,
1671                                                 ASP_CONNECT_STATUS_REQUEST_RECEIVED,
1672                                                 NULL);
1673
1674         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
1675
1676         __WDS_LOG_FUNC_EXIT__;
1677         return;
1678 }
1679
1680 void wfd_event_asp_prov_done(wfd_oem_event_s *event)
1681 {
1682         __WDS_LOG_FUNC_ENTER__;
1683
1684         wfd_manager_s *manager = wfd_get_manager();
1685         wfd_session_s *session = NULL;
1686         wfd_oem_asp_prov_s *prov_params;
1687         int res = 0;
1688
1689         if (manager == NULL || event == NULL || event->edata == NULL) {
1690                 WDS_LOGE("Invalid parameter");
1691                 __WDS_LOG_FUNC_EXIT__;
1692                 return;
1693         }
1694
1695         if (!manager->is_asp_supported) {
1696                 WDS_LOGD("ASP is not supported.");
1697                 __WDS_LOG_FUNC_EXIT__;
1698                 return;
1699         }
1700
1701         prov_params = (wfd_oem_asp_prov_s *)event->edata;
1702         /* Incomming Session, auto_accept = TRUE emit request Received */
1703         /* generate SessionConfigRequest if event->wps_mode is not P2PS  and return*/
1704         if (manager->session == NULL) {
1705                 wfd_asp_session_request(prov_params);
1706                 wfd_asp_connect_status(prov_params->session_mac,
1707                                                         prov_params->session_id,
1708                                                         ASP_CONNECT_STATUS_REQUEST_RECEIVED,
1709                                                         NULL);
1710         }
1711
1712         res = __wfd_handle_asp_prov(manager, event);
1713         session = (wfd_session_s *)manager->session;
1714         if (res < 0 || session == NULL) {
1715                 WDS_LOGE("Failed to process event of session");
1716                 wfd_destroy_session(manager);
1717                 wfd_asp_connect_status(prov_params->session_mac,
1718                                                         prov_params->session_id,
1719                                                         ASP_CONNECT_STATUS_REQUEST_FAILED,
1720                                                         NULL);
1721                 wfd_oem_refresh(manager->oem_ops);
1722                 __WDS_LOG_FUNC_EXIT__;
1723                 return;
1724         }
1725
1726         if (prov_params->status != WFD_OEM_SC_SUCCESS &&
1727                         prov_params->status != WFD_OEM_SC_SUCCESS_ACCEPTED_BY_USER) {
1728                 WDS_LOGD("ASP-PROV failed. remove session.");
1729                 wfd_destroy_session(manager);
1730                 wfd_oem_refresh(manager->oem_ops);
1731                 wfd_asp_connect_status(prov_params->session_mac,
1732                                                         prov_params->session_id,
1733                                                         ASP_CONNECT_STATUS_REQUEST_FAILED,
1734                                                         NULL);
1735                 __WDS_LOG_FUNC_EXIT__;
1736                 return;
1737         }
1738
1739         wfd_asp_connect_status(prov_params->session_mac,
1740                                                 prov_params->session_id,
1741                                                 ASP_CONNECT_STATUS_REQUEST_ACCEPTED,
1742                                                 NULL);
1743
1744         wfd_asp_connect_status(prov_params->session_mac,
1745                                                 prov_params->session_id,
1746                                                 ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
1747                                                 NULL);
1748         res = __wfd_handle_asp_prov_done(session, event);
1749         if (res < 0) {
1750                 WDS_LOGE("Connect failed. remove session.");
1751                 wfd_destroy_session(manager);
1752                 wfd_oem_refresh(manager->oem_ops);
1753
1754                 wfd_asp_connect_status(prov_params->session_mac,
1755                                                         prov_params->session_id,
1756                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
1757                                                         NULL);
1758                 __WDS_LOG_FUNC_EXIT__;
1759                 return;
1760         }
1761
1762         WDS_LOGD("Provision done succeeded.");
1763         __WDS_LOG_FUNC_EXIT__;
1764         return;
1765 }
1766
1767 void wfd_event_init(wfd_oem_event_cbs_s *event_cbs)
1768 {
1769         __WDS_LOG_FUNC_ENTER__;
1770
1771         if (!event_cbs) {
1772                 __WDS_LOG_FUNC_EXIT__;
1773                 return;
1774         }
1775
1776         event_cbs->deactivated_cb = wfd_event_deactivated;
1777         event_cbs->peer_found_cb = wfd_event_peer_found;
1778         event_cbs->peer_disappeared_cb = wfd_event_peer_disappeared;
1779         event_cbs->discovery_finished_cb = wfd_event_discovery_finished;
1780
1781         event_cbs->prov_disc_req_cb = wfd_event_prov_disc_req;
1782         event_cbs->prov_disc_resp_cb = wfd_event_prov_disc_resp;
1783         event_cbs->prov_disc_fail_cb = wfd_event_prov_disc_fail;
1784
1785         event_cbs->go_neg_req_cb = wfd_event_go_neg_req;
1786         event_cbs->go_neg_fail_cb = wfd_event_go_neg_fail;
1787         event_cbs->go_neg_done_cb = wfd_event_go_neg_done;
1788
1789         event_cbs->wps_fail_cb = wfd_event_wps_fail;
1790         event_cbs->wps_done_cb = wfd_event_wps_done;
1791         event_cbs->key_neg_fail_cb = wfd_event_key_neg_fail;
1792         event_cbs->key_neg_done_cb = wfd_event_key_neg_done;
1793
1794         event_cbs->conn_fail_cb = wfd_event_conn_fail;
1795         event_cbs->conn_done_cb = wfd_event_conn_done;
1796
1797         event_cbs->group_created_cb = wfd_event_group_created;
1798         event_cbs->group_destroyed_cb = wfd_event_group_destroyed;
1799
1800         event_cbs->invitation_req_cb = wfd_event_invitation_req;
1801         event_cbs->invitation_resp_cb = wfd_event_invitation_res;
1802         event_cbs->sta_connected_cb = wfd_event_sta_connected;
1803         event_cbs->sta_disconnected_cb = wfd_event_sta_disconnected;
1804
1805         event_cbs->terminating_cb = wfd_event_terminating;
1806
1807         event_cbs->serv_disc_resp_cb = wfd_event_serv_disc_resp;
1808         event_cbs->serv_disc_started_cb = wfd_event_serv_disc_started;
1809
1810         event_cbs->group_formation_failure_cb = wfd_event_group_formation_failure;
1811         event_cbs->invitation_accepted_cb = wfd_event_invitation_accepted;
1812
1813         event_cbs->asp_serv_resp_cb = wfd_event_asp_serv_resp;
1814         event_cbs->asp_prov_start_cb = wfd_event_asp_prov_start;
1815         event_cbs->asp_prov_done_cb = wfd_event_asp_prov_done;
1816
1817         event_cbs->extra_data = NULL;
1818
1819         __WDS_LOG_FUNC_EXIT__;
1820         return;
1821 }