9f02dc7a5cd362ec502f3660263002f8b0f7133e
[platform/core/connectivity/net-config.git] / src / signal-handler.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 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 #include <stdio.h>
21 #include <string.h>
22 #include <vconf.h>
23 #include <vconf-keys.h>
24
25 #include "log.h"
26 #include "util.h"
27 #include "netdbus.h"
28 #include "neterror.h"
29 #include "wifi-wps.h"
30 #include "wifi-agent.h"
31 #include "wifi-power.h"
32 #include "wifi-state.h"
33 #include "netsupplicant.h"
34 #include "network-state.h"
35 #include "cellular-state.h"
36 #include "signal-handler.h"
37 #include "wifi-ssid-scan.h"
38 #include "wifi-background-scan.h"
39 #include "wifi-tdls.h"
40
41 #define DBUS_SERVICE_DBUS                       "org.freedesktop.DBus"
42 #define DBUS_INTERFACE_DBUS                     "org.freedesktop.DBus"
43 #define SIGNAL_INTERFACE_REMOVED                "InterfaceRemoved"
44 #define SIGNAL_SCAN_DONE                        "ScanDone"
45 #define SIGNAL_BSS_ADDED                        "BSSAdded"
46 #define SIGNAL_PROPERTIES_CHANGED               "PropertiesChanged"
47 #define SIGNAL_PROPERTIES_DRIVER_HANGED         "DriverHanged"
48 #define SIGNAL_PROPERTIES_SESSION_OVERLAPPED    "SessionOverlapped"
49 #define SIGNAL_TDLS_CONNECTED                           "TDLSConnected"
50 #define SIGNAL_TDLS_DISCONNECTED                        "TDLSDisconnected"
51 #define SIGNAL_TDLS_PEER_FOUND                          "TDLSPeerFound"
52
53 #define SIGNAL_WPS_CONNECTED                            "WPSConnected"
54 #define SIGNAL_WPS_EVENT                                        "Event"
55 #define SIGNAL_WPS_CREDENTIALS                          "Credentials"
56
57 #define CONNMAN_SIGNAL_SERVICES_CHANGED         "ServicesChanged"
58 #define CONNMAN_SIGNAL_PROPERTY_CHANGED         "PropertyChanged"
59 #define CONNMAN_SIGNAL_NAME_CHANGED             "NameOwnerChanged"
60
61 #define MAX_SIG_LEN 64
62 #define TOTAL_CONN_SIGNALS 5
63
64 typedef enum {
65         SIG_INTERFACE_REMOVED = 0,
66         SIG_PROPERTIES_CHANGED,
67         SIG_BSS_ADDED,
68         SIG_SCAN_DONE,
69         SIG_DRIVER_HANGED,
70         SIG_SESSION_OVERLAPPED,
71         SIG_TDLS_CONNECTED,
72         SIG_TDLS_DISCONNECTED,
73         SIG_TDLS_PEER_FOUND,
74         SIG_MAX
75 } SuppSigArrayIndex;
76
77 static int conn_subscription_ids[TOTAL_CONN_SIGNALS] = {0};
78 static const char supplicant_signals[SIG_MAX][MAX_SIG_LEN] = {
79                 SIGNAL_INTERFACE_REMOVED,
80                 SIGNAL_PROPERTIES_CHANGED,
81                 SIGNAL_BSS_ADDED,
82                 SIGNAL_SCAN_DONE,
83                 SIGNAL_PROPERTIES_DRIVER_HANGED,
84                 SIGNAL_PROPERTIES_SESSION_OVERLAPPED,
85                 SIGNAL_TDLS_CONNECTED,
86                 SIGNAL_TDLS_DISCONNECTED,
87                 SIGNAL_TDLS_PEER_FOUND,
88 };
89
90 static int supp_subscription_ids[SIG_MAX] = {0};
91
92 typedef void (*supplicant_signal_cb)(GDBusConnection *conn,
93                 const gchar *name, const gchar *path, const gchar *interface,
94                 const gchar *sig, GVariant *param, gpointer user_data);
95 typedef void (*connman_signal_cb)(GDBusConnection *conn,
96                 const gchar *name, const gchar *path, const gchar *interface,
97                 const gchar *sig, GVariant *param, gpointer user_data);
98
99 static void _technology_signal_cb(GDBusConnection *conn,
100                 const gchar *name, const gchar *path, const gchar *interface,
101                 const gchar *sig, GVariant *param, gpointer user_data)
102 {
103         gchar *key = NULL;
104         gboolean value = FALSE;
105         GVariant *var = NULL;
106
107         if (param == NULL)
108                 return;
109
110         if (g_str_has_prefix(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == TRUE) {
111                 g_variant_get(param, "(sv)", &key, &var);
112                 if (g_strcmp0(key, "Powered") == 0) {
113                         /* Power state */
114                         value = g_variant_get_boolean(var);
115                         if (value == TRUE)
116                                 wifi_state_update_power_state(TRUE);
117                         else
118                                 wifi_state_update_power_state(FALSE);
119                 } else if (g_strcmp0(key, "Connected") == 0) {
120                         /* Connection state */
121                         value = g_variant_get_boolean(var);
122                         if (value == TRUE)
123                                 wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_CONNECTED);
124                         else
125                                 wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_POWERED);
126                 } else if (g_strcmp0(key, "Tethering") == 0) {
127                         /* Tethering state */
128                         wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_TETHERED);
129                 }
130                 if (key)
131                         g_free(key);
132                 if (var)
133                         g_variant_unref(var);
134         }
135 }
136
137 static void _service_signal_cb(GDBusConnection *conn,
138                 const gchar *name, const gchar *path,
139                 const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data)
140 {
141         gchar *sigvalue = NULL;
142         gchar *property;
143         GVariant *variant = NULL, *var;
144         GVariantIter *iter;
145         const gchar *value = NULL;
146
147         if (path == NULL || param == NULL)
148                 goto done;
149
150         g_variant_get(param, "(sv)", &sigvalue, &variant);
151         if (sigvalue == NULL)
152                 goto done;
153
154         if (g_strcmp0(sig, CONNMAN_SIGNAL_PROPERTY_CHANGED) != 0)
155                 goto done;
156
157         if (g_strcmp0(sigvalue, "State") == 0) {
158                 g_variant_get(variant, "s", &property);
159
160                 DBG("[%s] %s", property, path);
161                 if (netconfig_is_wifi_profile(path) == TRUE) {
162                         int wifi_state = 0;
163
164                         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
165                         if (wifi_state == VCONFKEY_WIFI_OFF) {
166                                 g_free(property);
167                                 goto done;
168                         }
169
170                         if (g_strcmp0(property, "ready") == 0 || g_strcmp0(property, "online") == 0) {
171                                 if (wifi_state >= VCONFKEY_WIFI_CONNECTED) {
172                                         g_free(property);
173                                         goto done;
174                                 }
175
176                                 netconfig_update_default_profile(path);
177
178                                 wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTED);
179
180                         } else if (g_strcmp0(property, "failure") == 0 || g_strcmp0(property, "disconnect") == 0 || g_strcmp0(property, "idle") == 0) {
181                                 if (netconfig_get_default_profile() == NULL ||
182                                                 netconfig_is_wifi_profile(netconfig_get_default_profile())
183                                                 != TRUE) {
184                                         if (g_strcmp0(property, "failure") == 0)
185                                                 wifi_state_set_service_state(NETCONFIG_WIFI_FAILURE);
186                                         else
187                                                 wifi_state_set_service_state(NETCONFIG_WIFI_IDLE);
188                                         g_free(property);
189                                         goto done;
190                                 }
191
192                                 if (g_strcmp0(path, netconfig_get_default_profile()) != 0) {
193                                         g_free(property);
194                                         goto done;
195                                 }
196
197                                 netconfig_update_default_profile(NULL);
198
199                                 if (g_strcmp0(property, "failure") == 0)
200                                         wifi_state_set_service_state(NETCONFIG_WIFI_FAILURE);
201                                 else
202                                         wifi_state_set_service_state(NETCONFIG_WIFI_IDLE);
203
204                         } else if (g_strcmp0(property, "association") == 0 || g_strcmp0(property, "configuration") == 0) {
205                                 if (netconfig_get_default_profile() == NULL ||
206                                                 netconfig_is_wifi_profile(netconfig_get_default_profile()) != TRUE) {
207                                         if (g_strcmp0(property, "association") == 0)
208                                                 wifi_state_set_service_state(NETCONFIG_WIFI_ASSOCIATION);
209                                         else
210                                                 wifi_state_set_service_state(NETCONFIG_WIFI_CONFIGURATION);
211                                         g_free(property);
212                                         goto done;
213                                 }
214
215                                 if (g_strcmp0(path, netconfig_get_default_profile()) != 0) {
216                                         g_free(property);
217                                         goto done;
218                                 }
219
220                                 netconfig_update_default_profile(NULL);
221
222                                 if (g_strcmp0(property, "association") == 0)
223                                         wifi_state_set_service_state(NETCONFIG_WIFI_ASSOCIATION);
224                                 else
225                                         wifi_state_set_service_state(NETCONFIG_WIFI_CONFIGURATION);
226
227                         }
228                 } else {
229                         if (g_strcmp0(property, "ready") == 0 || g_strcmp0(property, "online") == 0) {
230                                 if (netconfig_get_default_profile() == NULL) {
231                                         if (!netconfig_is_cellular_profile(path))
232                                                 netconfig_update_default_profile(path);
233                                         else {
234                                                 if (netconfig_is_cellular_internet_profile(path))
235                                                         netconfig_update_default_profile(path);
236                                         }
237                                 }
238
239                                 if (netconfig_is_cellular_profile(path) && netconfig_is_cellular_internet_profile(path))
240                                         cellular_state_set_service_state(NETCONFIG_CELLULAR_ONLINE);
241
242                         } else if (g_strcmp0(property, "failure") == 0 || g_strcmp0(property, "disconnect") == 0 || g_strcmp0(property, "idle") == 0) {
243                                 if (netconfig_get_default_profile() == NULL) {
244                                         g_free(property);
245                                         goto done;
246                                 }
247
248                                 if (netconfig_is_cellular_profile(path) && netconfig_is_cellular_internet_profile(path))
249                                         cellular_state_set_service_state(NETCONFIG_CELLULAR_IDLE);
250
251                                 if (g_strcmp0(path, netconfig_get_default_profile()) != 0) {
252                                         g_free(property);
253                                         goto done;
254                                 }
255
256                                 netconfig_update_default_profile(NULL);
257                         } else if (g_strcmp0(property, "association") == 0 || g_strcmp0(property, "configuration") == 0) {
258                                 if (netconfig_get_default_profile() == NULL) {
259                                         g_free(property);
260                                         goto done;
261                                 }
262
263                                 if (netconfig_is_cellular_profile(path) && netconfig_is_cellular_internet_profile(path))
264                                         cellular_state_set_service_state(NETCONFIG_CELLULAR_CONNECTING);
265
266                                 if (g_strcmp0(path, netconfig_get_default_profile()) != 0) {
267                                         g_free(property);
268                                         goto done;
269                                 }
270
271                                 netconfig_update_default_profile(NULL);
272                         }
273                 }
274                 g_free(property);
275         } else if (g_strcmp0(sigvalue, "Proxy") == 0) {
276                 if (netconfig_is_wifi_profile(path) != TRUE || g_strcmp0(path, netconfig_get_default_profile()) != 0)
277                         goto done;
278
279                 if (!g_variant_type_equal(variant, G_VARIANT_TYPE_ARRAY))
280                         goto done;
281
282                 g_variant_get(variant, "a{sv}", &iter);
283                 while (g_variant_iter_loop(iter, "{sv}", &property, &var)) {
284                         if (g_strcmp0(property, "Servers") == 0) {
285                                 GVariantIter *iter_sub = NULL;
286
287                                 g_variant_get(var, "as", &iter_sub);
288                                 g_variant_iter_loop(iter_sub, "s", &value);
289                                 g_variant_iter_free(iter_sub);
290
291                                 DBG("Proxy - [%s]", value);
292                                 vconf_set_str(VCONFKEY_NETWORK_PROXY, value);
293
294                                 g_free(property);
295                                 g_variant_unref(var);
296                                 break;
297                         } else if (g_strcmp0(property, "Method") == 0) {
298                                 value = g_variant_get_string(var, NULL);
299                                 DBG("Method - [%s]", value);
300
301                                 if (g_strcmp0(value, "direct") == 0)
302                                         vconf_set_str(VCONFKEY_NETWORK_PROXY, "");
303
304                                 g_free(property);
305                                 g_variant_unref(var);
306                                 break;
307                         }
308                 }
309
310                 g_variant_iter_free(iter);
311         } else if (g_strcmp0(sigvalue, "Error") == 0) {
312                 g_variant_get(variant, "s", &property);
313                 INFO("[%s] Property : %s", sigvalue, property);
314                 g_free(property);
315         }
316 done:
317         if (sigvalue)
318                 g_free(sigvalue);
319
320         if (variant)
321                 g_variant_unref(variant);
322
323         return;
324 }
325
326 static void _dbus_name_changed_cb(GDBusConnection *conn,
327                 const gchar *Name, const gchar *path, const gchar *interface,
328                 const gchar *sig, GVariant *param, gpointer user_data)
329 {
330         gchar *name = NULL;
331         gchar *old = NULL;
332         gchar *new = NULL;
333
334         if (param == NULL)
335                 return;
336
337         g_variant_get(param, "(sss)", &name, &old, &new);
338
339         if (g_strcmp0(name, CONNMAN_SERVICE) == 0 && *new == '\0') {
340                 DBG("ConnMan destroyed: name %s, old %s, new %s", name, old, new);
341
342                 connman_register_agent();
343         }
344         if (name)
345                 g_free(name);
346         if (old)
347                 g_free(old);
348         if (new)
349                 g_free(new);
350
351         return;
352 }
353
354 static void _services_changed_cb(GDBusConnection *conn, const gchar *name,
355                 const gchar *path, const gchar *interface, const gchar *sig,
356                 GVariant *param, gpointer user_data)
357 {
358         gchar *property, *value;
359         gchar *service_path;
360         GVariant *variant = NULL;
361         GVariantIter *added = NULL, *removed = NULL, *next = NULL;
362
363         if (path == NULL || param == NULL)
364                 return;
365
366         if (g_strcmp0(sig, CONNMAN_SIGNAL_SERVICES_CHANGED) != 0)
367                 return;
368
369         if (netconfig_get_default_profile() != NULL)
370                 return;
371
372         g_variant_get(param, "(a(oa{sv})ao)", &added, &removed);
373
374         while (g_variant_iter_loop(added, "(oa{sv})", &service_path, &next)) {
375                 gboolean is_wifi_prof, is_cell_prof, is_cell_internet_prof;
376                 is_wifi_prof = netconfig_is_wifi_profile(service_path);
377                 is_cell_prof = netconfig_is_cellular_profile(service_path);
378                 is_cell_internet_prof = netconfig_is_cellular_internet_profile(
379                                 service_path);
380                 if (service_path != NULL) {
381                         while (g_variant_iter_loop(next, "{sv}", &property,
382                                                 &variant)) {
383                                 if (g_strcmp0(property, "State") == 0) {
384                                         g_variant_get(variant, "s", &value);
385                                         DBG("Profile %s State %s", service_path,
386                                                         value);
387                                         if (g_strcmp0(value, "ready") != 0 &&
388                                                         g_strcmp0(value,
389                                                                 "online") != 0) {
390                                                 g_free(property);
391                                                 g_free(value);
392                                                 g_variant_unref(variant);
393                                                 break;
394                                         }
395
396                                         if (!is_cell_prof)
397                                                 netconfig_update_default_profile(
398                                                                 service_path);
399                                         else if (is_cell_internet_prof) {
400                                                 netconfig_update_default_profile(
401                                                                 service_path);
402                                         }
403                                         if (is_wifi_prof)
404                                                 wifi_state_set_service_state(
405                                                         NETCONFIG_WIFI_CONNECTED);
406                                         else if (is_cell_prof &&
407                                                         is_cell_internet_prof)
408                                                 cellular_state_set_service_state(
409                                                         NETCONFIG_CELLULAR_ONLINE);
410                                         g_free(property);
411                                         g_free(value);
412                                         g_variant_unref(variant);
413                                         break;
414                                 }
415                         }
416                 }
417         }
418
419         g_variant_iter_free(added);
420
421         if (next)
422                 g_variant_iter_free(next);
423
424         if (removed)
425                 g_variant_iter_free(removed);
426
427         return;
428 }
429
430 static void _supplicant_interface_removed(GDBusConnection *conn,
431                 const gchar *name, const gchar *path, const gchar *interface,
432                 const gchar *sig, GVariant *param, gpointer user_data)
433 {
434         DBG("Interface removed handling!");
435         if (netconfig_wifi_is_wps_enabled() == TRUE)
436                 netconfig_wifi_wps_signal_scanaborted();
437
438         return;
439 }
440
441 static void _supplicant_properties_changed(GDBusConnection *conn,
442                 const gchar *name, const gchar *path, const gchar *interface,
443                 const gchar *sig, GVariant *param, gpointer user_data)
444 {
445         DBG("Properties changed handling!");
446         gchar *key;
447         GVariantIter *iter;
448         GVariant *variant;
449         gboolean scanning = FALSE;
450
451         if (param == NULL)
452                 return;
453
454         g_variant_get(param, "(a{sv})", &iter);
455         while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
456                 if (g_strcmp0(key, "Scanning") == 0) {
457                         scanning = g_variant_get_boolean(variant);
458                         if (scanning == TRUE)
459                                 netconfig_wifi_set_scanning(TRUE);
460
461                         g_variant_unref(variant);
462                         g_free(key);
463                         break;
464                 }
465         }
466
467         g_variant_iter_free(iter);
468
469         return;
470 }
471
472 static void _supplicant_bss_added(GDBusConnection *conn,
473                 const gchar *name, const gchar *path, const gchar *interface,
474                 const gchar *sig, GVariant *param, gpointer user_data)
475 {
476         DBG("BSS added handling!");
477         if (wifi_ssid_scan_get_state() == TRUE)
478                 wifi_ssid_scan_add_bss(param);
479         else
480                 wifi_state_set_bss_found(TRUE);
481
482         return;
483 }
484
485 static void _supplicant_scan_done(GDBusConnection *conn,
486                 const gchar *name, const gchar *path, const gchar *interface,
487                 const gchar *sig, GVariant *param, gpointer user_data)
488 {
489         DBG("Scan Done handling!");
490         netconfig_wifi_set_scanning(FALSE);
491
492         if (netconfig_wifi_is_wps_enabled() == TRUE) {
493                 netconfig_wifi_wps_signal_scandone();
494                 if (wifi_state_get_technology_state() < NETCONFIG_WIFI_TECH_POWERED)
495                         return;
496         }
497
498         if (netconfig_wifi_get_bgscan_state() != TRUE) {
499                 if (wifi_ssid_scan_get_state() == TRUE)
500                         wifi_ssid_scan_emit_scan_completed();
501                 else
502                         wifi_ssid_scan(NULL);
503         } else {
504                 if (wifi_state_get_technology_state() >=
505                                 NETCONFIG_WIFI_TECH_POWERED)
506                         netconfig_wifi_bgscan_start(FALSE);
507
508                 wifi_start_timer_network_notification();
509         }
510
511         return;
512 }
513
514 static void _supplicant_driver_hanged(GDBusConnection *conn,
515                 const gchar *name, const gchar *path, const gchar *interface,
516                 const gchar *sig, GVariant *param, gpointer user_data)
517 {
518         DBG("Driver Hanged handling!");
519         ERR("Critical. Wi-Fi firmware crashed");
520
521         wifi_power_recover_firmware();
522
523         return;
524 }
525
526 static void _supplicant_session_overlapped(GDBusConnection *conn,
527                 const gchar *name, const gchar *path, const gchar *interface,
528                 const gchar *sig, GVariant *param, gpointer user_data)
529 {
530         DBG("Driver session overlapped handling!");
531         ERR("WPS PBC SESSION OVERLAPPED");
532 #if defined TIZEN_WEARABLE
533         return;
534 #else
535         netconfig_send_message_to_net_popup("WPS Error",
536                                         "wps session overlapped", "popup", NULL);
537 #endif
538 }
539
540 static void _supplicant_tdls_connected(GDBusConnection *conn,
541                 const gchar *name, const gchar *path, const gchar *interface,
542                 const gchar *sig, GVariant *param, gpointer user_data)
543 {
544         ERR("Received TDLS Connected Signal");
545         netconfig_wifi_tlds_connected_event(param);
546
547         return;
548 }
549
550 static void _supplicant_tdls_disconnected(GDBusConnection *conn,
551                 const gchar *name, const gchar *path, const gchar *interface,
552                 const gchar *sig, GVariant *param, gpointer user_data)
553 {
554         ERR("Received TDLS Disconnected Signal");
555         netconfig_wifi_tlds_disconnected_event(param);
556
557         return;
558 }
559
560 static void _supplicant_tdls_peer_found(GDBusConnection *conn,
561                 const gchar *name, const gchar *path, const gchar *interface,
562                 const gchar *sig, GVariant *param, gpointer user_data)
563 {
564         ERR("Received TDLS Peer Found Signal");
565         return;
566 }
567
568 static void _supplicant_wifi_wps_connected(GVariant *param)
569 {
570         gchar *key;
571         char ssid[32] = {0, };
572         gchar *name;
573         GVariantIter *iter;
574         GVariant *variant;
575         int config_error = 0;
576         int error_indication = 0;
577         gsize ssid_len = 0;
578
579         if (param == NULL) {
580                 ERR("Param is NULL");
581                 return;
582         }
583
584         g_variant_get(param, "(sa{sv})", &name, &iter);
585         INFO("wps Result: %s", name);
586         while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
587                 INFO("wps Key is %s", key);
588                 if (g_strcmp0(key, "SSID") == 0) {
589                         const char *t_key = NULL;
590                         t_key = g_variant_get_fixed_array(variant, &ssid_len, sizeof(guchar));
591                         INFO("wps ssid_len is %d ", ssid_len);
592                         if (t_key == NULL) {
593                                 g_free(key);
594                                 g_variant_unref(variant);
595                                 ERR("WPS PBC Connection Failed");
596                                 goto error;
597                         }
598                         if (ssid_len > 0 && ssid_len <= 32) {
599                                 memcpy(ssid, t_key, ssid_len);
600                         } else {
601                                 memset(ssid, 0, sizeof(ssid));
602                                 ssid_len = 0;
603                         }
604                         INFO("WPS PBC Connection completed with AP %s", ssid);
605                         netconfig_wifi_notify_wps_completed(ssid, ssid_len);
606                 }
607         }
608
609         g_variant_iter_free(iter);
610         g_free(name);
611         return;
612
613 error:
614         g_variant_iter_free(iter);
615         g_free(name);
616         error_indication = WPS_EI_OPERATION_FAILED;
617         config_error = WPS_CFG_NO_ERROR;
618         ERR("Error Occured! Notifying Fail Event");
619         netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
620
621 }
622
623 static void _supplicant_wifi_wps_event(GVariant *param)
624 {
625         gchar *key;
626         gchar *name;
627         GVariantIter *iter;
628         GVariant *variant;
629         gint32 config_error = 0;
630         gint32 error_indication = 0;
631
632         if (param == NULL) {
633                 ERR("Param is NULL");
634                 return;
635         }
636
637         g_variant_get(param, "(sa{sv})", &name, &iter);
638         INFO("Event Result: %s", name);
639         if (g_strcmp0(name, "failed") == 0) {
640                 while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
641                         if (key == NULL)
642                                 goto error;
643                         INFO("Key is %s", key);
644                         if (g_strcmp0(key, "config_error") == 0) {
645                                 config_error = g_variant_get_int32(variant);
646                                 ERR("Config Error %d", config_error);
647                         } else if (g_strcmp0(key, "error_indication") == 0) {
648                                 error_indication = g_variant_get_int32(variant);
649                                 ERR("Error Indication %d", error_indication);
650                         }
651                 }
652                 netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
653         }
654
655         g_variant_iter_free(iter);
656         g_free(name);
657         return;
658
659 error:
660         g_variant_iter_free(iter);
661         g_free(name);
662         error_indication = WPS_EI_OPERATION_FAILED;
663         config_error = WPS_CFG_NO_ERROR;
664         ERR("Error Occured! Notifying Fail Event");
665         netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
666 }
667
668 static void _supplicant_wifi_wps_credentials(GVariant *param)
669 {
670         gchar *key;
671         char ssid[32];
672         char wps_key[100];
673         GVariantIter *iter;
674         GVariant *variant;
675         int config_error = 0;
676         int error_indication = 0;
677         gsize ssid_len = 0;
678
679         if (param == NULL) {
680                 ERR("Param is NULL");
681                 return;
682         }
683
684         g_variant_get(param, "(a{sv})", &iter);
685         while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
686                 if (key == NULL)
687                         goto error;
688                 INFO("wps Key is %s", key);
689                 if (g_strcmp0(key, "Key") == 0) {
690                         gsize key_len = 0;
691                         const char *t_key = NULL;
692                         key_len = g_variant_get_size(variant);
693
694                         INFO("wps password len %d ", key_len);
695                         if (key_len > 0) {
696                                 t_key = g_variant_get_fixed_array(variant, &key_len, sizeof(guchar));
697                                 if (!t_key) {
698                                         g_free(key);
699                                         g_variant_unref(variant);
700                                         goto error;
701                                 }
702                                 strncpy(wps_key, t_key, key_len);
703                                 wps_key[key_len] = '\0';
704                                 INFO("WPS Key in process credentials %s", wps_key);
705                         } else
706                                 SLOGI("WPS AP Security ->Open");
707                 } else if (g_strcmp0(key, "SSID") == 0) {
708                         const char *t_key = NULL;
709                         t_key = g_variant_get_fixed_array(variant, &ssid_len, sizeof(guchar));
710                         INFO("wps ssid_len is %d ", ssid_len);
711                         if (!t_key) {
712                                 g_free(key);
713                                 g_variant_unref(variant);
714                                 goto error;
715                         }
716                         if (ssid_len > 0 && ssid_len <= 32) {
717                                 memcpy(ssid, t_key, ssid_len);
718                         } else {
719                                 memset(ssid, 0, sizeof(ssid));
720                                 ssid_len = 0;
721                         }
722                         INFO("SSID in process credentials %s", ssid);
723                 }
724         }
725
726         g_variant_iter_free(iter);
727
728 #if 0
729         /*
730          * Notify WPS Credentials only when requested through WPS PBC
731          * In case of WPS PIN connman will take care of notification
732          */
733         if (netconfig_get_wps_field() == TRUE)
734 #endif
735         netconfig_wifi_notify_wps_credentials(ssid, ssid_len, wps_key);
736         return;
737
738 error:
739         g_variant_iter_free(iter);
740         error_indication = WPS_EI_OPERATION_FAILED;
741         config_error = WPS_CFG_NO_ERROR;
742         ERR("Error Occured! Notifying Fail Event");
743         netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
744 }
745
746 static void __netconfig_wps_signal_filter_handler(GDBusConnection *conn,
747                 const gchar *name, const gchar *path, const gchar *interface,
748                 const gchar *sig, GVariant *param, gpointer user_data)
749 {
750         if (g_strcmp0(sig, SIGNAL_WPS_CREDENTIALS) == 0) {
751                 INFO("Received wps CREDENTIALS Signal from Supplicant");
752                 _supplicant_wifi_wps_credentials(param);
753         } else if (g_strcmp0(sig, SIGNAL_WPS_EVENT) == 0) {
754                 INFO("Received wps EVENT Signal from Supplicant");
755                 _supplicant_wifi_wps_event(param);
756         } else if (g_strcmp0(sig, SIGNAL_WPS_CONNECTED) == 0) {
757                 INFO("Received WPSConnected Signal from Supplicant");
758                 _supplicant_wifi_wps_connected(param);
759         }
760
761         return;
762 }
763
764 static supplicant_signal_cb supplicant_cbs[SIG_MAX] = {
765                 _supplicant_interface_removed,
766                 _supplicant_properties_changed,
767                 _supplicant_bss_added,
768                 _supplicant_scan_done,
769                 _supplicant_driver_hanged,
770                 _supplicant_session_overlapped,
771                 _supplicant_tdls_connected,
772                 _supplicant_tdls_disconnected,
773                 _supplicant_tdls_peer_found
774 };
775
776 void register_gdbus_signal(void)
777 {
778         GDBusConnection *connection = NULL;
779         const char *interface = NULL;
780         SuppSigArrayIndex sig;
781         connection = netdbus_get_connection();
782
783         if (connection == NULL) {
784                 ERR("Failed to get GDbus Connection");
785                 return;
786         }
787
788         /* listening to messages from all objects as no path is specified */
789         /* see signals from the given interface */
790         conn_subscription_ids[0] = g_dbus_connection_signal_subscribe(
791                         connection,
792                         CONNMAN_SERVICE,
793                         CONNMAN_TECHNOLOGY_INTERFACE,
794                         NULL,
795                         NULL,
796                         NULL,
797                         G_DBUS_SIGNAL_FLAGS_NONE,
798                         _technology_signal_cb,
799                         NULL,
800                         NULL);
801
802         conn_subscription_ids[1] = g_dbus_connection_signal_subscribe(
803                         connection,
804                         CONNMAN_SERVICE,
805                         CONNMAN_SERVICE_INTERFACE,
806                         CONNMAN_SIGNAL_PROPERTY_CHANGED,
807                         NULL,
808                         NULL,
809                         G_DBUS_SIGNAL_FLAGS_NONE,
810                         _service_signal_cb,
811                         NULL,
812                         NULL);
813
814         conn_subscription_ids[2] = g_dbus_connection_signal_subscribe(
815                         connection,
816                         DBUS_SERVICE_DBUS,
817                         DBUS_INTERFACE_DBUS,
818                         CONNMAN_SIGNAL_NAME_CHANGED,
819                         NULL,
820                         CONNMAN_SERVICE,
821                         G_DBUS_SIGNAL_FLAGS_NONE,
822                         _dbus_name_changed_cb,
823                         NULL,
824                         NULL);
825
826         conn_subscription_ids[3] = g_dbus_connection_signal_subscribe(
827                         connection,
828                         CONNMAN_SERVICE,
829                         CONNMAN_MANAGER_INTERFACE,
830                         CONNMAN_SIGNAL_SERVICES_CHANGED,
831                         NULL,
832                         NULL,
833                         G_DBUS_SIGNAL_FLAGS_NONE,
834                         _services_changed_cb,
835                         NULL,
836                         NULL);
837
838         INFO("Successfully register connman DBus signal filters");
839
840         conn_subscription_ids[4] = g_dbus_connection_signal_subscribe(
841                         connection,
842                         SUPPLICANT_SERVICE,
843                         SUPPLICANT_INTERFACE ".Interface.WPS",
844                         NULL,
845                         NULL,
846                         NULL,
847                         G_DBUS_SIGNAL_FLAGS_NONE,
848                         __netconfig_wps_signal_filter_handler,
849                         NULL,
850                         NULL);
851
852         INFO("Successfully register Supplicant WPS DBus signal filters");
853
854         for (sig = SIG_INTERFACE_REMOVED; sig < SIG_MAX; sig++) {
855                 /*
856                  * For SIG_INTERFACE_REMOVED INTERFACE_ADDED
857                  */
858                 interface = (sig == SIG_INTERFACE_REMOVED) ?
859                                 SUPPLICANT_INTERFACE : SUPPLICANT_IFACE_INTERFACE;
860
861                 supp_subscription_ids[sig] = g_dbus_connection_signal_subscribe(
862                                 connection,
863                                 SUPPLICANT_SERVICE,
864                                 interface,
865                                 supplicant_signals[sig],
866                                 NULL,
867                                 NULL,
868                                 G_DBUS_SIGNAL_FLAGS_NONE,
869                                 supplicant_cbs[sig],
870                                 NULL,
871                                 NULL);
872         }
873
874         INFO("Successfully register Supplicant DBus signal filters");
875
876         /* In case ConnMan precedes this signal register,
877          * net-config should update the default connected profile.
878          */
879         netconfig_update_default();
880 }
881
882 void deregister_gdbus_signal(void)
883 {
884         GDBusConnection *connection = NULL;
885         int signal;
886         SuppSigArrayIndex sig;
887         connection = netdbus_get_connection();
888         if (!connection) {
889                 ERR("Already de-registered. Nothing to be done");
890                 return;
891         }
892
893         for (signal = 0; signal < TOTAL_CONN_SIGNALS; signal++) {
894                 if (conn_subscription_ids[signal]) {
895                         g_dbus_connection_signal_unsubscribe(connection,
896                                                 conn_subscription_ids[signal]);
897                 }
898         }
899
900         for (sig = SIG_INTERFACE_REMOVED; sig < SIG_MAX; sig++) {
901                 if (supp_subscription_ids[sig]) {
902                         g_dbus_connection_signal_unsubscribe(connection,
903                                                 supp_subscription_ids[sig]);
904                 }
905         }
906
907 }