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>
30 #include "wifi-state.h"
31 #include "network-state.h"
33 #define NETCONFIG_NETWORK_STATE_PATH "/net/netconfig/network"
34 #define ROUTE_EXEC_PATH "/sbin/route"
36 #define PROP_DEFAULT FALSE
37 #define PROP_DEFAULT_STR NULL
40 gboolean netconfig_iface_network_state_add_route(
41 NetconfigNetworkState *master,
42 gchar *ip_addr, gchar *netmask,
43 gchar *interface, gboolean *result, GError **error);
45 gboolean netconfig_iface_network_state_remove_route(
46 NetconfigNetworkState *master,
47 gchar *ip_addr, gchar *netmask,
48 gchar *interface, gboolean *result, GError **error);
50 #include "netconfig-iface-network-state-glue.h"
54 PROP_NETWORK_STATE_CONN,
55 PROP_NETWORK_STATE_PATH,
58 struct NetconfigNetworkStateClass {
62 struct NetconfigNetworkState {
65 DBusGConnection *conn;
69 G_DEFINE_TYPE(NetconfigNetworkState, netconfig_network_state, G_TYPE_OBJECT);
72 static void __netconfig_network_state_gobject_get_property(GObject *object,
73 guint prop_id, GValue *value, GParamSpec *pspec)
78 static void __netconfig_network_state_gobject_set_property(GObject *object,
79 guint prop_id, const GValue *value, GParamSpec *pspec)
81 NetconfigNetworkState *network_state = NETCONFIG_NETWORK_STATE(object);
84 case PROP_NETWORK_STATE_CONN:
86 network_state->conn = g_value_get_boxed(value);
87 INFO("network_state(%p) set conn(%p)", network_state, network_state->conn);
91 case PROP_NETWORK_STATE_PATH:
93 if (network_state->path)
94 g_free(network_state->path);
96 network_state->path = g_value_dup_string(value);
97 INFO("network_state(%p) path(%s)", network_state, network_state->path);
103 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
107 static void netconfig_network_state_init(NetconfigNetworkState *network_state)
109 DBG("network_state initialize");
111 network_state->conn = NULL;
112 network_state->path = g_strdup(PROP_DEFAULT_STR);
115 static void netconfig_network_state_class_init(NetconfigNetworkStateClass *klass)
117 GObjectClass *object_class = G_OBJECT_CLASS(klass);
119 DBG("class initialize");
121 object_class->get_property = __netconfig_network_state_gobject_get_property;
122 object_class->set_property = __netconfig_network_state_gobject_set_property;
125 dbus_g_object_type_install_info(NETCONFIG_TYPE_NETWORK_STATE,
126 &dbus_glib_netconfig_iface_network_state_object_info);
129 g_object_class_install_property(object_class, PROP_NETWORK_STATE_CONN,
130 g_param_spec_boxed("conn", "CONNECTION", "DBus connection",
131 DBUS_TYPE_G_CONNECTION,
132 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
134 g_object_class_install_property(object_class, PROP_NETWORK_STATE_PATH,
135 g_param_spec_string("path", "Path", "Object path",
137 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
140 struct netconfig_default_connection {
148 static struct netconfig_default_connection
149 netconfig_default_connection_info;
151 static void __netconfig_pop_3g_alert_syspoppup(void)
155 int wifi_ug_state = 0;
157 vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state);
158 if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
163 bundle_add(b, "_SYSPOPUP_TITLE_", "Cellular connection popup");
164 bundle_add(b, "_SYSPOPUP_TYPE_", "notification");
165 bundle_add(b, "_SYSPOPUP_CONTENT_", "connected");
167 DBG("Launch 3G alert network popup");
168 rv = aul_launch_app("org.tizen.net-popup", b);
173 static gboolean __netconfig_is_connected(const char *profile)
175 gboolean is_connected = FALSE;
176 DBusMessage *message = NULL;
177 DBusMessageIter iter, array;
182 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile,
183 CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
184 if (message == NULL) {
185 ERR("Failed to get service properties");
189 if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
190 const char *ptr = dbus_message_get_error_name(message);
191 ERR("Error!!! Error message received [%s]", ptr);
195 dbus_message_iter_init(message, &iter);
196 dbus_message_iter_recurse(&iter, &array);
198 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
199 DBusMessageIter entry, string;
200 const char *key = NULL;
202 dbus_message_iter_recurse(&array, &entry);
203 dbus_message_iter_get_basic(&entry, &key);
205 if (g_str_equal(key, "State") == TRUE) {
206 dbus_message_iter_next(&entry);
207 dbus_message_iter_recurse(&entry, &string);
209 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
210 dbus_message_iter_get_basic(&string, &key);
212 if (g_str_equal(key, "ready") == TRUE ||
213 g_str_equal(key, "online") == TRUE) {
221 dbus_message_iter_next(&array);
226 dbus_message_unref(message);
231 static char *__netconfig_get_default_profile(void)
233 DBusMessage *message = NULL;
234 GSList *service_profiles = NULL;
236 DBusMessageIter iter, dict;
237 char *default_profile = NULL;
239 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
240 CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
241 "GetServices", NULL);
242 if (message == NULL) {
243 ERR("Failed to get profiles");
247 dbus_message_iter_init(message, &iter);
248 dbus_message_iter_recurse(&iter, &dict);
250 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
251 DBusMessageIter entry;
252 const char *object_path = NULL;
254 dbus_message_iter_recurse(&dict, &entry);
255 dbus_message_iter_get_basic(&entry, &object_path);
258 service_profiles = g_slist_append(
260 g_strdup(object_path));
262 dbus_message_iter_next(&dict);
265 for (list = service_profiles; list != NULL; list = list->next) {
266 char *profile_path = list->data;
268 if (__netconfig_is_connected((const char *)profile_path) == TRUE) {
269 default_profile = g_strdup(profile_path);
274 g_slist_free(service_profiles);
276 dbus_message_unref(message);
278 return default_profile;
281 static void __netconfig_get_default_connection_info(const char *profile)
283 DBusMessage *message = NULL;
284 DBusMessageIter iter, array;
286 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile,
287 CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
288 if (message == NULL) {
289 ERR("Failed to get service properties");
293 if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
294 const char *ptr = dbus_message_get_error_name(message);
295 ERR("Error!!! Error message received [%s]", ptr);
299 dbus_message_iter_init(message, &iter);
300 dbus_message_iter_recurse(&iter, &array);
302 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
303 DBusMessageIter entry, variant, string, iter1, iter2, iter3;
304 const char *key = NULL, *value = NULL;
306 dbus_message_iter_recurse(&array, &entry);
307 dbus_message_iter_get_basic(&entry, &key);
309 if (g_str_equal(key, "Name") == TRUE &&
310 netconfig_is_wifi_profile(profile) == TRUE) {
311 dbus_message_iter_next(&entry);
312 dbus_message_iter_recurse(&entry, &string);
314 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
315 dbus_message_iter_get_basic(&string, &value);
317 netconfig_default_connection_info.essid = g_strdup(value);
319 } else if (g_str_equal(key, "Ethernet") == TRUE) {
320 dbus_message_iter_next(&entry);
321 dbus_message_iter_recurse(&entry, &variant);
322 dbus_message_iter_recurse(&variant, &iter1);
324 while (dbus_message_iter_get_arg_type(&iter1)
325 == DBUS_TYPE_DICT_ENTRY) {
326 dbus_message_iter_recurse(&iter1, &iter2);
327 dbus_message_iter_get_basic(&iter2, &key);
329 if (g_str_equal(key, "Interface") == TRUE) {
330 dbus_message_iter_next(&iter2);
331 dbus_message_iter_recurse(&iter2, &iter3);
332 dbus_message_iter_get_basic(&iter3, &value);
334 netconfig_default_connection_info.ifname = g_strdup(value);
337 dbus_message_iter_next(&iter1);
339 } else if (g_str_equal(key, "IPv4") == TRUE) {
340 dbus_message_iter_next(&entry);
341 dbus_message_iter_recurse(&entry, &variant);
342 dbus_message_iter_recurse(&variant, &iter1);
344 while (dbus_message_iter_get_arg_type(&iter1)
345 == DBUS_TYPE_DICT_ENTRY) {
346 dbus_message_iter_recurse(&iter1, &iter2);
347 dbus_message_iter_get_basic(&iter2, &key);
349 if (g_str_equal(key, "Address") == TRUE) {
350 dbus_message_iter_next(&iter2);
351 dbus_message_iter_recurse(&iter2, &iter3);
352 dbus_message_iter_get_basic(&iter3, &value);
354 netconfig_default_connection_info.ipaddress = g_strdup(value);
357 dbus_message_iter_next(&iter1);
359 } else if (g_str_equal(key, "IPv6") == TRUE) {
360 dbus_message_iter_next(&entry);
361 dbus_message_iter_recurse(&entry, &variant);
362 dbus_message_iter_recurse(&variant, &iter1);
364 while (dbus_message_iter_get_arg_type(&iter1)
365 == DBUS_TYPE_DICT_ENTRY) {
366 dbus_message_iter_recurse(&iter1, &iter2);
367 dbus_message_iter_get_basic(&iter2, &key);
369 if (g_str_equal(key, "Address") == TRUE) {
370 dbus_message_iter_next(&iter2);
371 dbus_message_iter_recurse(&iter2, &iter3);
372 dbus_message_iter_get_basic(&iter3, &value);
374 netconfig_default_connection_info.ipaddress = g_strdup(value);
377 dbus_message_iter_next(&iter1);
379 } else if (g_str_equal(key, "Proxy") == TRUE) {
380 dbus_message_iter_next(&entry);
381 dbus_message_iter_recurse(&entry, &variant);
382 dbus_message_iter_recurse(&variant, &iter1);
384 while (dbus_message_iter_get_arg_type(&iter1)
385 == DBUS_TYPE_DICT_ENTRY) {
386 DBusMessageIter iter4;
388 dbus_message_iter_recurse(&iter1, &iter2);
389 dbus_message_iter_get_basic(&iter2, &key);
391 if (g_str_equal(key, "Servers") == TRUE) {
392 dbus_message_iter_next(&iter2);
393 dbus_message_iter_recurse(&iter2, &iter3);
394 if (dbus_message_iter_get_arg_type(&iter3)
398 dbus_message_iter_recurse(&iter3, &iter4);
399 if (dbus_message_iter_get_arg_type(&iter4)
403 dbus_message_iter_get_basic(&iter4, &value);
404 if (value != NULL && (strlen(value) > 0))
405 netconfig_default_connection_info.proxy = g_strdup(value);
407 } else if (g_str_equal(key, "Method") == TRUE) {
408 dbus_message_iter_next(&iter2);
409 dbus_message_iter_recurse(&iter2, &iter3);
410 if (dbus_message_iter_get_arg_type(&iter3)
414 dbus_message_iter_get_basic(&iter3, &value);
415 if (g_strcmp0(value, "direct") == 0) {
416 g_free(netconfig_default_connection_info.proxy);
417 netconfig_default_connection_info.proxy = NULL;
423 dbus_message_iter_next(&iter1);
427 dbus_message_iter_next(&array);
432 dbus_message_unref(message);
435 static void __netconfig_update_default_connection_info(void)
437 int old_network_status = 0;
438 const char *profile = netconfig_get_default_profile();
439 const char *ip_addr = netconfig_get_default_ipaddress();
440 const char *proxy_addr = netconfig_get_default_proxy();
442 if (netconfig_emulator_is_emulated() == TRUE)
446 DBG("Reset network state configuration");
448 DBG("%s: ip(%s) proxy(%s)", profile, ip_addr, proxy_addr);
450 vconf_get_int(VCONFKEY_NETWORK_STATUS, &old_network_status);
452 if (profile == NULL && old_network_status != VCONFKEY_NETWORK_OFF) {
453 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF);
455 vconf_set_str(VCONFKEY_NETWORK_IP, "");
456 vconf_set_str(VCONFKEY_NETWORK_PROXY, "");
458 vconf_set_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 0);
460 DBG("Successfully clear IP and PROXY up");
461 } else if (profile != NULL) {
462 char *old_ip = vconf_get_str(VCONFKEY_NETWORK_IP);
463 char *old_proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
465 if (netconfig_is_wifi_profile(profile) == TRUE) {
466 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_WIFI);
467 } else if (netconfig_is_cellular_profile(profile) == TRUE) {
468 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_CELLULAR);
470 if (old_network_status != VCONFKEY_NETWORK_CELLULAR)
471 __netconfig_pop_3g_alert_syspoppup();
472 } else if (netconfig_is_ethernet_profile(profile) == TRUE) {
473 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_ETHERNET);
474 } else if (netconfig_is_bluetooth_profile(profile) == TRUE) {
475 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_BLUETOOTH);
477 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF);
480 if (g_strcmp0(old_ip, ip_addr) != 0) {
482 vconf_set_str(VCONFKEY_NETWORK_IP, "");
484 vconf_set_str(VCONFKEY_NETWORK_IP, ip_addr);
487 if (g_strcmp0(old_proxy, proxy_addr) != 0) {
488 if (proxy_addr == NULL)
489 vconf_set_str(VCONFKEY_NETWORK_PROXY, "");
491 vconf_set_str(VCONFKEY_NETWORK_PROXY, proxy_addr);
494 vconf_set_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 1);
496 DBG("Successfully update default network configuration");
500 const char *netconfig_get_default_profile(void)
502 return netconfig_default_connection_info.profile;
505 const char *netconfig_get_default_ipaddress(void)
507 return netconfig_default_connection_info.ipaddress;
510 const char *netconfig_get_default_proxy(void)
512 return netconfig_default_connection_info.proxy;
515 const char *netconfig_wifi_get_connected_essid(const char *default_profile)
517 if (default_profile == NULL)
520 if (netconfig_is_wifi_profile(default_profile) != TRUE)
523 if (g_str_equal(default_profile, netconfig_default_connection_info.profile)
527 return netconfig_default_connection_info.essid;
530 void netconfig_set_default_profile(const char *profile)
532 char *default_profile = NULL;
534 /* It's automatically updated by signal-handler
535 * DO NOT update manually
537 * It is going to update default connection information
539 if (netconfig_default_connection_info.profile != NULL) {
540 g_free(netconfig_default_connection_info.profile);
541 netconfig_default_connection_info.profile = NULL;
543 g_free(netconfig_default_connection_info.ifname);
544 netconfig_default_connection_info.ifname = NULL;
546 g_free(netconfig_default_connection_info.ipaddress);
547 netconfig_default_connection_info.ipaddress = NULL;
549 g_free(netconfig_default_connection_info.proxy);
550 netconfig_default_connection_info.proxy = NULL;
552 if (netconfig_wifi_state_get_service_state()
553 != NETCONFIG_WIFI_CONNECTED) {
554 g_free(netconfig_default_connection_info.essid);
555 netconfig_default_connection_info.essid = NULL;
559 if (profile == NULL) {
560 default_profile = __netconfig_get_default_profile();
561 if (default_profile == NULL) {
562 __netconfig_update_default_connection_info();
568 netconfig_default_connection_info.profile = g_strdup(profile);
570 netconfig_default_connection_info.profile = default_profile;
572 __netconfig_get_default_connection_info(
573 netconfig_default_connection_info.profile);
575 __netconfig_update_default_connection_info();
578 gboolean netconfig_iface_network_state_add_route(
579 NetconfigNetworkState *master,
580 gchar *ip_addr, gchar *netmask,
581 gchar *interface, gboolean *result, GError **error)
583 gboolean ret = FALSE;
585 const char *path = ROUTE_EXEC_PATH;
586 char *const args[] = {"route", "add",
591 char *const envs[] = { NULL };
593 DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface);
595 if (ip_addr == NULL || netmask == NULL || interface == NULL) {
596 DBG("Invalid parameter!");
600 rv = netconfig_execute_file(path, args, envs);
602 DBG("Failed to add a new route");
606 DBG("Successfully added a new route");
614 gboolean netconfig_iface_network_state_remove_route(
615 NetconfigNetworkState *master,
616 gchar *ip_addr, gchar *netmask,
617 gchar *interface, gboolean *result, GError **error)
619 gboolean ret = FALSE;
621 const char *path = ROUTE_EXEC_PATH;
622 char *const args[] = {"route", "del",
627 char *const envs[] = { NULL };
629 DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface);
631 if (ip_addr == NULL || netmask == NULL || interface == NULL) {
632 DBG("Invalid parameter!");
636 rv = netconfig_execute_file(path, args, envs);
638 DBG("Failed to remove a new route");
642 DBG("Successfully remove a new route");
650 gpointer netconfig_network_state_create_and_init(DBusGConnection *conn)
654 g_return_val_if_fail(conn != NULL, NULL);
656 object = g_object_new(NETCONFIG_TYPE_NETWORK_STATE, "conn", conn, "path",
657 NETCONFIG_NETWORK_STATE_PATH, NULL);
659 INFO("create network_state(%p)", object);
661 dbus_g_connection_register_g_object(conn, NETCONFIG_NETWORK_STATE_PATH, object);
663 INFO("network_state(%p) register DBus path(%s)", object, NETCONFIG_NETWORK_STATE_PATH);