2 * Network Configuration Module
4 * Copyright (c) 2000 - 2012 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.
22 #include <sys/types.h>
33 #include "wifi-config.h"
35 #define CONNMAN_STORAGE "/var/lib/connman"
36 #define WIFI_CONFIG_PREFIX "wifi_"
38 #define WIFI_CONFIG_NAME "Name"
39 #define WIFI_CONFIG_SSID "SSID"
40 #define WIFI_CONFIG_PASSPHRASE "Passphrase"
41 #define WIFI_CONFIG_SECURITY_TYPE "Security"
42 #define WIFI_CONFIG_FAVORITE "Favorite"
43 #define WIFI_CONFIG_AUTOCONNECT "AutoConnect"
44 #define WIFI_CONFIG_HIDDEN "Hidden"
45 #define WIFI_CONFIG_FAILURE "Failure"
46 #define WIFI_CONFIG_PROXYADDRESS "ProxyAddress"
47 #define WIFI_CONFIG_PROXY_METHOD "Proxy.Method"
48 #define WIFI_CONFIG_PROXY_SERVER "Proxy.Servers"
50 #define WIFI_SECURITY_NONE "none"
51 #define WIFI_SECURITY_WEP "wep"
52 #define WIFI_SECURITY_WPA_PSK "psk"
53 #define WIFI_SECURITY_EAP "ieee8021x"
55 #define WIFI_PREFIX_LENGTH 18 // wifi_485a3f2f506a_
69 static gint __netconfig_get_mac_address(gchar **mac_address)
71 gchar *tmp_mac = NULL;
73 gchar mac[13] = { 0, };
76 tmp_mac = vconf_get_str(VCONFKEY_WIFI_BSSID_ADDRESS);
77 if (tmp_mac == NULL) {
78 ERR("vconf_get_str(WIFI_BSSID_ADDRESS) Failed");
82 tmp = g_ascii_strdown(tmp_mac, (gssize)strlen(tmp_mac));
92 *mac_address = g_strdup(mac);
97 static gboolean ___netconfig_remove_file(const gchar *pathname, const gchar *filename)
102 path = g_strdup_printf("%s/%s", pathname, filename);
103 if (g_file_test(path, G_FILE_TEST_EXISTS) == FALSE) {
105 } else if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == TRUE) {
114 static gboolean __netconfig_remove_configuration(const gchar *pathname)
118 if (___netconfig_remove_file(pathname, "settings") != TRUE) {
119 ERR("Cannot remove [%s/settings]", pathname);
122 if (___netconfig_remove_file(pathname, "data") != TRUE) {
123 ERR("Cannot remove [%s/data]", pathname);
127 ret = rmdir(pathname);
129 ERR("Cannot remove [%s]", pathname);
136 static gint _netconfig_get_security_type(const gchar *config_id, gchar **type)
140 if (g_str_has_suffix(config_id, WIFI_SECURITY_NONE) == TRUE) {
141 *type = g_strdup(WIFI_SECURITY_NONE);
142 } else if (g_str_has_suffix(config_id, WIFI_SECURITY_WEP) == TRUE) {
143 *type = g_strdup(WIFI_SECURITY_WEP);
144 } else if (g_str_has_suffix(config_id, WIFI_SECURITY_WPA_PSK) == TRUE) {
145 *type = g_strdup(WIFI_SECURITY_WPA_PSK);
146 } else if (g_str_has_suffix(config_id, WIFI_SECURITY_EAP) == TRUE) {
147 *type = g_strdup(WIFI_SECURITY_EAP);
156 static gboolean _netconfig_load_wifi_configuration(const gchar *config_id,
157 struct wifi_config *config)
162 gchar *mac_address = NULL;
163 gboolean hidden = FALSE;
165 __netconfig_get_mac_address(&mac_address);
166 if (strlen(mac_address) == 0) {
167 ERR("mac_address is NULL");
171 group_name = g_strdup_printf(WIFI_CONFIG_PREFIX "%s_%s", mac_address, config_id);
173 path = g_strdup_printf("/var/lib/connman/%s/settings", group_name);
175 DBG("group_name %s", group_name);
176 DBG("path %s", path);
178 keyfile = netconfig_keyfile_load(path);
179 if (keyfile == NULL) {
180 ERR("keyfile[%s] is NULL", path);
183 config->name = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
184 config->passphrase = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
185 _netconfig_get_security_type(config_id, &config->security_type);
186 config->proxy_address = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
187 hidden = g_key_file_get_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, NULL);
189 config->is_hidden = g_strdup("TRUE");
191 config->is_hidden = g_strdup("FALSE");
193 config->last_error = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_FAILURE, NULL);
201 static gboolean _netconfig_save_wifi_configuration(const gchar *config_id,
202 const struct wifi_config *config)
208 gchar *mac_address = NULL;
210 __netconfig_get_mac_address(&mac_address);
211 if (mac_address == NULL) {
212 ERR("mac_address is NULL");
216 group_name = g_strdup_printf("wifi_%s_%s", mac_address, config_id);
219 dir = g_strdup_printf(CONNMAN_STORAGE "/%s", group_name);
220 if (g_file_test(dir, G_FILE_TEST_IS_DIR) == TRUE) {
221 if (__netconfig_remove_configuration(dir) != TRUE) {
222 ERR("[%s] is existed, but cannot remove", dir);
229 if (mkdir(dir, (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) < 0) {
230 ERR("Cannot mkdir %s", dir);
236 keyfile = g_key_file_new();
237 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_NAME, config->name);
238 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_SSID, config->ssid);
240 if (config->passphrase != NULL)
241 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, config->passphrase);
243 g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_FAVORITE, config->favorite);
244 g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_AUTOCONNECT, config->autoconnect);
247 if (config->proxy_address != NULL) {
248 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_METHOD, "manual");
249 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, config->proxy_address);
252 if (config->is_hidden != NULL) {
253 gboolean hidden = FALSE;
254 if (g_strcmp0(config->is_hidden, "TRUE") == 0) {
257 g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
260 path = g_strdup_printf(CONNMAN_STORAGE "/%s/settings", group_name);
261 netconfig_keyfile_save(keyfile, path);
269 static gboolean _netconfig_remove_wifi_configuration(const gchar *config_id)
271 gboolean ret = FALSE;
274 gchar *mac_address = NULL;
276 __netconfig_get_mac_address(&mac_address);
277 if (mac_address == NULL) {
278 ERR("mac_address is NULL");
282 group_name = g_strdup_printf("wifi_%s_%s", mac_address, config_id);
285 dir = g_strdup_printf(CONNMAN_STORAGE "/%s", group_name);
286 if (g_file_test(dir, G_FILE_TEST_IS_DIR) == TRUE) {
287 if (__netconfig_remove_configuration(dir) != TRUE) {
288 ERR("[%s] is existed, but cannot remove", dir);
291 INFO("Success to remove [%s]", dir);
294 ERR("[%s] is not existed", dir);
304 static gboolean _netconfig_set_wifi_config_field(const gchar *config_id,
305 const gchar *key, const gchar *value)
311 gchar *mac_address = NULL;
313 __netconfig_get_mac_address(&mac_address);
314 if (strlen(mac_address) == 0) {
315 ERR("mac_address is NULL");
319 group_name = g_strdup_printf(WIFI_CONFIG_PREFIX "%s_%s", mac_address, config_id);
321 path = g_strdup_printf("/var/lib/connman/%s/settings", group_name);
323 DBG("group_name %s", group_name);
324 DBG("path %s", path);
326 keyfile = netconfig_keyfile_load(path);
327 if (keyfile == NULL) {
328 ERR("keyfile[%s] is NULL", path);
332 if (g_strcmp0(key, WIFI_CONFIG_PROXY_METHOD) == 0) {
333 g_key_file_set_string(keyfile, group_name, key, value);
334 }else if (g_strcmp0(key, WIFI_CONFIG_PROXY_SERVER) == 0) {
335 g_key_file_set_string(keyfile, group_name, key, value);
336 } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
337 gboolean hidden = FALSE;
338 if (g_strcmp0(value, "TRUE") == 0) {
341 g_key_file_set_boolean(keyfile, group_name, key, hidden);
343 ERR("key[%s] is not supported", key);
347 netconfig_keyfile_save(keyfile, path);
354 static GSList *_netconfig_get_wifi_config_list(void)
360 dir = opendir(CONNMAN_STORAGE);
362 ERR("Cannot open dir %s", CONNMAN_STORAGE);
366 while ((d = readdir(dir))) {
367 if (g_strcmp0(d->d_name, ".") == 0 ||
368 g_strcmp0(d->d_name, "..") == 0 ||
369 strncmp(d->d_name, WIFI_CONFIG_PREFIX, strlen(WIFI_CONFIG_PREFIX)) != 0) {
372 gchar *config_id = g_strdup(d->d_name + WIFI_PREFIX_LENGTH);
373 list = g_slist_append(list, g_strdup(config_id));
381 gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context)
384 GSList *config_ids = NULL;
386 gchar **result = NULL;
388 g_return_val_if_fail(wifi != NULL, FALSE);
390 config_ids = _netconfig_get_wifi_config_list();
391 if (config_ids == NULL) {
392 netconfig_error_no_profile(context);
393 ERR("Fail to get config list");
397 length = g_slist_length(config_ids);
398 result = g_new0(gchar *, length + 1);
399 for (i = 0; i < length; i++) {
400 gchar *config_id = g_slist_nth_data(config_ids, i);
401 result[i] = g_strdup(config_id);
404 config_ids = g_slist_nth(config_ids, 0);
405 g_slist_free_full(config_ids, g_free);
407 wifi_complete_get_config_ids(wifi, context, (const gchar * const*)result);
411 gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
412 const gchar *config_id)
414 gboolean ret = FALSE;
415 gchar *name = NULL, *passphrase = NULL, *security_type = NULL;
416 gchar *proxy_address = NULL, *is_hidden = NULL, *last_error = NULL;
417 struct wifi_config *conf = NULL;
419 g_return_val_if_fail(wifi != NULL, FALSE);
421 conf = g_new0(struct wifi_config, 1);
423 ret = _netconfig_load_wifi_configuration(config_id, conf);
426 ERR("No wifi configuration");
427 netconfig_error_no_profile(context);
431 name = g_strdup(conf->name);
432 passphrase = g_strdup(conf->passphrase);
433 security_type = g_strdup(conf->security_type);
434 is_hidden = g_strdup(conf->is_hidden);
436 if (conf->proxy_address != NULL) {
437 proxy_address = g_strdup(conf->proxy_address);
438 g_free(conf->proxy_address);
440 proxy_address = g_strdup("NONE");
442 if (conf->last_error != NULL) {
443 last_error = g_strdup(conf->last_error);
444 g_free(conf->last_error);
446 last_error = g_strdup("ERROR_NONE");
450 g_free(conf->passphrase);
451 g_free(conf->security_type);
452 g_free(conf->is_hidden);
455 wifi_complete_load_configuration (wifi, context, name,
456 passphrase, security_type, proxy_address, is_hidden, last_error);
461 gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
462 const gchar *config_id, GVariant *configuration)
464 gboolean ret = FALSE;
465 struct wifi_config *conf = NULL;
470 if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
471 ERR("Invaliad parameter");
472 netconfig_error_invalid_parameter(context);
476 conf = g_new0(struct wifi_config, 1);
478 g_variant_get(configuration, "a{sv}", &iter);
479 while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
480 if (g_strcmp0(field, WIFI_CONFIG_NAME) == 0) {
481 if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
482 conf->name = g_strdup(g_variant_get_string(value, NULL));
483 ERR("name [%s]", conf->name);
487 } else if (g_strcmp0(field, WIFI_CONFIG_SSID) == 0) {
488 if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
489 conf->ssid = g_strdup(g_variant_get_string(value, NULL));
490 ERR("ssid [%s]", conf->ssid);
494 } else if (g_strcmp0(field, WIFI_CONFIG_PASSPHRASE) == 0) {
495 if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
496 conf->passphrase = g_strdup(g_variant_get_string(value, NULL));
497 ERR("passphrase [%s]", conf->passphrase);
499 conf->passphrase = NULL;
501 } else if (g_strcmp0(field, WIFI_CONFIG_HIDDEN) == 0) {
502 if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
503 conf->is_hidden = g_strdup(g_variant_get_string(value, NULL));
504 ERR("is_hidden [%s]", conf->is_hidden);
506 conf->is_hidden = NULL;
508 } else if (g_strcmp0(field, WIFI_CONFIG_PROXYADDRESS) == 0) {
509 conf->proxy_address = g_strdup(g_variant_get_string(value, NULL));
510 ERR("proxy_address [%s]", conf->proxy_address);
512 conf->proxy_address = NULL;
515 conf->favorite = TRUE;
516 conf->autoconnect = TRUE;
517 ret = _netconfig_save_wifi_configuration(config_id, conf);
521 g_free(conf->passphrase);
522 g_free(conf->is_hidden);
523 g_free(conf->proxy_address);
526 g_variant_iter_free(iter);
529 wifi_complete_save_configuration(wifi, context);
531 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailSaveConfiguration");
537 gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context, const gchar *config_id)
539 gboolean ret = FALSE;
541 if ((wifi == NULL) || (config_id == NULL)) {
542 ERR("Invaliad parameter");
543 netconfig_error_invalid_parameter(context);
547 ret = _netconfig_remove_wifi_configuration(config_id);
549 // no configuration or error
550 ERR("No [%s] configuration", config_id);
551 netconfig_error_no_profile(context);
555 wifi_complete_remove_configuration(wifi, context);
559 // config field key / value
561 * [wifi_macaddress_config_id]
562 * Name=name (mandatory)
563 * SSID=SSID (mandatory)
566 * AutoConnect=true (Default true)
567 * Modified=2015-03-20 (X)
568 * IPv4.method=manual (O)
569 * IPv4.DHCP.LastAddress=192.0.0.1 (X)
570 * IPv6.method=auto (X)
571 * IPv6.privacy=disabled (X)
572 * IPv4.netmask_prefixlen=24 (X)
573 * IPv4.local_address=192.0.0.1 (O)
574 * IPv4.gateway=192.0.0.1 (O ? X ?)
575 * Nameservers=192.168.43.22; (O)
576 * Proxy.Method=manual (O)
577 * Proxy.Servers=trst.com:8888; (O)
579 gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
580 const gchar *config_id, const gchar *key, const gchar *value)
582 gboolean ret = FALSE;
583 gchar *keyfile_key = NULL;
585 g_return_val_if_fail(wifi != NULL, FALSE);
586 g_return_val_if_fail(config_id != NULL, FALSE);
587 g_return_val_if_fail(key != NULL, FALSE);
589 DBG("Key[%s] Value[%d]", key, value);
591 if (g_strcmp0(key, WIFI_CONFIG_PROXYADDRESS) == 0) {
592 ret = _netconfig_set_wifi_config_field(config_id, WIFI_CONFIG_PROXY_METHOD, "manual");
594 ERR("Fail to [%s]set_wifi_config_field(%s/manual)", config_id, WIFI_CONFIG_PROXY_METHOD);
595 netconfig_error_invalid_parameter(context);
598 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_PROXY_SERVER);
599 } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
600 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_HIDDEN);
602 ERR("Not supported key[%s]", key);
603 netconfig_error_invalid_parameter(context);
607 ret = _netconfig_set_wifi_config_field(config_id, keyfile_key, (const gchar *)value);
609 ERR("Fail to [%s]set_wifi_config_field(%s/%s)", config_id, key, value);
613 if (keyfile_key != NULL)
616 wifi_complete_set_config_field(wifi,context);