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>
22 #include <notification.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)
154 int wifi_ug_state = 0;
155 notification_error_e err = NOTIFICATION_ERROR_NONE;
157 vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state);
158 if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
161 DBG("Launch 3G alert network popup");
162 // TODO : display a popup
164 notification_h noti = NULL;
166 noti = notification_create(NOTIFICATION_TYPE_NOTI);
168 ERR("Failed to create notification \n");
172 err = notification_set_pkgname(noti, NET_CONFIG_APP_NAME);
173 if (err != NOTIFICATION_ERROR_NONE) {
174 ERR("Unable to set pkgname \n");
178 err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_TITLE, "Cellular connection popup", NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
179 if (err != NOTIFICATION_ERROR_NONE) {
180 ERR("Unable to set notification title \n");
184 err = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT, "Connected" , NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
185 if (err != NOTIFICATION_ERROR_NONE) {
186 ERR("Unable to set notification content \n");
190 err = notification_insert(noti, NULL);
191 if (err != NOTIFICATION_ERROR_NONE) {
192 ERR("Unable to insert notification \n");
198 static gboolean __netconfig_is_connected(const char *profile)
200 gboolean is_connected = FALSE;
201 DBusMessage *message = NULL;
202 DBusMessageIter iter, array;
207 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile,
208 CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
209 if (message == NULL) {
210 ERR("Failed to get service properties");
214 if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
215 const char *ptr = dbus_message_get_error_name(message);
216 ERR("Error!!! Error message received [%s]", ptr);
220 dbus_message_iter_init(message, &iter);
221 dbus_message_iter_recurse(&iter, &array);
223 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
224 DBusMessageIter entry, string;
225 const char *key = NULL;
227 dbus_message_iter_recurse(&array, &entry);
228 dbus_message_iter_get_basic(&entry, &key);
230 if (g_str_equal(key, "State") == TRUE) {
231 dbus_message_iter_next(&entry);
232 dbus_message_iter_recurse(&entry, &string);
234 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
235 dbus_message_iter_get_basic(&string, &key);
237 if (g_str_equal(key, "ready") == TRUE ||
238 g_str_equal(key, "online") == TRUE) {
246 dbus_message_iter_next(&array);
251 dbus_message_unref(message);
256 static char *__netconfig_get_default_profile(void)
258 DBusMessage *message = NULL;
259 GSList *service_profiles = NULL;
261 DBusMessageIter iter, dict;
262 char *default_profile = NULL;
264 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
265 CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
266 "GetServices", NULL);
267 if (message == NULL) {
268 ERR("Failed to get profiles");
272 dbus_message_iter_init(message, &iter);
273 dbus_message_iter_recurse(&iter, &dict);
275 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
276 DBusMessageIter entry;
277 const char *object_path = NULL;
279 dbus_message_iter_recurse(&dict, &entry);
280 dbus_message_iter_get_basic(&entry, &object_path);
283 service_profiles = g_slist_append(
285 g_strdup(object_path));
287 dbus_message_iter_next(&dict);
290 for (list = service_profiles; list != NULL; list = list->next) {
291 char *profile_path = list->data;
293 if (__netconfig_is_connected((const char *)profile_path) == TRUE) {
294 default_profile = g_strdup(profile_path);
299 g_slist_free(service_profiles);
301 dbus_message_unref(message);
303 return default_profile;
306 static void __netconfig_get_default_connection_info(const char *profile)
308 DBusMessage *message = NULL;
309 DBusMessageIter iter, array;
311 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile,
312 CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
313 if (message == NULL) {
314 ERR("Failed to get service properties");
318 if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
319 const char *ptr = dbus_message_get_error_name(message);
320 ERR("Error!!! Error message received [%s]", ptr);
324 dbus_message_iter_init(message, &iter);
325 dbus_message_iter_recurse(&iter, &array);
327 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
328 DBusMessageIter entry, variant, string, iter1, iter2, iter3;
329 const char *key = NULL, *value = NULL;
331 dbus_message_iter_recurse(&array, &entry);
332 dbus_message_iter_get_basic(&entry, &key);
334 if (g_str_equal(key, "Name") == TRUE &&
335 netconfig_is_wifi_profile(profile) == TRUE) {
336 dbus_message_iter_next(&entry);
337 dbus_message_iter_recurse(&entry, &string);
339 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
340 dbus_message_iter_get_basic(&string, &value);
342 netconfig_default_connection_info.essid = g_strdup(value);
344 } else if (g_str_equal(key, "Ethernet") == TRUE) {
345 dbus_message_iter_next(&entry);
346 dbus_message_iter_recurse(&entry, &variant);
347 dbus_message_iter_recurse(&variant, &iter1);
349 while (dbus_message_iter_get_arg_type(&iter1)
350 == DBUS_TYPE_DICT_ENTRY) {
351 dbus_message_iter_recurse(&iter1, &iter2);
352 dbus_message_iter_get_basic(&iter2, &key);
354 if (g_str_equal(key, "Interface") == TRUE) {
355 dbus_message_iter_next(&iter2);
356 dbus_message_iter_recurse(&iter2, &iter3);
357 dbus_message_iter_get_basic(&iter3, &value);
359 netconfig_default_connection_info.ifname = g_strdup(value);
362 dbus_message_iter_next(&iter1);
364 } else if (g_str_equal(key, "IPv4") == TRUE) {
365 dbus_message_iter_next(&entry);
366 dbus_message_iter_recurse(&entry, &variant);
367 dbus_message_iter_recurse(&variant, &iter1);
369 while (dbus_message_iter_get_arg_type(&iter1)
370 == DBUS_TYPE_DICT_ENTRY) {
371 dbus_message_iter_recurse(&iter1, &iter2);
372 dbus_message_iter_get_basic(&iter2, &key);
374 if (g_str_equal(key, "Address") == TRUE) {
375 dbus_message_iter_next(&iter2);
376 dbus_message_iter_recurse(&iter2, &iter3);
377 dbus_message_iter_get_basic(&iter3, &value);
379 netconfig_default_connection_info.ipaddress = g_strdup(value);
382 dbus_message_iter_next(&iter1);
384 } else if (g_str_equal(key, "IPv6") == TRUE) {
385 dbus_message_iter_next(&entry);
386 dbus_message_iter_recurse(&entry, &variant);
387 dbus_message_iter_recurse(&variant, &iter1);
389 while (dbus_message_iter_get_arg_type(&iter1)
390 == DBUS_TYPE_DICT_ENTRY) {
391 dbus_message_iter_recurse(&iter1, &iter2);
392 dbus_message_iter_get_basic(&iter2, &key);
394 if (g_str_equal(key, "Address") == TRUE) {
395 dbus_message_iter_next(&iter2);
396 dbus_message_iter_recurse(&iter2, &iter3);
397 dbus_message_iter_get_basic(&iter3, &value);
399 netconfig_default_connection_info.ipaddress = g_strdup(value);
402 dbus_message_iter_next(&iter1);
404 } else if (g_str_equal(key, "Proxy") == TRUE) {
405 dbus_message_iter_next(&entry);
406 dbus_message_iter_recurse(&entry, &variant);
407 dbus_message_iter_recurse(&variant, &iter1);
409 while (dbus_message_iter_get_arg_type(&iter1)
410 == DBUS_TYPE_DICT_ENTRY) {
411 DBusMessageIter iter4;
413 dbus_message_iter_recurse(&iter1, &iter2);
414 dbus_message_iter_get_basic(&iter2, &key);
416 if (g_str_equal(key, "Servers") == TRUE) {
417 dbus_message_iter_next(&iter2);
418 dbus_message_iter_recurse(&iter2, &iter3);
419 if (dbus_message_iter_get_arg_type(&iter3)
423 dbus_message_iter_recurse(&iter3, &iter4);
424 if (dbus_message_iter_get_arg_type(&iter4)
428 dbus_message_iter_get_basic(&iter4, &value);
429 if (value != NULL && (strlen(value) > 0))
430 netconfig_default_connection_info.proxy = g_strdup(value);
432 } else if (g_str_equal(key, "Method") == TRUE) {
433 dbus_message_iter_next(&iter2);
434 dbus_message_iter_recurse(&iter2, &iter3);
435 if (dbus_message_iter_get_arg_type(&iter3)
439 dbus_message_iter_get_basic(&iter3, &value);
440 if (g_strcmp0(value, "direct") == 0) {
441 g_free(netconfig_default_connection_info.proxy);
442 netconfig_default_connection_info.proxy = NULL;
448 dbus_message_iter_next(&iter1);
452 dbus_message_iter_next(&array);
457 dbus_message_unref(message);
460 static void __netconfig_update_default_connection_info(void)
462 int old_network_status = 0;
463 const char *profile = netconfig_get_default_profile();
464 const char *ip_addr = netconfig_get_default_ipaddress();
465 const char *proxy_addr = netconfig_get_default_proxy();
467 if (netconfig_emulator_is_emulated() == TRUE)
471 DBG("Reset network state configuration");
473 DBG("%s: ip(%s) proxy(%s)", profile, ip_addr, proxy_addr);
475 vconf_get_int(VCONFKEY_NETWORK_STATUS, &old_network_status);
477 if (profile == NULL && old_network_status != VCONFKEY_NETWORK_OFF) {
478 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF);
480 vconf_set_str(VCONFKEY_NETWORK_IP, "");
481 vconf_set_str(VCONFKEY_NETWORK_PROXY, "");
483 vconf_set_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 0);
485 DBG("Successfully clear IP and PROXY up");
486 } else if (profile != NULL) {
487 char *old_ip = vconf_get_str(VCONFKEY_NETWORK_IP);
488 char *old_proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
490 if (netconfig_is_wifi_profile(profile) == TRUE) {
491 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_WIFI);
492 } else if (netconfig_is_cellular_profile(profile) == TRUE) {
493 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_CELLULAR);
495 if (old_network_status != VCONFKEY_NETWORK_CELLULAR)
496 __netconfig_pop_3g_alert_syspoppup();
497 } else if (netconfig_is_ethernet_profile(profile) == TRUE) {
498 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_ETHERNET);
499 } else if (netconfig_is_bluetooth_profile(profile) == TRUE) {
500 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_BLUETOOTH);
502 vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF);
505 if (g_strcmp0(old_ip, ip_addr) != 0) {
507 vconf_set_str(VCONFKEY_NETWORK_IP, "");
509 vconf_set_str(VCONFKEY_NETWORK_IP, ip_addr);
512 if (g_strcmp0(old_proxy, proxy_addr) != 0) {
513 if (proxy_addr == NULL)
514 vconf_set_str(VCONFKEY_NETWORK_PROXY, "");
516 vconf_set_str(VCONFKEY_NETWORK_PROXY, proxy_addr);
519 vconf_set_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 1);
521 DBG("Successfully update default network configuration");
525 const char *netconfig_get_default_profile(void)
527 return netconfig_default_connection_info.profile;
530 const char *netconfig_get_default_ipaddress(void)
532 return netconfig_default_connection_info.ipaddress;
535 const char *netconfig_get_default_proxy(void)
537 return netconfig_default_connection_info.proxy;
540 const char *netconfig_wifi_get_connected_essid(const char *default_profile)
542 if (default_profile == NULL)
545 if (netconfig_is_wifi_profile(default_profile) != TRUE)
548 if (g_str_equal(default_profile, netconfig_default_connection_info.profile)
552 return netconfig_default_connection_info.essid;
555 void netconfig_set_default_profile(const char *profile)
557 char *default_profile = NULL;
559 /* It's automatically updated by signal-handler
560 * DO NOT update manually
562 * It is going to update default connection information
564 if (netconfig_default_connection_info.profile != NULL) {
565 g_free(netconfig_default_connection_info.profile);
566 netconfig_default_connection_info.profile = NULL;
568 g_free(netconfig_default_connection_info.ifname);
569 netconfig_default_connection_info.ifname = NULL;
571 g_free(netconfig_default_connection_info.ipaddress);
572 netconfig_default_connection_info.ipaddress = NULL;
574 g_free(netconfig_default_connection_info.proxy);
575 netconfig_default_connection_info.proxy = NULL;
577 if (netconfig_wifi_state_get_service_state()
578 != NETCONFIG_WIFI_CONNECTED) {
579 g_free(netconfig_default_connection_info.essid);
580 netconfig_default_connection_info.essid = NULL;
584 if (profile == NULL) {
585 default_profile = __netconfig_get_default_profile();
586 if (default_profile == NULL) {
587 __netconfig_update_default_connection_info();
593 netconfig_default_connection_info.profile = g_strdup(profile);
595 netconfig_default_connection_info.profile = default_profile;
597 __netconfig_get_default_connection_info(
598 netconfig_default_connection_info.profile);
600 __netconfig_update_default_connection_info();
603 gboolean netconfig_iface_network_state_add_route(
604 NetconfigNetworkState *master,
605 gchar *ip_addr, gchar *netmask,
606 gchar *interface, gboolean *result, GError **error)
608 gboolean ret = FALSE;
610 const char *path = ROUTE_EXEC_PATH;
611 char *const args[] = {"route", "add",
616 char *const envs[] = { NULL };
618 DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface);
620 if (ip_addr == NULL || netmask == NULL || interface == NULL) {
621 DBG("Invalid parameter!");
625 rv = netconfig_execute_file(path, args, envs);
627 DBG("Failed to add a new route");
631 DBG("Successfully added a new route");
639 gboolean netconfig_iface_network_state_remove_route(
640 NetconfigNetworkState *master,
641 gchar *ip_addr, gchar *netmask,
642 gchar *interface, gboolean *result, GError **error)
644 gboolean ret = FALSE;
646 const char *path = ROUTE_EXEC_PATH;
647 char *const args[] = {"route", "del",
652 char *const envs[] = { NULL };
654 DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface);
656 if (ip_addr == NULL || netmask == NULL || interface == NULL) {
657 DBG("Invalid parameter!");
661 rv = netconfig_execute_file(path, args, envs);
663 DBG("Failed to remove a new route");
667 DBG("Successfully remove a new route");
675 gpointer netconfig_network_state_create_and_init(DBusGConnection *conn)
679 g_return_val_if_fail(conn != NULL, NULL);
681 object = g_object_new(NETCONFIG_TYPE_NETWORK_STATE, "conn", conn, "path",
682 NETCONFIG_NETWORK_STATE_PATH, NULL);
684 INFO("create network_state(%p)", object);
686 dbus_g_connection_register_g_object(conn, NETCONFIG_NETWORK_STATE_PATH, object);
688 INFO("network_state(%p) register DBus path(%s)", object, NETCONFIG_NETWORK_STATE_PATH);