Merge "Revise background scan routine" into tizen
[platform/core/connectivity/net-config.git] / src / wifi-state.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 <vconf.h>
21 #include <vconf-keys.h>
22
23 #include "log.h"
24 #include "util.h"
25 #include "netdbus.h"
26 #include "wifi-state.h"
27 #include "wifi-power.h"
28 #include "netsupplicant.h"
29 #include "network-state.h"
30 #include "wifi-indicator.h"
31 #include "network-statistics.h"
32 #include "wifi-background-scan.h"
33
34 #define NETCONFIG_NETWORK_NOTIFICATION_TIMEOUT  15 * 1000
35
36 static gboolean new_bss_found = FALSE;
37 static guint network_noti_timer_id = 0;
38
39 static wifi_service_state_e g_service_state = NETCONFIG_WIFI_UNKNOWN;
40 static wifi_tech_state_e g_tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
41
42 static GSList *notifier_list = NULL;
43
44 static guint network_connected_popup_timer_id = 0;
45 static gboolean block_network_connected_popup = FALSE;
46
47 char *_convert_wifi_service_state_to_string(wifi_service_state_e wifi_service_state_type)
48 {
49         switch (wifi_service_state_type) {
50         case NETCONFIG_WIFI_UNKNOWN:
51                 return "unknown";
52         case NETCONFIG_WIFI_IDLE:
53                 return "idle";
54         case NETCONFIG_WIFI_ASSOCIATION:
55                 return "association";
56         case NETCONFIG_WIFI_CONFIGURATION:
57                 return "configuration";
58         case NETCONFIG_WIFI_CONNECTED:
59                 return "connected";
60         case NETCONFIG_WIFI_FAILURE:
61                 return "failure";
62         default:
63                 ERR("Invalid wifi_service_state_e parameter");
64                 break;
65         }
66
67         return "Invalid parameter";
68 }
69
70 char *_convert_wifi_technology_state_to_string(wifi_tech_state_e wifi_tech_state_type)
71 {
72         switch (wifi_tech_state_type) {
73         case NETCONFIG_WIFI_TECH_UNKNOWN:
74                 return "unknown";
75         case NETCONFIG_WIFI_TECH_OFF:
76                 return "off";
77         case NETCONFIG_WIFI_TECH_WPS_ONLY:
78                 return "wps only";
79         case NETCONFIG_WIFI_TECH_POWERED:
80                 return "powered";
81         case NETCONFIG_WIFI_TECH_CONNECTED:
82                 return "connected";
83         case NETCONFIG_WIFI_TECH_TETHERED:
84                 return "tethered";
85         default:
86                 ERR("Invalid wifi_tech_state_e parameter");
87                 break;
88         }
89
90         return "Invalid parameter";
91 }
92
93 static gboolean _block_network_connection_popup(gpointer data)
94 {
95         block_network_connected_popup = FALSE;
96         netconfig_stop_timer(&network_connected_popup_timer_id);
97         return FALSE;
98 }
99
100 static void __set_wifi_connected_essid(void)
101 {
102         const char *essid_name = NULL;
103         const char *wifi_profile = netconfig_get_default_profile();
104
105         if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
106                 return;
107
108         if (wifi_profile == NULL ||
109                         netconfig_is_wifi_profile(wifi_profile) != TRUE) {
110                 ERR("Can't get Wi-Fi profile");
111                 return;
112         }
113
114         essid_name = netconfig_wifi_get_connected_essid(wifi_profile);
115         if (essid_name == NULL) {
116                 ERR("Can't get Wi-Fi name");
117                 return;
118         }
119
120         netconfig_set_vconf_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, essid_name);
121
122         /* Block Network Connected popup for 3sec
123          * to avoid multiple popup's due to ready signals */
124         if (block_network_connected_popup == FALSE) {
125                 block_network_connected_popup = TRUE;
126                 netconfig_start_timer(3000, _block_network_connection_popup,
127                                 NULL, &network_connected_popup_timer_id);
128                 __netconfig_pop_wifi_connected_poppup(essid_name);
129         }
130 }
131
132 static void __unset_wifi_connected_essid(void)
133 {
134         netconfig_set_vconf_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, "");
135 }
136
137 static const char *__get_wifi_connected_essid(void)
138 {
139         const char *essid_name = NULL;
140         const char *wifi_profile = NULL;
141
142         if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
143                 return NULL;
144
145         wifi_profile = netconfig_get_default_profile();
146
147         if (wifi_profile == NULL || netconfig_is_wifi_profile(wifi_profile) != TRUE) {
148                 ERR("Can't get Wi-Fi profile");
149                 return NULL;
150         }
151
152         essid_name = netconfig_wifi_get_connected_essid(wifi_profile);
153         if (essid_name == NULL) {
154                 ERR("Can't get Wi-Fi name");
155                 return NULL;
156         }
157
158         return essid_name;
159 }
160
161 static gboolean __is_wifi_profile_available(void)
162 {
163         GVariant *message = NULL;
164         GVariantIter *iter, *next;
165         gchar *obj;
166
167         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
168                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
169                         "GetServices", NULL);
170         if (message == NULL) {
171                 ERR("Failed to get service list");
172                 return FALSE;
173         }
174
175         g_variant_get(message, "(a(oa{sv}))", &iter);
176         while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
177                 if (obj == NULL || netconfig_is_wifi_profile((const gchar*)obj) == FALSE)
178                         continue;
179
180                 g_variant_iter_free(next);
181                 g_free(obj);
182                 break;
183         }
184
185         g_variant_unref(message);
186
187         g_variant_iter_free(iter);
188
189         return TRUE;
190 }
191
192 static gboolean __is_favorited(GVariantIter *array)
193 {
194         gboolean is_favorite = FALSE;
195         gchar *key;
196         GVariant *var;
197
198         while (g_variant_iter_loop(array, "{sv}", &key, &var)) {
199                 gboolean value;
200
201                 if (g_str_equal(key, "Favorite") != TRUE)
202                         continue;
203
204                 value = g_variant_get_boolean(var);
205                 if (value)
206                         is_favorite = TRUE;
207                 g_free(key);
208                 g_variant_unref(var);
209                 break;
210         }
211
212         return is_favorite;
213 }
214
215 static void _wifi_state_connected_activation(void)
216 {
217         /* Add activation of services when Wi-Fi is connected */
218 }
219
220 static void _wifi_state_changed(wifi_service_state_e state)
221 {
222         GSList *list;
223
224         for (list = notifier_list; list; list = list->next) {
225                 wifi_state_notifier *notifier = list->data;
226
227                 if (notifier->wifi_state_changed != NULL)
228                         notifier->wifi_state_changed(state, notifier->user_data);
229         }
230 }
231
232 static void _set_bss_found(gboolean found)
233 {
234         if (found != new_bss_found)
235                 new_bss_found = found;
236 }
237
238 static gboolean _check_network_notification(gpointer data)
239 {
240         int qs_enable = 0, ug_state = 0;
241         static gboolean check_again = FALSE;
242
243         wifi_tech_state_e tech_state;
244         wifi_service_state_e service_state;
245
246         tech_state = wifi_state_get_technology_state();
247         if (tech_state < NETCONFIG_WIFI_TECH_POWERED) {
248                 DBG("Wi-Fi off or WPS only supported[%d]", tech_state);
249                 goto cleanup;
250         }
251
252         service_state = wifi_state_get_service_state();
253         if (service_state == NETCONFIG_WIFI_CONNECTED) {
254                 DBG("Service state is connected");
255                 goto cleanup;
256         } else if (service_state == NETCONFIG_WIFI_ASSOCIATION ||
257                 service_state == NETCONFIG_WIFI_CONFIGURATION) {
258                 DBG("Service state is connecting (check again : %d)", check_again);
259                 if (!check_again) {
260                         check_again = TRUE;
261                         return TRUE;
262                 } else
263                         check_again = FALSE;
264         }
265
266         if (__is_wifi_profile_available() == FALSE) {
267                 netconfig_send_notification_to_net_popup(
268                 NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
269                 goto cleanup;
270         }
271
272         netconfig_vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &qs_enable);
273         if (qs_enable != VCONFKEY_WIFI_QS_ENABLE) {
274                 DBG("qs_enable != VCONFKEY_WIFI_QS_ENABLE");
275                 goto cleanup;
276         }
277
278         netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state);
279         if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
280                 goto cleanup;
281
282         netconfig_send_notification_to_net_popup(NETCONFIG_ADD_FOUND_AP_NOTI, NULL);
283
284         _set_bss_found(FALSE);
285
286 cleanup:
287         netconfig_stop_timer(&network_noti_timer_id);
288         return FALSE;
289 }
290
291 static char *_get_connman_favorite_service(void)
292 {
293         char *favorite_service = NULL;
294         GVariant *message = NULL;
295         gchar *obj;
296         GVariantIter *iter, *next;
297
298         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
299                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
300                         "GetServices", NULL);
301         if (message == NULL) {
302                 ERR("Failed to get service list");
303                 return NULL;
304         }
305
306         g_variant_get(message, "(a(oa{sv}))", &iter);
307         while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
308                 if (obj == NULL || netconfig_is_wifi_profile(obj) == FALSE)
309                         continue;
310
311                 if (__is_favorited(next) == TRUE) {
312                         favorite_service = g_strdup(obj);
313                         g_free(obj);
314                         g_variant_iter_free(next);
315                         break;
316                 }
317         }
318
319         g_variant_iter_free(iter);
320         g_variant_unref(message);
321
322         return favorite_service;
323 }
324
325 static void __notification_value_changed_cb(keynode_t *node, void *user_data)
326 {
327         int value = -1;
328
329         if (netconfig_vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &value) < 0)
330                 return;
331
332         if (value == VCONFKEY_WIFI_QS_DISABLE)
333                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
334 }
335
336 static void _register_network_notification(void)
337 {
338 #if defined TIZEN_WEARABLE
339         return;
340 #endif
341         vconf_notify_key_changed(VCONFKEY_WIFI_ENABLE_QS, __notification_value_changed_cb, NULL);
342 }
343
344 static void _deregister_network_notification(void)
345 {
346 #if defined TIZEN_WEARABLE
347                 return;
348 #endif
349         vconf_ignore_key_changed(VCONFKEY_WIFI_ENABLE_QS, __notification_value_changed_cb);
350 }
351
352 static void _set_power_save(gboolean power_save)
353 {
354         gboolean result;
355         char *if_path;
356         GVariant *input_args = NULL;
357         static gboolean old_state = TRUE;
358         const gchar *args_disable = "POWERMODE 1";
359         const gchar *args_enable = "POWERMODE 0";
360         if (old_state == power_save)
361                 return;
362
363         if_path = netconfig_wifi_get_supplicant_interface();
364         if (if_path == NULL) {
365                 ERR("Fail to get wpa_supplicant DBus path");
366                 return;
367         }
368
369         if (power_save)
370                 input_args = g_variant_new("(s)", args_enable);
371         else
372                 input_args = g_variant_new("(s)", args_disable);
373
374         result = netconfig_supplicant_invoke_dbus_method_nonblock(
375                         SUPPLICANT_SERVICE,
376                         if_path,
377                         SUPPLICANT_INTERFACE ".Interface",
378                         "Driver",
379                         input_args,
380                         NULL);
381         if (result == FALSE)
382                 ERR("Fail to set power save mode POWERMODE %d", power_save);
383         else
384                 old_state = power_save;
385
386         g_free(if_path);
387
388         return;
389 }
390
391 static void _set_power_lock(gboolean power_lock)
392 {
393         gint32 ret = 0;
394         GVariant *reply;
395         GVariant *params;
396         char state[] = "lcdoff";
397         char flag[] = "staycurstate";
398         char standby[] = "NULL";
399         int timeout = 0;
400         char sleepmargin[] = "sleepmargin";
401
402         const char *lockstate = "lockstate";
403         const char *unlockstate = "unlockstate";
404         static gboolean old_state = FALSE;
405         const char *lock_method;
406
407         if (old_state == power_lock)
408                 return;
409
410         if (power_lock == TRUE) {
411                 /* deviced power lock enable */
412                 params = g_variant_new("(sssi)", state, flag, standby, timeout);
413
414                 lock_method = lockstate;
415         } else {
416                 /* deviced power lock disable */
417                 params = g_variant_new("(ss)", state, sleepmargin);
418
419                 lock_method = unlockstate;
420         }
421
422         reply = netconfig_invoke_dbus_method(
423                         "org.tizen.system.deviced",
424                         "/Org/Tizen/System/DeviceD/Display",
425                         "org.tizen.system.deviced.display",
426                         lock_method,
427                         params);
428         if (reply == NULL) {
429                 ERR("Failed to set_power_lock");
430                 return;
431         }
432
433         if (g_variant_is_of_type(reply, G_VARIANT_TYPE_INT32)) {
434                 ret = g_variant_get_int32(reply);
435                 if (ret < 0)
436                         ERR("Failed to set power lock %s with ret %d",
437                                 power_lock == TRUE ? "enable" : "disable", ret);
438                 else
439                         old_state = power_lock;
440         }
441
442         g_variant_unref(reply);
443
444         return;
445 }
446
447 void wifi_state_emit_power_completed(gboolean power_on)
448 {
449         if (power_on)
450                 wifi_emit_power_on_completed((Wifi *)get_wifi_object());
451         else
452                 wifi_emit_power_off_completed((Wifi *)get_wifi_object());
453
454         DBG("Successfully sent signal [%s]", (power_on) ? "powerOn" : "powerOff");
455 }
456
457 void wifi_state_emit_power_failed(void)
458 {
459         wifi_emit_power_operation_failed((Wifi *)get_wifi_object());
460
461         DBG("Successfully sent signal [PowerOperationFailed]");
462 }
463
464 void wifi_state_update_power_state(gboolean powered)
465 {
466         wifi_tech_state_e tech_state;
467
468         /* It's automatically updated by signal-handler
469          * DO NOT update manually
470          * It includes Wi-Fi state configuration
471          */
472         tech_state = wifi_state_get_technology_state();
473
474         if (powered == TRUE) {
475                 if (tech_state < NETCONFIG_WIFI_TECH_POWERED && netconfig_is_wifi_tethering_on() != TRUE) {
476                         DBG("Wi-Fi turned on or waken up from power-save mode");
477
478                         wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_POWERED);
479
480                         wifi_state_emit_power_completed(TRUE);
481
482                         netconfig_wifi_device_picker_service_start();
483
484                         netconfig_set_vconf_int(VCONF_WIFI_LAST_POWER_STATE, VCONFKEY_WIFI_UNCONNECTED);
485                         netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
486                         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
487
488                         netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_ON);
489
490                         netconfig_wifi_bgscan_stop();
491                         netconfig_wifi_bgscan_set_interval(SCAN_EXPONENTIAL_MIN);
492                         netconfig_wifi_bgscan_start(TRUE);
493
494                         /* Add callback to track change in notification setting */
495                         _register_network_notification();
496                 }
497         } else if (tech_state > NETCONFIG_WIFI_TECH_OFF) {
498                 DBG("Wi-Fi turned off or in power-save mode");
499
500                 wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_WPS_ONLY);
501
502                 netconfig_wifi_device_picker_service_stop();
503
504                 wifi_power_disable_technology_state_by_only_connman_signal();
505                 wifi_power_driver_and_supplicant(FALSE);
506
507                 wifi_state_emit_power_completed(FALSE);
508
509                 netconfig_set_vconf_int(VCONF_WIFI_LAST_POWER_STATE, VCONFKEY_WIFI_OFF);
510                 netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF);
511                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF);
512
513                 netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_OFF);
514
515                 netconfig_wifi_bgscan_stop();
516
517                 _set_bss_found(FALSE);
518
519                 /* Inform net-popup to remove the wifi found notification */
520                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
521                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_PORTAL_NOTI, NULL);
522
523                 _deregister_network_notification();
524         }
525 }
526
527 char *wifi_get_favorite_service(void)
528 {
529         return _get_connman_favorite_service();
530 }
531
532 void wifi_start_timer_network_notification(void)
533 {
534 #if defined TIZEN_WEARABLE
535                 /* In case of wearable device, no need to notify available Wi-Fi APs */
536                 return ;
537 #endif
538         netconfig_start_timer(NETCONFIG_NETWORK_NOTIFICATION_TIMEOUT, _check_network_notification, NULL, &network_noti_timer_id);
539 }
540
541 void wifi_state_notifier_register(wifi_state_notifier *notifier)
542 {
543         DBG("register notifier");
544
545         notifier_list = g_slist_append(notifier_list, notifier);
546 }
547
548 void wifi_state_notifier_unregister(wifi_state_notifier *notifier)
549 {
550         DBG("un-register notifier");
551
552         notifier_list = g_slist_remove_all(notifier_list, notifier);
553 }
554
555 void wifi_state_notifier_cleanup(void)
556 {
557         g_slist_free_full(notifier_list, NULL);
558 }
559
560 void wifi_state_set_bss_found(gboolean found)
561 {
562         _set_bss_found(found);
563 }
564
565 gboolean wifi_state_is_bss_found(void)
566 {
567         return new_bss_found;
568 }
569
570 void wifi_state_set_service_state(wifi_service_state_e new_state)
571 {
572         static gboolean dhcp_stage = FALSE;
573         wifi_service_state_e old_state = g_service_state;
574
575         if (old_state == new_state)
576                 return;
577
578         g_service_state = new_state;
579         DBG("Wi-Fi service state, old state[%s] ==> new state[%s]",
580                 _convert_wifi_service_state_to_string(old_state), _convert_wifi_service_state_to_string(new_state));
581
582         /* During DHCP, temporarily disable Wi-Fi power saving */
583         if ((old_state < NETCONFIG_WIFI_ASSOCIATION || old_state == NETCONFIG_WIFI_FAILURE) && new_state == NETCONFIG_WIFI_CONFIGURATION) {
584                 _set_power_lock(TRUE);
585                 _set_power_save(FALSE);
586                 dhcp_stage = TRUE;
587         } else if (dhcp_stage == TRUE) {
588                 _set_power_lock(FALSE);
589                 _set_power_save(TRUE);
590                 dhcp_stage = FALSE;
591         }
592
593         if (new_state == NETCONFIG_WIFI_CONNECTED) {
594                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
595
596                 netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_CONNECTED);
597                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_CONNECTED);
598
599                 netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_CONNECTED);
600
601                 __set_wifi_connected_essid();
602
603                 netconfig_wifi_indicator_start();
604         } else if (old_state == NETCONFIG_WIFI_CONNECTED) {
605                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_PORTAL_NOTI, NULL);
606
607                 __unset_wifi_connected_essid();
608
609                 netconfig_set_vconf_int (VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
610                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
611
612                 netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_ON);
613
614                 netconfig_wifi_indicator_stop();
615
616                 netconfig_wifi_bgscan_stop();
617                 netconfig_wifi_bgscan_set_interval(SCAN_EXPONENTIAL_MIN);
618                 netconfig_wifi_bgscan_start(TRUE);
619         } else if ((old_state > NETCONFIG_WIFI_IDLE && old_state < NETCONFIG_WIFI_CONNECTED) && new_state == NETCONFIG_WIFI_IDLE) {
620                 /* in ipv6 case disconnect/association -> association */
621                 DBG("reset the bg scan period");
622
623                 netconfig_wifi_bgscan_stop();
624                 netconfig_wifi_bgscan_start(TRUE);
625         }
626
627         _wifi_state_changed(new_state);
628
629         if (new_state == NETCONFIG_WIFI_CONNECTED)
630                 _wifi_state_connected_activation();
631 }
632
633 wifi_service_state_e wifi_state_get_service_state(void)
634 {
635         return g_service_state;
636 }
637
638 void wifi_state_set_tech_state(wifi_tech_state_e new_state)
639 {
640         wifi_tech_state_e old_state = g_tech_state;
641
642         if (old_state == new_state)
643                 return;
644
645         g_tech_state = new_state;
646
647         DBG("Wi-Fi technology state, old state[%s] ==> new state[%s]",
648                 _convert_wifi_technology_state_to_string(old_state), _convert_wifi_technology_state_to_string(new_state));
649 }
650
651 wifi_tech_state_e wifi_state_get_technology_state(void)
652 {
653         GVariant *message = NULL, *variant;
654         GVariantIter *iter, *next;
655         wifi_tech_state_e ret = NETCONFIG_WIFI_TECH_OFF;
656         gboolean wifi_tech_powered = FALSE;
657         gboolean wifi_tech_connected = FALSE;
658         const char *path;
659         gchar *key;
660
661         if (g_tech_state > NETCONFIG_WIFI_TECH_UNKNOWN)
662                 return g_tech_state;
663
664         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
665                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
666                         "GetTechnologies", NULL);
667         if (message == NULL) {
668                 ERR("Failed to get_technology_state");
669                 return NETCONFIG_WIFI_TECH_UNKNOWN;
670         }
671
672         g_variant_get(message, "(a(oa{sv}))", &iter);
673         while (g_variant_iter_loop(iter, "(oa{sv})", &path, &next)) {
674                 if (path == NULL || g_strcmp0(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) != 0)
675                         continue;
676
677                 while (g_variant_iter_loop(next, "{sv}", &key, &variant)) {
678                         const gchar *sdata = NULL;
679                         gboolean data;
680
681                         if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)) {
682                                 data = g_variant_get_boolean(variant);
683                                 DBG("key-[%s] - %s", key, data ? "True" : "False");
684
685                                 if (strcmp(key, "Powered") == 0 && data)
686                                         wifi_tech_powered = TRUE;
687                                 else if (strcmp(key, "Connected") == 0 && data)
688                                         wifi_tech_connected = TRUE;
689                                 /* For further use
690                                 else if (strcmp(key, "Tethering") == 0 && data) {
691                                 } */
692                         } else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
693                                 sdata = g_variant_get_string(variant, NULL);
694                                 DBG("%s", sdata);
695                         }
696                 }
697         }
698
699         g_variant_unref(message);
700
701         g_variant_iter_free(iter);
702
703         if (wifi_tech_powered == TRUE)
704                 ret = NETCONFIG_WIFI_TECH_POWERED;
705
706         if (wifi_tech_connected == TRUE)
707                 ret = NETCONFIG_WIFI_TECH_CONNECTED;
708
709         g_tech_state = ret;
710
711         return g_tech_state;
712 }
713
714 void wifi_state_set_connected_essid(void)
715 {
716         __set_wifi_connected_essid();
717 }
718
719 void wifi_state_get_connected_essid(gchar **essid)
720 {
721         *essid = g_strdup(__get_wifi_connected_essid());
722 }
723
724 /*      wifi_connection_state_e in CAPI
725  *
726  *      WIFI_CONNECTION_STATE_FAILURE           = -1
727  *      WIFI_CONNECTION_STATE_DISCONNECTED      = 0
728  *      WIFI_CONNECTION_STATE_ASSOCIATION       = 1
729  *      WIFI_CONNECTION_STATE_CONFIGURATION     = 2
730  *      WIFI_CONNECTION_STATE_CONNECTED         = 3
731  */
732 /*      connection_wifi_state_e in CAPI
733  *
734  *      CONNECTION_WIFI_STATE_DEACTIVATED       = 0
735  *      CONNECTION_WIFI_STATE_DISCONNECTED      = 1
736  *      CONNECTION_WIFI_STATE_CONNECTED         = 2
737  */
738 gboolean handle_get_wifi_state(Wifi *wifi, GDBusMethodInvocation *context)
739 {
740         g_return_val_if_fail(wifi != NULL, FALSE);
741         GVariant *param = NULL;
742         wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
743         wifi_service_state_e service_state = NETCONFIG_WIFI_UNKNOWN;
744         tech_state = wifi_state_get_technology_state();
745         service_state = wifi_state_get_service_state();
746
747         if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN)
748                 param = g_variant_new("(s)", "unknown");
749         else if (tech_state == NETCONFIG_WIFI_TECH_OFF ||
750                 tech_state == NETCONFIG_WIFI_TECH_WPS_ONLY)
751                 param = g_variant_new("(s)", "deactivated");
752         else if (tech_state == NETCONFIG_WIFI_TECH_CONNECTED)
753                 param = g_variant_new("(s)", "connected");
754         else {
755                 switch (service_state) {
756                 case NETCONFIG_WIFI_FAILURE:
757                         param = g_variant_new("(s)", "failure");
758                         break;
759                 case NETCONFIG_WIFI_ASSOCIATION:
760                         param = g_variant_new("(s)", "association");
761                         break;
762                 case NETCONFIG_WIFI_CONFIGURATION:
763                         param = g_variant_new("(s)", "configuration");
764                         break;
765                 case NETCONFIG_WIFI_CONNECTED:
766                         param = g_variant_new("(s)", "connected");
767                         break;
768                 case NETCONFIG_WIFI_UNKNOWN:
769                 case NETCONFIG_WIFI_IDLE:
770                 default:
771                         param = g_variant_new("(s)", "disconnected");
772                 }
773         }
774
775         g_dbus_method_invocation_return_value(context, param);
776
777         return TRUE;
778 }