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