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;
236 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
237 CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
238 "GetTechnologies", NULL);
239 if (message == NULL) {
240 ERR("Failed to get Wi-Fi technology state");
241 return NETCONFIG_WIFI_TECH_UNKNOWN;
244 dbus_message_iter_init(message, &iter);
245 dbus_message_iter_recurse(&iter, &array);
247 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
248 DBusMessageIter entry, dict;
251 dbus_message_iter_recurse(&array, &entry);
252 dbus_message_iter_get_basic(&entry, &path);
254 dbus_message_iter_next(&entry);
255 dbus_message_iter_recurse(&entry, &dict);
258 g_str_equal(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == FALSE) {
259 dbus_message_iter_next(&array);
263 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
264 DBusMessageIter entry1, value1;
265 const char *key, *sdata;
268 dbus_message_iter_recurse(&dict, &entry1);
269 dbus_message_iter_get_basic(&entry1, &key);
271 dbus_message_iter_next(&entry1);
272 dbus_message_iter_recurse(&entry1, &value1);
274 if (dbus_message_iter_get_arg_type(&value1) ==
276 dbus_message_iter_get_basic(&value1, &data);
277 DBG("key-[%s] - %s", key, data ? "True" : "False");
279 if (strcmp(key, "Powered") == 0 && data) {
280 wifi_tech_powered = TRUE;
281 } else if (strcmp(key, "Connected") == 0 && data) {
282 wifi_tech_connected = TRUE;
283 } else if (strcmp(key, "Tethering") == 0 && data) {
284 /* For further use */
286 } else if (dbus_message_iter_get_arg_type(&value1) ==
288 dbus_message_iter_get_basic(&value1, &sdata);
291 dbus_message_iter_next(&dict);
294 dbus_message_iter_next(&array);
297 dbus_message_unref(message);
299 if (wifi_tech_powered)
300 ret = NETCONFIG_WIFI_TECH_POWERED;
302 if (wifi_tech_connected)
303 ret = NETCONFIG_WIFI_TECH_CONNECTED;
308 void netconfig_wifi_update_power_state(gboolean powered)
312 /* It's automatically updated by signal-handler
313 * DO NOT update manually
314 * It includes Wi-Fi state configuration
316 vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
318 if (powered == TRUE) {
319 if (wifi_state == VCONFKEY_WIFI_OFF &&
320 netconfig_is_wifi_direct_on() != TRUE &&
321 netconfig_is_wifi_tethering_on() != TRUE) {
322 DBG("Wi-Fi successfully turned on or waken up from power-save mode");
324 vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
325 vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_ON);
326 vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
328 netconfig_wifi_notify_power_completed(TRUE);
330 netconfig_wifi_device_picker_service_start();
332 netconfig_wifi_bgscan_start();
335 if (wifi_state != VCONFKEY_WIFI_OFF) {
336 DBG("Wi-Fi successfully turned off or in power-save mode");
338 netconfig_wifi_device_picker_service_stop();
340 netconfig_wifi_remove_driver();
342 vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF);
343 vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_OFF);
344 vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF);
346 netconfig_wifi_notify_power_completed(FALSE);
348 netconfig_del_wifi_found_notification();
350 netconfig_wifi_bgscan_stop();
352 __netconfig_wifi_set_profiles_count(0);
357 char *netconfig_wifi_get_favorite_service(void)
359 return __netconfig_wifi_get_connman_favorite_service();
362 void netconfig_wifi_check_network_notification(DBusMessage *message)
364 DBusMessageIter iter;
365 int profiles_count = 0;
366 int qs_enable, ug_state;
368 if (netconfig_wifi_state_get_service_state() == NETCONFIG_WIFI_CONNECTED) {
369 DBG("Service state is connected");
373 if (vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &qs_enable) == -1) {
374 DBG("Fail to get %s", VCONFKEY_WIFI_ENABLE_QS);
378 if (qs_enable != VCONFKEY_WIFI_QS_ENABLE) {
379 DBG("qs_enable != VCONFKEY_WIFI_QS_ENABLE");
383 if (vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state) == -1) {
384 DBG("Fail to get %s", VCONFKEY_WIFI_UG_RUN_STATE);
388 if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) {
389 DBG("ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND");
393 if (message == NULL) {
394 ERR("Failed to get service list");
398 dbus_message_iter_init(message, &iter);
399 DBusMessageIter array, value;
400 dbus_message_iter_recurse(&iter, &array);
401 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) {
402 DBG("Array not found. type %d", dbus_message_iter_get_arg_type(&array));
406 dbus_message_iter_recurse(&array, &value);
407 while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
408 const char *object_path = NULL;
410 dbus_message_iter_get_basic(&value, &object_path);
412 DBG("found a profile: %s", object_path);
413 if (netconfig_is_wifi_profile(object_path) == TRUE) {
415 DBG("Total wifi profile cnt = %d", profiles_count);
418 dbus_message_iter_next(&array);
419 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) {
420 DBG("Not a structure entry. Arg type = %d", dbus_message_iter_get_arg_type(&array));
423 dbus_message_iter_recurse(&array, &value);
426 if (__netconfig_wifi_get_profiles_count() != profiles_count) {
427 DBG("profiles prev_count (%d) - profiles count (%d)",
428 __netconfig_wifi_get_profiles_count(), profiles_count);
430 netconfig_add_wifi_found_notification();
431 __netconfig_wifi_set_profiles_count(profiles_count);
433 DBG("No change in profile count[%d]", profiles_count);
436 void netconfig_wifi_state_notifier_cleanup(void)
438 g_slist_free_full(notifier_list, NULL);
441 void netconfig_wifi_state_notifier_register(
442 struct netconfig_wifi_state_notifier *notifier)
444 DBG("register notifier");
446 notifier_list = g_slist_append(notifier_list, notifier);
449 void netconfig_wifi_state_notifier_unregister(
450 struct netconfig_wifi_state_notifier *notifier)
452 DBG("un-register notifier");
454 notifier_list = g_slist_remove_all(notifier_list, notifier);