1c671e90c55ce38d3a07108198433870c5eb76f8
[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 <aul.h>
21 #include <vconf.h>
22 #include <vconf-keys.h>
23 #include <bundle.h>
24 #include <bundle_internal.h>
25 #include <eventsystem.h>
26
27 #include "log.h"
28 #include "util.h"
29 #include "netdbus.h"
30 #include "wifi-state.h"
31 #include "wifi-power.h"
32 #include "netsupplicant.h"
33 #include "network-state.h"
34 #include "wifi-indicator.h"
35 #include "network-statistics.h"
36 #include "wifi-background-scan.h"
37
38 #define NETCONFIG_NETWORK_NOTIFICATION_TIMEOUT  15 * 1000
39
40 static gboolean new_bss_found = FALSE;
41 static guint network_noti_timer_id = 0;
42
43 static enum netconfig_wifi_service_state
44         wifi_service_state = NETCONFIG_WIFI_UNKNOWN;
45 static enum netconfig_wifi_tech_state
46         wifi_technology_state = NETCONFIG_WIFI_TECH_UNKNOWN;
47
48 static GSList *notifier_list = NULL;
49
50
51 static void __netconfig_pop_wifi_connected_poppup(const char *ssid)
52 {
53         bundle *b = NULL;
54
55         if (ssid == NULL)
56                 return;
57
58         b = bundle_create();
59
60         bundle_add(b, "_SYSPOPUP_TITLE_", "Network connection popup");
61         bundle_add(b, "_SYSPOPUP_TYPE_", "notification");
62         bundle_add(b, "_SYSPOPUP_CONTENT_", "wifi connected");
63         bundle_add(b, "_AP_NAME_", ssid);
64
65         DBG("Launch Wi-Fi connected alert network popup");
66         aul_launch_app("net.netpopup", b);
67
68         bundle_free(b);
69 }
70
71 static void __netconfig_wifi_state_connected_activation(void)
72 {
73         /* Add activation of services when Wi-Fi is connected */
74         bundle *b = NULL;
75
76         b = bundle_create();
77         aul_launch_app("com.samsung.keepit-service-standby", b);
78         bundle_free(b);
79 }
80
81 static void __netconfig_wifi_set_essid(void)
82 {
83         const char *essid_name = NULL;
84         const char *wifi_profile = netconfig_get_default_profile();
85
86         if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
87                 return;
88
89         if (wifi_profile == NULL ||
90                         netconfig_is_wifi_profile(wifi_profile) != TRUE) {
91                 ERR("Can't get Wi-Fi profile");
92                 return;
93         }
94
95         essid_name = netconfig_wifi_get_connected_essid(wifi_profile);
96         if (essid_name == NULL) {
97                 ERR("Can't get Wi-Fi name");
98                 return;
99         }
100
101         netconfig_set_vconf_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, essid_name);
102
103         __netconfig_pop_wifi_connected_poppup(essid_name);
104 }
105
106 static void __netconfig_wifi_unset_essid(void)
107 {
108         netconfig_set_vconf_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, "");
109 }
110
111 static gboolean __netconfig_is_wifi_profile_available(void)
112 {
113         GVariant *message = NULL;
114         GVariantIter *iter, *next;
115         gchar *obj;
116
117         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
118                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
119                         "GetServices", NULL);
120         if (message == NULL) {
121                 ERR("Failed to get service list");
122                 return FALSE;
123         }
124
125         g_variant_get(message, "(a(oa{sv}))", &iter);
126         while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
127                 if (obj == NULL || netconfig_is_wifi_profile((const gchar*)obj) == FALSE) {
128                         continue;
129                 }
130
131                 g_variant_iter_free(next);
132                 g_free(obj);
133                 break;
134         }
135
136         g_variant_unref(message);
137
138         g_variant_iter_free(iter);
139
140         return TRUE;
141 }
142
143 static gboolean __netconfig_wifi_is_favorited(GVariantIter *array)
144 {
145         gboolean is_favorite = FALSE;
146         gchar *key;
147         GVariant *var;
148
149         while (g_variant_iter_loop(array, "{sv}", &key, &var)) {
150                 gboolean value;
151
152                 if (g_str_equal(key, "Favorite") != TRUE) {
153                         continue;
154                 }
155
156                 value = g_variant_get_boolean(var);
157                 if (value)
158                         is_favorite = TRUE;
159                 g_free(key);
160                 g_variant_unref(var);
161                 break;
162         }
163
164         return is_favorite;
165 }
166
167 static char *__netconfig_wifi_get_connman_favorite_service(void)
168 {
169         char *favorite_service = NULL;
170         GVariant *message = NULL;
171         gchar *obj;
172         GVariantIter *iter, *next;
173
174         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
175                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
176                         "GetServices", NULL);
177         if (message == NULL) {
178                 ERR("Failed to get service list");
179                 return NULL;
180         }
181
182         g_variant_get(message, "(a(oa{sv}))", &iter);
183         while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
184                 if (obj == NULL || netconfig_is_wifi_profile(obj) == FALSE) {
185                         continue;
186                 }
187
188                 if (__netconfig_wifi_is_favorited(next) == TRUE) {
189                         favorite_service = g_strdup(obj);
190                         g_free(obj);
191                         g_variant_iter_free(next);
192                         break;
193                 }
194         }
195
196         g_variant_iter_free(iter);
197         g_variant_unref(message);
198
199         return favorite_service;
200 }
201
202 static void __netconfig_wifi_state_changed(
203                 enum netconfig_wifi_service_state state)
204 {
205         GSList *list;
206
207         for (list = notifier_list; list; list = list->next) {
208                 struct netconfig_wifi_state_notifier *notifier = list->data;
209
210                 if (notifier->netconfig_wifi_state_changed != NULL)
211                         notifier->netconfig_wifi_state_changed(state, notifier->user_data);
212         }
213 }
214
215 void netconfig_wifi_set_bss_found(const gboolean found)
216 {
217         if (found != new_bss_found)
218                 new_bss_found = found;
219 }
220
221 gboolean netconfig_wifi_is_bss_found(void)
222 {
223         return new_bss_found;
224 }
225
226 static void __netconfig_wifi_state_set_power_save(gboolean power_save)
227 {
228         gboolean result;
229         const char *if_path;
230         GVariant *input_args = NULL;
231         static gboolean old_state = TRUE;
232         const gchar *args_disable = "POWERMODE 1";
233         const gchar *args_enable = "POWERMODE 0";
234         if (old_state == power_save)
235                 return;
236
237         if_path = netconfig_wifi_get_supplicant_interface();
238         if (if_path == NULL) {
239                 ERR("Fail to get wpa_supplicant DBus path");
240                 return;
241         }
242
243         if (power_save)
244                 input_args = g_variant_new_string(args_enable);
245         else
246                 input_args = g_variant_new_string(args_disable);
247
248         result = netconfig_supplicant_invoke_dbus_method_nonblock(
249                         SUPPLICANT_SERVICE,
250                         if_path,
251                         SUPPLICANT_INTERFACE ".Interface",
252                         "Driver",
253                         input_args,
254                         NULL);
255         if (result == FALSE)
256                 ERR("Fail to set power save mode POWERMODE %d", power_save);
257         else
258                 old_state = power_save;
259
260         return;
261 }
262
263 static void __netconfig_wifi_state_set_power_lock(gboolean power_lock)
264 {
265         gint32 ret = 0;
266         GVariant *reply;
267         GVariant *params;
268         char state[] = "lcdoff";
269         char flag[] = "staycurstate";
270         char standby[] = "NULL";
271         int timeout = 0;
272         char sleepmargin[] = "sleepmargin";
273
274         const char *lockstate = "lockstate";
275         const char *unlockstate = "unlockstate";
276         static gboolean old_state = FALSE;
277         const char *lock_method;
278
279         if (old_state == power_lock)
280                 return;
281
282         if (power_lock == TRUE) {
283                 /* deviced power lock enable */
284                 params = g_variant_new("(sssi)", state, flag, standby, timeout);
285
286                 lock_method = lockstate;
287         } else {
288                 /* deviced power lock disable */
289                 params = g_variant_new("(ss)", state, sleepmargin);
290
291                 lock_method = unlockstate;
292         }
293
294         reply = netconfig_invoke_dbus_method(
295                         "org.tizen.system.deviced",
296                         "/Org/Tizen/System/DeviceD/Display",
297                         "org.tizen.system.deviced.display",
298                         lock_method,
299                         params);
300         if (reply == NULL){
301                 ERR("Failed to set_power_lock");
302                 return;
303         }
304
305         ret = g_variant_get_int32(reply);
306         if (ret < 0)
307                 ERR("Failed to set power lock %s with ret %d",
308                                 power_lock == TRUE ? "enable" : "disable", ret);
309         else
310                 old_state = power_lock;
311
312         return;
313 }
314
315 void netconfig_wifi_state_set_service_state(
316                 enum netconfig_wifi_service_state new_state)
317 {
318         static gboolean dhcp_stage = FALSE;
319         enum netconfig_wifi_service_state old_state = wifi_service_state;
320
321         if (old_state == new_state)
322                 return;
323
324         wifi_service_state = new_state;
325         DBG("Wi-Fi state %d ==> %d", old_state, new_state);
326
327         /* During DHCP, temporarily disable Wi-Fi power saving */
328         if ((old_state < NETCONFIG_WIFI_ASSOCIATION ||
329                         old_state == NETCONFIG_WIFI_FAILURE) &&
330                         new_state == NETCONFIG_WIFI_CONFIGURATION) {
331                 __netconfig_wifi_state_set_power_lock(TRUE);
332                 __netconfig_wifi_state_set_power_save(FALSE);
333                 dhcp_stage = TRUE;
334         } else if (dhcp_stage == TRUE) {
335                 __netconfig_wifi_state_set_power_lock(FALSE);
336                 __netconfig_wifi_state_set_power_save(TRUE);
337                 dhcp_stage = FALSE;
338         }
339
340         if (new_state == NETCONFIG_WIFI_CONNECTED) {
341                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
342
343                 netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_CONNECTED);
344                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE,
345                                                                         VCONFKEY_NETWORK_WIFI_CONNECTED);
346
347                 netconfig_set_system_event(SYS_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_CONNECTED);
348
349                 __netconfig_wifi_set_essid();
350
351                 netconfig_wifi_indicator_start();
352         } else if (old_state == NETCONFIG_WIFI_CONNECTED) {
353                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_PORTAL_NOTI, NULL);
354
355                 __netconfig_wifi_unset_essid();
356
357                 netconfig_set_vconf_int (VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
358                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE,
359                                                                         VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
360
361                 netconfig_set_system_event(SYS_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_ON);
362
363                 netconfig_wifi_indicator_stop();
364
365                 netconfig_wifi_set_bgscan_pause(FALSE);
366
367                 netconfig_wifi_bgscan_stop();
368                 netconfig_wifi_bgscan_start(TRUE);
369         } else if ( (old_state > NETCONFIG_WIFI_IDLE && old_state < NETCONFIG_WIFI_CONNECTED)
370                                         && new_state == NETCONFIG_WIFI_IDLE){
371                 //in ipv6 case disconnect/association -> association
372                 DBG("reset the bg scan period");
373                 netconfig_wifi_set_bgscan_pause(FALSE);
374
375                 netconfig_wifi_bgscan_stop();
376                 netconfig_wifi_bgscan_start(TRUE);
377         }
378
379         __netconfig_wifi_state_changed(new_state);
380
381         if (new_state == NETCONFIG_WIFI_CONNECTED){
382                 __netconfig_wifi_state_connected_activation();
383 #if defined TIZEN_WEARABLE
384                 wc_launch_syspopup(WC_POPUP_TYPE_WIFI_CONNECTED);
385 #endif
386         }
387 }
388
389 enum netconfig_wifi_service_state
390 netconfig_wifi_state_get_service_state(void)
391 {
392         return wifi_service_state;
393 }
394
395 void netconfig_wifi_state_set_technology_state(
396                 enum netconfig_wifi_tech_state new_state)
397 {
398         enum netconfig_wifi_tech_state old_state = wifi_technology_state;
399
400         if (old_state == new_state)
401                 return;
402
403         wifi_technology_state = new_state;
404
405         DBG("Wi-Fi technology state %d ==> %d", old_state, new_state);
406 }
407
408 enum netconfig_wifi_tech_state netconfig_wifi_state_get_technology_state(void)
409 {
410         GVariant *message = NULL, *variant;
411         GVariantIter *iter, *next;
412         enum netconfig_wifi_tech_state ret = NETCONFIG_WIFI_TECH_OFF;
413         gboolean wifi_tech_powered = FALSE;
414         gboolean wifi_tech_connected = FALSE;
415         const char *path;
416         gchar *key;
417
418         if (wifi_technology_state > NETCONFIG_WIFI_TECH_UNKNOWN)
419                 return wifi_technology_state;
420
421         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
422                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
423                         "GetTechnologies", NULL);
424         if (message == NULL) {
425                 ERR("Failed to get_technology_state");
426                 return NETCONFIG_WIFI_TECH_UNKNOWN;
427         }
428
429         g_variant_get(message, "(a(oa{sv}))", &iter);
430         while (g_variant_iter_loop(iter, "(oa{sv})", &path, &next)) {
431                 if (path == NULL || g_strcmp0(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) != 0) {
432                         continue;
433                 }
434
435                 while (g_variant_iter_loop(next, "{sv}", &key, &variant)) {
436                         const gchar *sdata = NULL;
437                         gboolean data;
438
439                         if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)) {
440                                 data = g_variant_get_boolean(variant);
441                                 DBG("key-[%s] - %s", key, data ? "True" : "False");
442
443                                 if (strcmp(key, "Powered") == 0 && data) {
444                                         wifi_tech_powered = TRUE;
445                                 } else if (strcmp(key, "Connected") == 0 && data) {
446                                         wifi_tech_connected = TRUE;
447                                 } else if (strcmp(key, "Tethering") == 0 && data) {
448                                         // For further use
449                                 }
450                         } else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
451                                 sdata = g_variant_get_string(variant, NULL);
452                                 DBG("%s", sdata);
453                         }
454                 }
455                 g_variant_iter_free (next);
456         }
457
458         g_variant_unref(message);
459
460         g_variant_iter_free (iter);
461
462         if (wifi_tech_powered == TRUE)
463                 ret = NETCONFIG_WIFI_TECH_POWERED;
464
465         if (wifi_tech_connected == TRUE)
466                 ret = NETCONFIG_WIFI_TECH_CONNECTED;
467
468         wifi_technology_state = ret;
469
470         return wifi_technology_state;
471 }
472
473 void netconfig_wifi_notify_power_failed(void)
474 {
475         wifi_emit_power_operation_failed((Wifi *)get_netconfig_wifi_object());
476
477         DBG("Successfully sent signal [PowerOperationFailed]");
478 }
479
480 void netconfig_wifi_notify_power_completed(gboolean power_on)
481 {
482         if (power_on)
483                 wifi_emit_power_on_completed((Wifi *)get_netconfig_wifi_object());
484         else
485                 wifi_emit_power_off_completed((Wifi *)get_netconfig_wifi_object());
486
487         DBG("Successfully sent signal [%s]",(power_on)?"powerOn":"powerOff");
488 }
489
490 static void __netconfig_notification_value_changed_cb(
491                 keynode_t *node, void *user_data)
492 {
493         int value = -1;
494
495         if (vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &value) < 0) {
496                 return;
497         }
498
499         if (value == VCONFKEY_WIFI_QS_DISABLE) {
500                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI,
501                                 NULL);
502         }
503 }
504
505 static void __netconfig_register_network_notification(void)
506 {
507 #if defined TIZEN_WEARABLE
508         return;
509 #endif
510         vconf_notify_key_changed(VCONFKEY_WIFI_ENABLE_QS,
511                         __netconfig_notification_value_changed_cb, NULL);
512 }
513
514 static void __netconfig_deregister_network_notification(void)
515 {
516 #if defined TIZEN_WEARABLE
517                 return;
518 #endif
519         vconf_ignore_key_changed(VCONFKEY_WIFI_ENABLE_QS,
520                         __netconfig_notification_value_changed_cb);
521 }
522
523 void netconfig_wifi_update_power_state(gboolean powered)
524 {
525         enum netconfig_wifi_tech_state wifi_tech_state;
526
527         /* It's automatically updated by signal-handler
528          * DO NOT update manually
529          * It includes Wi-Fi state configuration
530          */
531         wifi_tech_state = netconfig_wifi_state_get_technology_state();
532
533         if (powered == TRUE) {
534                 if (wifi_tech_state < NETCONFIG_WIFI_TECH_POWERED &&
535                                                 netconfig_is_wifi_tethering_on() != TRUE) {
536                         DBG("Wi-Fi turned on or waken up from power-save mode");
537
538                         netconfig_wifi_state_set_technology_state(
539                                                                                 NETCONFIG_WIFI_TECH_POWERED);
540
541                         netconfig_wifi_notify_power_completed(TRUE);
542
543                         netconfig_wifi_device_picker_service_start();
544
545                         netconfig_set_vconf_int(VCONF_WIFI_LAST_POWER_STATE,
546                                                                                 VCONFKEY_WIFI_UNCONNECTED);
547                         netconfig_set_vconf_int(VCONFKEY_WIFI_STATE,
548                                                                                 VCONFKEY_WIFI_UNCONNECTED);
549                         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE,
550                                                                                 VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
551
552                         netconfig_set_system_event(SYS_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_ON);
553
554                         netconfig_wifi_bgscan_stop();
555                         netconfig_wifi_bgscan_start(TRUE);
556
557                         /* Add callback to track change in notification setting */
558                         __netconfig_register_network_notification();
559                 }
560         } else if (wifi_tech_state > NETCONFIG_WIFI_TECH_OFF) {
561                 DBG("Wi-Fi turned off or in power-save mode");
562
563                 netconfig_wifi_state_set_technology_state(
564                                                                                 NETCONFIG_WIFI_TECH_WPS_ONLY);
565
566                 netconfig_wifi_device_picker_service_stop();
567
568                 netconfig_wifi_disable_technology_state_by_only_connman_signal();
569                 netconfig_wifi_driver_and_supplicant(FALSE);
570
571                 netconfig_wifi_notify_power_completed(FALSE);
572
573                 netconfig_set_vconf_int(VCONF_WIFI_LAST_POWER_STATE, VCONFKEY_WIFI_OFF);
574                 netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF);
575                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE,
576                                                                                 VCONFKEY_NETWORK_WIFI_OFF);
577
578                 netconfig_set_system_event(SYS_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_OFF);
579
580                 netconfig_wifi_set_bgscan_pause(FALSE);
581                 netconfig_wifi_bgscan_stop();
582
583                 netconfig_wifi_set_bss_found(FALSE);
584
585                 /* Inform net-popup to remove the wifi found notification */
586                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
587                 netconfig_send_notification_to_net_popup(NETCONFIG_DEL_PORTAL_NOTI, NULL);
588
589                 __netconfig_deregister_network_notification();
590
591         }
592 }
593
594 char *netconfig_wifi_get_favorite_service(void)
595 {
596         return __netconfig_wifi_get_connman_favorite_service();
597 }
598
599 static gboolean __netconfig_wifi_check_network_notification(gpointer data)
600 {
601         int qs_enable = 0, ug_state = 0;
602         static gboolean check_again = FALSE;
603
604         enum netconfig_wifi_tech_state wifi_tech_state;
605         enum netconfig_wifi_service_state wifi_service_state;
606
607         wifi_tech_state = netconfig_wifi_state_get_technology_state();
608         if (wifi_tech_state < NETCONFIG_WIFI_TECH_POWERED) {
609                 DBG("Wi-Fi off or WPS only supported[%d]", wifi_tech_state);
610                 goto cleanup;
611         }
612
613         wifi_service_state = netconfig_wifi_state_get_service_state();
614         if (wifi_service_state == NETCONFIG_WIFI_CONNECTED) {
615                 DBG("Service state is connected");
616                 goto cleanup;
617         } else if (wifi_service_state == NETCONFIG_WIFI_ASSOCIATION ||
618                 wifi_service_state == NETCONFIG_WIFI_CONFIGURATION) {
619                 DBG("Service state is connecting (check again : %d)", check_again);
620                 if (!check_again) {
621                         check_again = TRUE;
622                         return TRUE;
623                 } else
624                         check_again = FALSE;
625         }
626
627         if (__netconfig_is_wifi_profile_available() == FALSE) {
628                 netconfig_send_notification_to_net_popup(
629                 NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
630                 goto cleanup;
631         }
632
633         vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &qs_enable);
634         if (qs_enable != VCONFKEY_WIFI_QS_ENABLE) {
635                 DBG("qs_enable != VCONFKEY_WIFI_QS_ENABLE");
636                 goto cleanup;
637         }
638
639         vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state);
640         if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) {
641                 goto cleanup;
642         }
643
644         netconfig_send_notification_to_net_popup(NETCONFIG_ADD_FOUND_AP_NOTI, NULL);
645
646         netconfig_wifi_set_bss_found(FALSE);
647
648 cleanup:
649         netconfig_stop_timer(&network_noti_timer_id);
650         return FALSE;
651 }
652
653 void netconfig_wifi_start_timer_network_notification(void)
654 {
655 #if defined TIZEN_WEARABLE
656                 /* In case of wearable device, no need to notify available Wi-Fi APs */
657                 return ;
658 #endif
659         netconfig_start_timer(NETCONFIG_NETWORK_NOTIFICATION_TIMEOUT,
660                 __netconfig_wifi_check_network_notification, NULL, &network_noti_timer_id);
661 }
662
663 void netconfig_wifi_state_notifier_cleanup(void)
664 {
665         g_slist_free_full(notifier_list, NULL);
666 }
667
668 void netconfig_wifi_state_notifier_register(
669                 struct netconfig_wifi_state_notifier *notifier)
670 {
671         DBG("register notifier");
672
673         notifier_list = g_slist_append(notifier_list, notifier);
674 }
675
676 void netconfig_wifi_state_notifier_unregister(
677                 struct netconfig_wifi_state_notifier *notifier)
678 {
679         DBG("un-register notifier");
680
681         notifier_list = g_slist_remove_all(notifier_list, notifier);
682 }