2 * Network Configuration Module
4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <vconf-keys.h>
26 #include "network-state.h"
27 #include "network-statistics.h"
28 #include "wifi-state.h"
29 #include "wifi-indicator.h"
30 #include "wifi-background-scan.h"
32 static int profiles_count = 0;
34 static enum netconfig_wifi_service_state
35 wifi_service_state = NETCONFIG_WIFI_UNKNOWN;
37 static GSList *notifier_list = NULL;
40 static void __netconfig_wifi_set_profiles_count(const int count)
42 profiles_count = count;
45 static int __netconfig_wifi_get_profiles_count(void)
47 return profiles_count;
50 static void __netconfig_wifi_set_essid(void)
52 const char *essid_name = NULL;
53 const char *wifi_profile = netconfig_get_default_profile();
55 if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
58 if (wifi_profile == NULL ||
59 netconfig_is_wifi_profile(wifi_profile) != TRUE) {
60 ERR("Can't get Wi-Fi profile");
64 essid_name = netconfig_wifi_get_connected_essid(wifi_profile);
65 if (essid_name == NULL) {
66 ERR("Can't get Wi-Fi name");
70 vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, essid_name);
73 static void __netconfig_wifi_unset_essid(void)
75 vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, "");
78 static GSList *__netconfig_wifi_state_get_service_profiles(DBusMessage *message)
80 GSList *service_profiles = NULL;
81 DBusMessageIter iter, dict;
83 dbus_message_iter_init(message, &iter);
84 dbus_message_iter_recurse(&iter, &dict);
86 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
87 DBusMessageIter entry;
88 const char *object_path = NULL;
90 dbus_message_iter_recurse(&dict, &entry);
91 dbus_message_iter_get_basic(&entry, &object_path);
93 if (object_path == NULL) {
94 dbus_message_iter_next(&dict);
98 if (netconfig_is_wifi_profile(object_path) == TRUE)
99 service_profiles = g_slist_append(service_profiles,
100 g_strdup(object_path));
102 dbus_message_iter_next(&dict);
105 return service_profiles;
108 static char *__netconfig_wifi_get_connman_favorite_service(void)
110 char *favorite_service = NULL;
111 DBusMessage *message = NULL;
112 GSList *service_profiles = NULL;
115 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
116 CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
117 "GetServices", NULL);
118 if (message == NULL) {
119 ERR("Failed to get service list");
123 /* Get service profiles from ConnMan Manager */
124 service_profiles = __netconfig_wifi_state_get_service_profiles(message);
125 dbus_message_unref(message);
127 for (list = service_profiles; list != NULL; list = list->next) {
128 char *profile_path = list->data;
129 DBusMessageIter iter, array;
131 if (favorite_service != NULL)
134 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
135 profile_path, CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
137 if (message == NULL) {
138 ERR("Failed to get service information of %s", profile_path);
142 dbus_message_iter_init(message, &iter);
143 dbus_message_iter_recurse(&iter, &array);
145 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
146 DBusMessageIter entry, variant;
147 const char *key = NULL;
150 dbus_message_iter_recurse(&array, &entry);
151 dbus_message_iter_get_basic(&entry, &key);
153 dbus_message_iter_next(&entry);
154 dbus_message_iter_recurse(&entry, &variant);
156 if (g_str_equal(key, "Favorite") != TRUE) {
157 dbus_message_iter_next(&array);
161 dbus_message_iter_get_basic(&variant, &value);
164 favorite_service = g_strdup(profile_path);
169 dbus_message_unref(message);
172 g_slist_free(service_profiles);
174 return favorite_service;
177 static void __netconfig_wifi_state_changed(
178 enum netconfig_wifi_service_state state)
182 for (list = notifier_list; list; list = list->next) {
183 struct netconfig_wifi_state_notifier *notifier = list->data;
185 if (notifier->netconfig_wifi_state_changed != NULL)
186 notifier->netconfig_wifi_state_changed(state, notifier->user_data);
190 void netconfig_wifi_state_set_service_state(
191 enum netconfig_wifi_service_state new_state)
193 enum netconfig_wifi_service_state old_state = wifi_service_state;
195 if (old_state == new_state)
198 wifi_service_state = new_state;
199 DBG("Wi-Fi state %d ==> %d", old_state, new_state);
201 if (new_state == NETCONFIG_WIFI_CONNECTED) {
202 netconfig_del_wifi_found_notification();
204 vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_CONNECTED);
205 vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_CONNECTED);
207 __netconfig_wifi_set_essid();
209 netconfig_wifi_indicator_start();
210 } else if (old_state == NETCONFIG_WIFI_CONNECTED) {
211 vconf_set_int (VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
212 vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
214 __netconfig_wifi_unset_essid();
216 netconfig_wifi_indicator_stop();
219 __netconfig_wifi_state_changed(new_state);
222 enum netconfig_wifi_service_state
223 netconfig_wifi_state_get_service_state(void)
225 return wifi_service_state;
228 enum netconfig_wifi_tech_state netconfig_wifi_get_technology_state(void)
230 DBusMessage *message = NULL;
231 DBusMessageIter iter, array;
232 enum netconfig_wifi_tech_state ret = NETCONFIG_WIFI_TECH_OFF;
233 gboolean wifi_tech_powered = FALSE;
234 gboolean wifi_tech_connected = FALSE;
235 gboolean wifi_tethering = FALSE;
237 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
238 CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
239 "GetTechnologies", NULL);
240 if (message == NULL) {
241 ERR("Failed to get Wi-Fi technology state");
242 return NETCONFIG_WIFI_TECH_UNKNOWN;
245 dbus_message_iter_init(message, &iter);
246 dbus_message_iter_recurse(&iter, &array);
248 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
249 DBusMessageIter entry, dict;
252 dbus_message_iter_recurse(&array, &entry);
253 dbus_message_iter_get_basic(&entry, &path);
255 dbus_message_iter_next(&entry);
256 dbus_message_iter_recurse(&entry, &dict);
259 g_str_equal(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == FALSE) {
260 dbus_message_iter_next(&array);
264 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
265 DBusMessageIter entry1, value1;
266 const char *key, *sdata;
269 dbus_message_iter_recurse(&dict, &entry1);
270 dbus_message_iter_get_basic(&entry1, &key);
272 dbus_message_iter_next(&entry1);
273 dbus_message_iter_recurse(&entry1, &value1);
275 if (dbus_message_iter_get_arg_type(&value1) ==
277 dbus_message_iter_get_basic(&value1, &data);
278 DBG("key-[%s] - %s", key, data ? "True" : "False");
280 if (strcmp(key, "Powered") == 0 && data) {
281 wifi_tech_powered = TRUE;
282 } else if (strcmp(key, "Connected") == 0 && data) {
283 wifi_tech_connected = TRUE;
284 } else if (strcmp(key, "Tethering") == 0 && data) {
285 wifi_tethering = TRUE;
287 } else if (dbus_message_iter_get_arg_type(&value1) ==
289 dbus_message_iter_get_basic(&value1, &sdata);
292 dbus_message_iter_next(&dict);
295 dbus_message_iter_next(&array);
298 dbus_message_unref(message);
300 if (wifi_tech_powered)
301 ret = NETCONFIG_WIFI_TECH_POWERED;
303 if (wifi_tech_connected)
304 ret = NETCONFIG_WIFI_TECH_CONNECTED;
307 ret = NETCONFIG_WIFI_TECH_TETHERING_ON;
312 void netconfig_wifi_update_power_state(gboolean powered)
316 /* It's automatically updated by signal-handler
317 * DO NOT update manually
318 * It includes Wi-Fi state configuration
320 vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
322 if (powered == TRUE) {
323 if (wifi_state == VCONFKEY_WIFI_OFF &&
324 netconfig_is_wifi_direct_on() != TRUE &&
325 netconfig_is_wifi_tethering_on() != TRUE) {
326 DBG("Wi-Fi successfully turned on or waken up from power-save mode");
328 vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
329 vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_ON);
330 vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
332 netconfig_wifi_notify_power_completed(TRUE);
334 netconfig_wifi_device_picker_service_start();
336 netconfig_wifi_bgscan_start();
339 if (wifi_state != VCONFKEY_WIFI_OFF) {
340 DBG("Wi-Fi successfully turned off or in power-save mode");
342 netconfig_wifi_device_picker_service_stop();
344 if (netconfig_is_wifi_tethering_on() != TRUE)
345 netconfig_wifi_remove_driver();
347 vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF);
348 vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_OFF);
349 vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF);
351 netconfig_wifi_notify_power_completed(FALSE);
353 netconfig_del_wifi_found_notification();
355 netconfig_wifi_bgscan_stop();
357 __netconfig_wifi_set_profiles_count(0);
362 char *netconfig_wifi_get_favorite_service(void)
364 return __netconfig_wifi_get_connman_favorite_service();
367 void netconfig_wifi_check_network_notification(DBusMessage *message)
369 DBusMessageIter iter;
370 int profiles_count = 0;
371 int qs_enable, ug_state;
373 if (netconfig_wifi_state_get_service_state() == NETCONFIG_WIFI_CONNECTED) {
374 DBG("Service state is connected");
378 if (vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &qs_enable) == -1) {
379 DBG("Fail to get %s", VCONFKEY_WIFI_ENABLE_QS);
383 if (qs_enable != VCONFKEY_WIFI_QS_ENABLE) {
384 DBG("qs_enable != VCONFKEY_WIFI_QS_ENABLE");
388 if (vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state) == -1) {
389 DBG("Fail to get %s", VCONFKEY_WIFI_UG_RUN_STATE);
393 if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) {
394 DBG("ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND");
398 if (message == NULL) {
399 ERR("Failed to get service list");
403 dbus_message_iter_init(message, &iter);
404 DBusMessageIter array, value;
405 dbus_message_iter_recurse(&iter, &array);
406 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) {
407 DBG("Array not found. type %d", dbus_message_iter_get_arg_type(&array));
411 dbus_message_iter_recurse(&array, &value);
412 while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
413 const char *object_path = NULL;
415 dbus_message_iter_get_basic(&value, &object_path);
417 DBG("found a profile: %s", object_path);
418 if (netconfig_is_wifi_profile(object_path) == TRUE) {
420 DBG("Total wifi profile cnt = %d", profiles_count);
423 dbus_message_iter_next(&array);
424 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) {
425 DBG("Not a structure entry. Arg type = %d", dbus_message_iter_get_arg_type(&array));
428 dbus_message_iter_recurse(&array, &value);
431 if (__netconfig_wifi_get_profiles_count() != profiles_count) {
432 DBG("profiles prev_count (%d) - profiles count (%d)",
433 __netconfig_wifi_get_profiles_count(), profiles_count);
435 netconfig_add_wifi_found_notification();
436 __netconfig_wifi_set_profiles_count(profiles_count);
438 DBG("No change in profile count[%d]", profiles_count);
441 void netconfig_wifi_state_notifier_cleanup(void)
444 * Now, all the user_data of notifier_list's element
445 * is NULL, so we don't free that, only use g_slist_free.
446 * If user_data is not NULL, using g_slist_free_full with
447 * destory_notify function to free user_data
449 g_slist_free(notifier_list);
452 void netconfig_wifi_state_notifier_register(
453 struct netconfig_wifi_state_notifier *notifier)
455 DBG("register notifier");
457 notifier_list = g_slist_append(notifier_list, notifier);
460 void netconfig_wifi_state_notifier_unregister(
461 struct netconfig_wifi_state_notifier *notifier)
463 DBG("un-register notifier");
465 notifier_list = g_slist_remove_all(notifier_list, notifier);