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