Support 6GHz band for channels and RSSI level
[platform/core/connectivity/net-config.git] / src / wifi-config.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <dirent.h>
25 #include <sys/stat.h>
26 #include <glib.h>
27 #include <unistd.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
31
32 #include <vconf.h>
33
34 #include "log.h"
35 #include "util.h"
36 #include "neterror.h"
37 #include "wifi-config.h"
38 #include "wifi-state.h"
39 #include "netsupplicant.h"
40 #include "wifi-key-encryption.h"
41
42 #define CONNMAN_STORAGE         "/var/lib/connman"
43
44 #define WIFI_SECURITY_NONE              "none"
45 #define WIFI_SECURITY_WEP               "wep"
46 #define WIFI_SECURITY_WPA_PSK   "psk"
47 #define WIFI_SECURITY_EAP               "ieee8021x"
48 #define WIFI_SECURITY_SAE               "sae"
49
50 #define WIFI_CONFIG_PREFIX      "wifi_"
51 #define MAC_ADDRESS_LENGTH              12
52 #define WIFI_PREFIX_LENGTH              MAC_ADDRESS_LENGTH + 6  /* wifi_485a3f2f506a_ */
53 #define PROFILE_PREFIX_LENGTH   WIFI_PREFIX_LENGTH + 21 /* /net/connman/service/wifi_485a3f2f506a_ */
54
55 #define NET_DNS_ADDR_MAX                2
56
57 #define MAX_WIFI_PROFILES               200
58
59 struct wifi_eap_config {
60         gchar *anonymous_identity;
61         gchar *ca_cert;
62         gchar *client_cert;
63         gchar *private_key;
64         gchar *private_key_password;
65         gchar *identity;
66         gchar *eap_type;
67         gchar *eap_auth_type;
68         gchar *subject_match;
69 };
70
71 typedef struct {
72         gchar *ip_address;
73         gchar *subnet_mask;
74         gchar *gateway_address;
75         gchar *dns_address[NET_DNS_ADDR_MAX];
76         int prefix_length;
77         int dns_count;
78         gchar *ip_type;
79         gchar *dns_type;
80 } wifi_ip_info_s;
81
82 struct wifi_config {
83         gchar *name;
84         gchar *ssid;
85         gchar *passphrase;
86         gchar *security_type;
87         gboolean favorite;
88         gboolean autoconnect;
89         gchar *is_hidden;
90         gboolean is_created;
91         gchar *proxy_address;
92         struct wifi_eap_config *eap_config;
93         wifi_ip_info_s *ip_info;
94         guint frequency;
95         gchar *last_error;
96 };
97
98 static void __free_wifi_configuration(struct wifi_config *conf)
99 {
100         if (conf == NULL)
101                 return;
102
103         g_free(conf->name);
104         g_free(conf->ssid);
105         g_free(conf->passphrase);
106         g_free(conf->security_type);
107         g_free(conf->is_hidden);
108         g_free(conf->proxy_address);
109         g_free(conf->last_error);
110         if (conf->eap_config) {
111                 g_free(conf->eap_config->anonymous_identity);
112                 g_free(conf->eap_config->ca_cert);
113                 g_free(conf->eap_config->client_cert);
114                 g_free(conf->eap_config->private_key);
115                 g_free(conf->eap_config->private_key_password);
116                 g_free(conf->eap_config->identity);
117                 g_free(conf->eap_config->eap_type);
118                 g_free(conf->eap_config->eap_auth_type);
119                 g_free(conf->eap_config->subject_match);
120                 g_free(conf->eap_config);
121         }
122
123         if (conf->ip_info) {
124                 g_free(conf->ip_info->ip_type);
125                 g_free(conf->ip_info->ip_address);
126                 g_free(conf->ip_info->subnet_mask);
127                 g_free(conf->ip_info->gateway_address);
128                 g_free(conf->ip_info->dns_type);
129                 conf->ip_info->prefix_length = 0;
130
131                 int i = 0, count = conf->ip_info->dns_count;
132                 while (i < count) {
133                         g_free(conf->ip_info->dns_address[i]);
134                         i++;
135                 }
136                 g_free(conf->ip_info);
137         }
138         g_free(conf);
139 }
140
141 static gboolean __get_mac_address(const gchar *interface_name, gchar **mac_address)
142 {
143         FILE *fp = NULL;
144         char buf[WIFI_MAC_ADDR_LENGTH + 1];
145         char path[WIFI_MAC_PATH_LENGTH];
146         gchar *tmp_mac = NULL;
147         gchar *tmp = NULL;
148         gchar mac[13] = { 0, };
149         gint i = 0, j = 0;
150
151         snprintf(path, WIFI_MAC_PATH_LENGTH, WIFI_MAC_ADDR_PATH, interface_name);
152
153         if (0 == access(path, F_OK))
154                 fp = fopen(path, "r");
155
156         if (fp) {
157                 if (fgets(buf, sizeof(buf), fp) == NULL) {
158                         ERR("Failed to get MAC info from %s\n", path);
159                         *mac_address = NULL;
160                         fclose(fp);
161                         return FALSE;
162                 }
163                 tmp_mac = (gchar *)malloc(WIFI_MAC_ADDR_LENGTH + 1);
164                 if (tmp_mac == NULL) {
165                         ERR("malloc() failed");
166                         *mac_address = NULL;
167                         fclose(fp);
168                         return FALSE;
169                 }
170                 memset(tmp_mac, 0, WIFI_MAC_ADDR_LENGTH + 1);
171                 g_strlcpy(tmp_mac, buf, WIFI_MAC_ADDR_LENGTH + 1);
172                 fclose(fp);
173         } else {
174                 ERR("Failed to open file %s\n", path);
175
176                 tmp_mac = vconf_get_str(VCONFKEY_WIFI_BSSID_ADDRESS);
177                 if (tmp_mac == NULL) {
178                         ERR("vconf_get_str(WIFI_BSSID_ADDRESS) Failed");
179                         *mac_address = NULL;
180                         return FALSE;
181                 }
182         }
183
184         tmp = g_ascii_strdown(tmp_mac, (gssize)strlen(tmp_mac));
185         free(tmp_mac);
186         while (tmp && tmp[i]) {
187                 if (tmp[i] != ':')
188                         mac[j++] = tmp[i];
189                 i++;
190         }
191         mac[12] = '\0';
192         *mac_address = g_strdup(mac);
193         g_free(tmp);
194
195         return TRUE;
196 }
197
198 gboolean wifi_config_get_group_name(const gchar *prefix,
199                 const gchar *interface_name, const gchar *config_id, gchar **group_name)
200 {
201         gchar *mac_address = NULL;
202         gchar *g_name = NULL;
203         gboolean ret = FALSE;
204
205         ret = __get_mac_address(interface_name, &mac_address);
206         if ((ret != TRUE) || (strlen(mac_address) == 0)) {
207                 ERR("Cannot get WIFI MAC address");
208                 g_free(mac_address);
209                 return FALSE;
210         }
211
212         g_name = g_strdup_printf("%s%s_%s", prefix, mac_address, config_id);
213         if (g_name == NULL) {
214                 g_free(mac_address);
215                 return FALSE;
216         }
217
218         *group_name = g_strdup(g_name);
219
220         g_free(mac_address);
221         g_free(g_name);
222
223         return TRUE;
224 }
225
226 static gboolean __get_security_type(const gchar *config_id, gchar **type)
227 {
228         if (g_str_has_suffix(config_id, WIFI_SECURITY_NONE) == TRUE) {
229                 *type = g_strdup(WIFI_SECURITY_NONE);
230         } else if (g_str_has_suffix(config_id, WIFI_SECURITY_WEP) == TRUE) {
231                 *type = g_strdup(WIFI_SECURITY_WEP);
232         } else if (g_str_has_suffix(config_id, WIFI_SECURITY_WPA_PSK) == TRUE) {
233                 *type = g_strdup(WIFI_SECURITY_WPA_PSK);
234         } else if (g_str_has_suffix(config_id, WIFI_SECURITY_EAP) == TRUE) {
235                 *type = g_strdup(WIFI_SECURITY_EAP);
236         } else if (g_str_has_suffix(config_id, WIFI_SECURITY_SAE) == TRUE) {
237                 *type = g_strdup(WIFI_SECURITY_SAE);
238         } else {
239                 *type = NULL;
240                 return FALSE;
241         }
242
243         return TRUE;
244 }
245
246 static gboolean __get_config_id(const gchar *profile, gchar **config_id)
247 {
248         *config_id = g_strdup(profile + PROFILE_PREFIX_LENGTH);
249         if (*config_id == NULL) {
250                 ERR("OOM");
251                 return FALSE;
252         }
253
254         return TRUE;
255 }
256
257
258 static GKeyFile *__get_configuration_keyfile(const gchar *group_name)
259 {
260         GKeyFile *keyfile = NULL;
261         gchar *path;
262
263         path = g_strdup_printf(CONNMAN_STORAGE "/%s/settings", group_name);
264
265         keyfile = netconfig_keyfile_load(path);
266         if (keyfile == NULL)
267                 ERR("keyfile[%s] is NULL", path);
268
269         g_free(path);
270
271         return keyfile;
272 }
273
274 static gboolean __remove_file(const gchar *pathname, const gchar *filename)
275 {
276         gboolean ret = FALSE;
277         gchar *path;
278
279         path = g_strdup_printf("%s/%s", pathname, filename);
280         if (g_file_test(path, G_FILE_TEST_EXISTS) == FALSE) {
281                 ret = TRUE;
282         } else if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == TRUE) {
283                 unlink(path);
284                 ret = TRUE;
285         }
286
287         g_free(path);
288         return ret;
289 }
290
291 static gboolean __remove_all_files(const gchar *pathname)
292 {
293         DIR *dir_ptr = NULL;
294         struct dirent *file = NULL;
295
296         if ((dir_ptr = opendir(pathname)) == NULL)
297                 return TRUE;
298
299         while ((file = readdir(dir_ptr)) != NULL) {
300                 if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0)
301                         continue;
302
303                 if (__remove_file(pathname, file->d_name) != TRUE) {
304                         ERR("Cannot remove [%s/%s]", pathname, file->d_name);
305                         closedir(dir_ptr);
306
307                         return FALSE;
308                 }
309         }
310
311         closedir(dir_ptr);
312
313         return TRUE;
314 }
315
316 static gboolean __remove_configuration(const gchar *pathname)
317 {
318         int ret = 0;
319
320         if (__remove_all_files(pathname) != TRUE) {
321                 ERR("Cannot remove [%s] directory", pathname);
322                 return FALSE;
323         }
324
325         ret = rmdir(pathname);
326         if (ret == -1) {
327                 ERR("Cannot remove [%s]", pathname);
328                 return FALSE;
329         }
330         return TRUE;
331 }
332
333 static gboolean _load_configuration(const gchar *interface_name,
334                 const gchar *config_id, struct wifi_config *config)
335 {
336         GKeyFile *keyfile;
337         gchar *group_name;
338         gboolean hidden = FALSE;
339         gboolean ret = FALSE;
340
341         ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
342                         interface_name, config_id, &group_name);
343         if (ret != TRUE) {
344                 ERR("Fail to get_wifi_config_group_name");
345                 return FALSE;
346         }
347
348         keyfile = __get_configuration_keyfile(group_name);
349         if (keyfile == NULL) {
350                 ERR("Fail to __get_configuration_keyfile[%s]", group_name);
351                 g_free(group_name);
352                 return FALSE;
353         }
354
355         config->name = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
356         DBG("name [%s]", config->name);
357
358         if (config->name == NULL) {
359                 ERR("Fail to get Name of [%s]", group_name);
360                 g_key_file_free(keyfile);
361                 g_free(group_name);
362                 return FALSE;
363         }
364
365         __get_security_type(config_id, &config->security_type);
366         if (config->security_type == NULL) {
367                 ERR("Fail to _get_security_type");
368                 g_key_file_free(keyfile);
369                 g_free(group_name);
370                 return FALSE;
371         }
372         DBG("security_type [%s]", config->security_type);
373
374         config->passphrase = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
375         DBG("passphrase []");
376
377         config->proxy_address = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
378         if (config->proxy_address)
379                 DBG("proxy_address [%s]", config->proxy_address);
380
381         hidden = g_key_file_get_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, NULL);
382         if (hidden)
383                 config->is_hidden = g_strdup("TRUE");
384         else
385                 config->is_hidden = g_strdup("FALSE");
386         DBG("is_hidden [%s]", config->is_hidden);
387
388         config->frequency = g_key_file_get_integer(keyfile, group_name, WIFI_CONFIG_FREQUENCY, NULL);
389         if (config->frequency)
390                 DBG("Frequency [%d]", config->frequency);
391
392         if (config->ip_info) {
393                 config->ip_info->ip_type = g_key_file_get_string(keyfile, group_name,
394                                 WIFI_CONFIG_IPV4_METHOD, NULL);
395                 if (config->ip_info->ip_type)
396                         DBG("IPv4.Method:%s", config->ip_info->ip_type);
397
398                 config->ip_info->ip_address = g_key_file_get_string(keyfile, group_name,
399                                 WIFI_CONFIG_IPV4_ADDRESS, NULL);
400                 if (config->ip_info->ip_address)
401                         DBG("IPv4.Address:%s", config->ip_info->ip_address);
402
403                 int prefix_len;
404                 in_addr_t addr;
405                 struct in_addr netmask;
406                 char *mask;
407                 GError *error = NULL;
408                 prefix_len = g_key_file_get_integer(keyfile, group_name,
409                                 WIFI_CONFIG_IPV4_SUBNET_MASK, &error);
410                 if (error != NULL) {
411                         DBG("g_key_file_get_integer failed error[%d: %s]", error->code, error->message);
412                         g_error_free(error);
413                 } else {
414                         if (prefix_len > 0 && prefix_len < 32) {
415                                 addr = 0xffffffff << (32 - prefix_len);
416                                 netmask.s_addr = htonl(addr);
417                                 mask = inet_ntoa(netmask);
418                                 config->ip_info->subnet_mask = g_strdup(mask);
419                         }
420                         if (config->ip_info->subnet_mask)
421                                 DBG("IPv4.SubnetMask:%s", config->ip_info->subnet_mask);
422                 }
423
424                 config->ip_info->gateway_address = g_key_file_get_string(keyfile,
425                                                         group_name, WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, NULL);
426                 if (config->ip_info->gateway_address)
427                         DBG("IPv4.gateway:%s", config->ip_info->gateway_address);
428
429                 config->ip_info->dns_type = g_key_file_get_string(keyfile, group_name,
430                                                           WIFI_CONFIG_IPV4_DNS_METHOD, NULL);
431                 if (config->ip_info->dns_type)
432                         DBG("DNS.IPv4Method:%s", config->ip_info->dns_type);
433
434                 char **nameservers;
435                 gsize length;
436                 nameservers = g_key_file_get_string_list(keyfile, group_name,
437                                                                  WIFI_CONFIG_DNS_ADDRESS, &length, NULL);
438                 if (nameservers) {
439                         if (length > 0) {
440                                 config->ip_info->dns_count = length;
441                                 int i = 0;
442                                 while (i < NET_DNS_ADDR_MAX && nameservers[i]) {
443                                         config->ip_info->dns_address[i] = g_strdup(nameservers[i]);
444                                         DBG("DNSAddress[%d]:%s", i+1, config->ip_info->dns_address[i]);
445                                         i += 1;
446                                 }
447                         }
448                         g_strfreev(nameservers);
449                 }
450         }
451
452
453         if (g_strcmp0(config->security_type, WIFI_SECURITY_EAP) == 0) {
454                 config->eap_config->anonymous_identity = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, NULL);
455                 config->eap_config->ca_cert = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CACERT, NULL);
456                 config->eap_config->client_cert = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CLIENTCERT, NULL);
457                 config->eap_config->private_key = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_PRIVATEKEY, NULL);
458                 config->eap_config->private_key_password = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, NULL);
459                 config->eap_config->identity = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_IDENTITY, NULL);
460                 config->eap_config->eap_type = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_TYPE, NULL);
461                 config->eap_config->eap_auth_type = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_AUTH_TYPE, NULL);
462                 config->eap_config->subject_match = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_SUBJECT_MATCH, NULL);
463
464                 if (config->eap_config->anonymous_identity)
465                         DBG("anonymous_identity [%s]", config->eap_config->anonymous_identity);
466                 if (config->eap_config->ca_cert)
467                         DBG("ca_cert [%s]", config->eap_config->ca_cert);
468                 if (config->eap_config->client_cert)
469                         DBG("client_cert [%s]", config->eap_config->client_cert);
470                 if (config->eap_config->private_key)
471                         DBG("private_key [%s]", config->eap_config->private_key);
472                 if (config->eap_config->private_key_password)
473                         DBG("private_key_password [%s]", config->eap_config->private_key_password);
474                 if (config->eap_config->identity)
475                         DBG("identity [%s]", config->eap_config->identity);
476                 if (config->eap_config->eap_type)
477                         DBG("eap_type [%s]", config->eap_config->eap_type);
478                 if (config->eap_config->eap_auth_type)
479                         DBG("eap_auth_type [%s]", config->eap_config->eap_auth_type);
480                 if (config->eap_config->subject_match)
481                         DBG("subject_match [%s]", config->eap_config->subject_match);
482         }
483
484         config->last_error = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_FAILURE, NULL);
485         if (config->last_error)
486                 DBG("last_error [%s]", config->last_error);
487
488         g_key_file_free(keyfile);
489         g_free(group_name);
490
491         return TRUE;
492 }
493
494 gboolean wifi_config_save_configuration(const gchar *interface_name,
495                 const gchar *config_id, GKeyFile *keyfile)
496 {
497         gchar *dir;
498         gchar *path;
499         gchar *group_name;
500         gboolean ret = FALSE;
501
502         ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
503                         interface_name, config_id, &group_name);
504         if (ret != TRUE) {
505                 ERR("Fail to get_wifi_config_group_name");
506                 return FALSE;
507         }
508
509         dir = g_strdup_printf(CONNMAN_STORAGE "/%s", group_name);
510         if (g_file_test(dir, G_FILE_TEST_IS_DIR) == TRUE) {
511                 if (__remove_configuration(dir) != TRUE) {
512                         ERR("[%s] is existed, but cannot remove", dir);
513                         g_free(group_name);
514                         g_free(dir);
515                         return FALSE;
516                 }
517         }
518
519         if (mkdir(dir, (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) < 0) {
520                 ERR("Cannot mkdir %s", dir);
521                 g_free(group_name);
522                 g_free(dir);
523                 return FALSE;
524         }
525
526         path = g_strdup_printf(CONNMAN_STORAGE "/%s/settings", group_name);
527         netconfig_keyfile_save(keyfile, path);
528         g_free(group_name);
529         g_free(dir);
530         g_free(path);
531
532         return TRUE;
533 }
534
535 static gboolean _remove_configuration(const gchar *interface_name, const gchar *config_id)
536 {
537         gboolean ret = FALSE;
538         gchar *dir;
539         gchar *group_name;
540
541         ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
542                         interface_name, config_id, &group_name);
543         if (ret != TRUE) {
544                 ERR("Fail to get_wifi_config_group_name");
545                 return FALSE;
546         }
547
548         dir = g_strdup_printf(CONNMAN_STORAGE "/%s", group_name);
549         if (g_file_test(dir, G_FILE_TEST_IS_DIR) == TRUE) {
550                 if (__remove_configuration(dir) != TRUE) {
551                         ERR("[%s] is existed, but cannot remove", dir);
552                         ret = FALSE;
553                 } else {
554                         INFO("Success to remove [%s]", dir);
555                         ret = TRUE;
556                 }
557         } else {
558                 ERR("[%s] is not existed", dir);
559                 ret = FALSE;
560         }
561
562         g_free(group_name);
563         g_free(dir);
564
565         return ret;
566 }
567
568
569 static gboolean _set_field(const gchar *interface_name,
570                 const gchar *config_id, const gchar *key, const gchar *value)
571 {
572         gboolean ret = TRUE;
573         GKeyFile *keyfile;
574         gchar *group_name;
575
576         ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
577                         interface_name, config_id, &group_name);
578         if (ret != TRUE) {
579                 ERR("Fail to get_wifi_config_group_name");
580                 return FALSE;
581         }
582         DBG("group_name %s", group_name);
583
584         keyfile = __get_configuration_keyfile(group_name);
585         if (keyfile == NULL) {
586                 ERR("Fail to __get_configuration_keyfile");
587                 g_free(group_name);
588                 return FALSE;
589         }
590
591         if (g_strcmp0(key, WIFI_CONFIG_PROXY_METHOD) == 0) {
592                 g_key_file_set_string(keyfile, group_name, key, value);
593         } else if (g_strcmp0(key, WIFI_CONFIG_PROXY_SERVER) == 0) {
594                 g_key_file_set_string(keyfile, group_name, key, value);
595         } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
596                 gboolean hidden = FALSE;
597                 if (g_strcmp0(value, "TRUE") == 0)
598                         hidden = TRUE;
599                 g_key_file_set_boolean(keyfile, group_name, key, hidden);
600         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
601                 g_key_file_set_string(keyfile, group_name, key, value);
602         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CACERT) == 0) {
603                 g_key_file_set_string(keyfile, group_name, key, value);
604         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
605                 g_key_file_set_string(keyfile, group_name, key, value);
606         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
607                 g_key_file_set_string(keyfile, group_name, key, value);
608         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_IDENTITY) == 0) {
609                 g_key_file_set_string(keyfile, group_name, key, value);
610         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_TYPE) == 0) {
611                 g_key_file_set_string(keyfile, group_name, key, value);
612         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
613                 g_key_file_set_string(keyfile, group_name, key, value);
614         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
615                 g_key_file_set_string(keyfile, group_name, key, value);
616         } else {
617                 ERR("key[%s] is not supported", key);
618                 ret = FALSE;
619         }
620
621         wifi_config_save_configuration(interface_name, config_id, keyfile);
622
623         g_key_file_free(keyfile);
624         g_free(group_name);
625
626         return ret;
627 }
628
629 static gboolean _get_field(const gchar *interface_name,
630                 const gchar *config_id, const gchar *key, gchar **value)
631 {
632         GKeyFile *keyfile;
633         gchar *group_name;
634         gchar *val = NULL;
635         gboolean hidden = FALSE;
636         gboolean ret = FALSE;
637
638         ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
639                         interface_name, config_id, &group_name);
640         if (ret != TRUE) {
641                 ERR("Fail to get_wifi_config_group_name");
642                 return FALSE;
643         }
644         DBG("group_name %s", group_name);
645
646         keyfile = __get_configuration_keyfile(group_name);
647         if (keyfile == NULL) {
648                 ERR("Fail to __get_configuration_keyfile");
649                 g_free(group_name);
650                 return FALSE;
651         }
652
653         if (g_strcmp0(key, WIFI_CONFIG_NAME) == 0) {
654                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
655         } else if (g_strcmp0(key, WIFI_CONFIG_PASSPHRASE) == 0) {
656                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
657         } else if (g_strcmp0(key, WIFI_CONFIG_PROXY_SERVER) == 0) {
658                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
659         } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
660                 hidden = g_key_file_get_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, NULL);
661                 if (hidden)
662                         val = g_strdup("TRUE");
663                 else
664                         val = g_strdup("FALSE");
665         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
666                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, NULL);
667         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CACERT) == 0) {
668                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CACERT, NULL);
669         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
670                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CLIENTCERT, NULL);
671         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
672                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_PRIVATEKEY, NULL);
673         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_IDENTITY) == 0) {
674                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_IDENTITY, NULL);
675         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_TYPE) == 0) {
676                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_TYPE, NULL);
677         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
678                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_AUTH_TYPE, NULL);
679         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
680                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_SUBJECT_MATCH, NULL);
681         } else if (g_strcmp0(key, WIFI_CONFIG_FAILURE) == 0) {
682                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_FAILURE, NULL);
683         } else {
684                 ERR("Invalid key[%s]", key);
685                 val = g_strdup("NOTSUPPORTED");
686         }
687
688         *value = g_strdup(val);
689         g_free(val);
690
691         g_key_file_free(keyfile);
692         g_free(group_name);
693
694         return TRUE;
695 }
696
697 static GSList *_get_list(const char *mac_addr)
698 {
699         GSList *list = NULL;
700         struct dirent *dp = NULL;
701         DIR *dir;
702
703         dir = opendir(CONNMAN_STORAGE);
704         if (dir == NULL) {
705                 ERR("Cannot open dir %s", CONNMAN_STORAGE);
706                 return NULL;
707         }
708
709         while ((dp = readdir(dir)) != NULL) {
710                 if (g_strcmp0(dp->d_name, ".") == 0 || g_strcmp0(dp->d_name, "..") == 0 ||
711                                 strncmp(dp->d_name, WIFI_CONFIG_PREFIX, strlen(WIFI_CONFIG_PREFIX)) != 0) {
712                         continue;
713                 }
714
715                 DBG("%s", dp->d_name);
716
717                 if (netconfig_check_mac_address(dp->d_name, mac_addr)) {
718                         gchar *config_id = g_strdup(dp->d_name + WIFI_PREFIX_LENGTH);
719                         DBG("%s", config_id);
720                         list = g_slist_append(list, g_strdup(config_id));
721                         g_free(config_id);
722                 }
723         }
724         closedir(dir);
725
726         return list;
727 }
728
729 gboolean wifi_config_get_config_id(const gchar *service_profile, gchar **config_id)
730 {
731         gboolean ret = FALSE;
732         gchar *val = NULL;
733
734         if ((service_profile == NULL) || (config_id == NULL)) {
735                 ERR("Invalid parameter");
736                 return FALSE;
737         }
738
739         ret = __get_config_id(service_profile, &val);
740         *config_id = g_strdup(val);
741         g_free(val);
742
743         return ret;
744 }
745
746 gboolean wifi_config_remove_configuration(const gchar *interface_name,
747                 const gchar *config_id)
748 {
749         gboolean ret = FALSE;
750
751         ret = _remove_configuration(interface_name, config_id);
752
753         return ret;
754 }
755
756 int __netconfig_hex_char_to_num(char c)
757 {
758         if (c >= '0' && c <= '9')
759                 return c - '0';
760
761         if (c >= 'a' && c <= 'f')
762                 return c - 'a' + 10;
763
764         if (c >= 'A' && c <= 'F')
765                 return c - 'A' + 10;
766
767         return -1;
768 }
769
770 int __netconfig_hex_to_byte(const char *hex)
771 {
772         int a, b;
773
774         a = __netconfig_hex_char_to_num(*hex++);
775         if (a < 0)
776                 return -1;
777
778         b = __netconfig_hex_char_to_num(*hex++);
779         if (b < 0)
780                 return -1;
781
782         return (a << 4) | b;
783 }
784
785 int __netconfig_hex_str_to_bin(const char *hex, unsigned char *buf, size_t len)
786 {
787         size_t i;
788         int a;
789         const char *ipos = hex;
790         unsigned char *opos = buf;
791
792         for (i = 0; i < len; i++) {
793                 a = __netconfig_hex_to_byte(ipos);
794                 if (a < 0)
795                         return -1;
796
797                 *opos++ = a;
798                 ipos += 2;
799         }
800
801         return 0;
802 }
803
804 static int __netconfig_byte_to_txt(const unsigned char *src, char **dst, int src_len)
805 {
806         int dst_length = 0;
807         int i = 0;
808         char *buf = NULL;
809
810         if (src_len <= 0) {
811                 ERR("Invalid parameter.");
812                 return -1;
813         }
814
815         *dst = (char *) g_try_malloc0((2*src_len)+1);
816         if (!(*dst)) {
817                 ERR("failed to allocate memory to buffer.");
818                 return -1;
819         }
820
821         buf = (*dst);
822
823         for (i = 0; i < src_len; i++) {
824                 snprintf(buf, 3, "%02x", src[i]);
825                 buf += 2;
826                 dst_length += 2;
827         }
828
829         return dst_length;
830 }
831
832 static int __netconfig_unpack_ay_malloc(unsigned char **dst, GVariantIter *iter)
833 {
834         GVariantIter *iter_copy = NULL;
835         int length = 0;
836         char tmp = 0;
837         unsigned char *tmp_dst = NULL;
838
839         if (!dst || *dst || !iter) {
840                 ERR("Invalid parameter");
841                 return 0;
842         }
843
844         iter_copy = g_variant_iter_copy(iter);
845
846         while (g_variant_iter_loop(iter, "y", &tmp))
847                 length++;
848         g_variant_iter_free(iter);
849
850         tmp_dst = (unsigned char *)g_try_malloc0(length + 1);
851         if (!tmp_dst) {
852                 ERR("failed to allocate memory");
853                 g_variant_iter_free(iter_copy);
854                 return 0;
855         }
856
857         length = 0;
858         while (g_variant_iter_loop(iter_copy, "y", &tmp_dst[length]))
859                 length++;
860         g_variant_iter_free(iter_copy);
861
862         if (length == 0) {
863                 g_free(tmp_dst);
864                 tmp_dst = NULL;
865         } else {
866                 tmp_dst[length] = '\0';
867         }
868
869         *dst = tmp_dst;
870         DBG("Length [%d]", length);
871         return length;
872 }
873
874 gboolean _add_vsie(const char *interface_name, int frame_id, const char* vsie)
875 {
876         GVariant *params = NULL;
877         GVariant *message = NULL;
878         GVariantBuilder *bytearray_builder = NULL;
879         char *if_path;
880         int i = 0;
881         size_t vsie_len = 0;
882
883         unsigned char *bytearray = NULL;
884         size_t bytearray_len = 0;
885
886         if (frame_id >= NETCONFIG_VSIE_FRAME_MAX) {
887                 DBG("Invalid parameter, frame-id: %d", frame_id);
888                 return FALSE;
889         }
890
891         vsie_len = strlen(vsie);
892         if (vsie_len == 0) {
893                 DBG("vsie length is zero");
894                 return FALSE;
895         }
896
897         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
898
899         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
900         if (bytearray == NULL) {
901                 DBG("Failed to allocate memory to bytearray");
902                 return FALSE;
903         }
904
905         if (__netconfig_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
906                 DBG("invalid vsie string");
907                 g_free(bytearray);
908                 return FALSE;
909         }
910
911         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
912         for (i = 0; i < bytearray_len; i++)
913                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
914
915         params = g_variant_new("(iay)", frame_id, bytearray_builder);
916         g_variant_builder_unref(bytearray_builder);
917
918         if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
919         if (if_path == NULL) {
920                 ERR("Fail to get wpa_supplicant DBus path");
921                 g_free(bytearray);
922                 return FALSE;
923         }
924
925         message = netconfig_supplicant_invoke_dbus_method(SUPPLICANT_SERVICE,
926                         if_path, SUPPLICANT_INTERFACE ".Interface", "VendorElemAdd", params);
927
928         g_free(if_path);
929         if (message == NULL) {
930                 ERR("Failed to send command to wpa_supplicant");
931                 g_free(bytearray);
932                 return FALSE;
933         }
934
935         DBG("Succeeded to add vsie: Frame ID[%d], VSIE[%s]", frame_id, vsie);
936
937         g_free(bytearray);
938         return TRUE;
939 }
940
941 gboolean _get_vsie(const char *interface_name, int frame_id, char **vsie)
942 {
943         GVariant *params = NULL;
944         GVariant *message = NULL;
945         char *if_path;
946
947         if (frame_id >= NETCONFIG_VSIE_FRAME_MAX) {
948                 DBG("Invalid parameter, frame-id: %d", frame_id);
949                 return FALSE;
950         }
951
952         if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
953         if (if_path == NULL) {
954                 ERR("Fail to get wpa_supplicant DBus path");
955                 return FALSE;
956         }
957
958         params = g_variant_new("(i)", frame_id);
959
960         message = netconfig_supplicant_invoke_dbus_method(SUPPLICANT_SERVICE,
961                         if_path, SUPPLICANT_INTERFACE ".Interface", "VendorElemGet", params);
962
963         g_free(if_path);
964         if (message == NULL) {
965                 ERR("Failed to send command to wpa_supplicant");
966                 return FALSE;
967         } else {
968                 GVariantIter *iter = NULL;
969                 unsigned char *vsie_bytes = NULL;
970                 int vsie_len = 0;
971                 int ret = 0;
972
973                 g_variant_get(message, "(ay)", &iter);
974                 if (iter == NULL) {
975                         ERR("vsie is not present");
976                         return FALSE;
977                 }
978
979                 vsie_len = __netconfig_unpack_ay_malloc(&vsie_bytes, iter);
980                 if (vsie_bytes == NULL) {
981                         ERR("vsie_bytes not allocated");
982                         return FALSE;
983                 }
984
985                 ret = __netconfig_byte_to_txt(vsie_bytes, vsie, vsie_len);
986                 if (ret < 0) {
987                         g_free(vsie_bytes);
988                         ERR("vsie not allocated.");
989                         return FALSE;
990                 }
991
992                 g_free(vsie_bytes);
993         }
994
995         ERR("Succeeded to get vsie: Frame ID[%d], VSIE[%s]", frame_id, *vsie);
996
997         return TRUE;
998
999 }
1000
1001 gboolean _remove_vsie(const char *interface_name, int frame_id, const char *vsie)
1002 {
1003         GVariant *params = NULL;
1004         GVariant *message = NULL;
1005         GVariantBuilder *bytearray_builder = NULL;
1006         char *if_path;
1007         int i = 0;
1008         size_t vsie_len = 0;
1009
1010         unsigned char *bytearray = NULL;
1011         size_t bytearray_len = 0;
1012
1013         if (frame_id >= NETCONFIG_VSIE_FRAME_MAX) {
1014                 DBG("Invalid parameter, frame-id: %d", frame_id);
1015                 return FALSE;
1016         }
1017
1018         vsie_len = strlen(vsie);
1019         if (vsie_len == 0) {
1020                 DBG("vsie length is zero");
1021                 return FALSE;
1022         }
1023
1024         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
1025
1026         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
1027         if (bytearray == NULL) {
1028                 DBG("Failed to allocate memory to bytearray");
1029                 return FALSE;
1030         }
1031
1032         if (__netconfig_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
1033                 DBG("invalid vsie string");
1034                 g_free(bytearray);
1035                 return FALSE;
1036         }
1037
1038         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1039         for (i = 0; i < bytearray_len; i++)
1040                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
1041
1042         params = g_variant_new("(iay)", frame_id, bytearray_builder);
1043         g_variant_builder_unref(bytearray_builder);
1044
1045         if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
1046         if (if_path == NULL) {
1047                 ERR("Fail to get wpa_supplicant DBus path");
1048                 g_free(bytearray);
1049                 return FALSE;
1050         }
1051
1052         message = netconfig_supplicant_invoke_dbus_method(SUPPLICANT_SERVICE,
1053                         if_path, SUPPLICANT_INTERFACE ".Interface", "VendorElemRem", params);
1054
1055         g_free(if_path);
1056         if (message == NULL) {
1057                 ERR("Failed to send command to wpa_supplicant");
1058                 g_free(bytearray);
1059                 return FALSE;
1060         }
1061
1062         DBG("Succeeded to remove vsie: Frame ID[%d], VSIE[%s]", frame_id, vsie);
1063
1064         g_free(bytearray);
1065         return TRUE;
1066 }
1067
1068 /* dbus method */
1069 gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context,
1070                 const gchar *ifname)
1071 {
1072         guint i = 0;
1073         GSList *config_ids = NULL;
1074         guint length;
1075         gchar **result = NULL;
1076         const gchar *mac_addr = NULL;
1077
1078         g_return_val_if_fail(wifi != NULL, TRUE);
1079
1080         mac_addr = wifi_state_get_mac_address(ifname);
1081         if (!mac_addr) {
1082                 ERR("Fail to get mac-address");
1083                 netconfig_error_no_profile(context);
1084                 return TRUE;
1085         }
1086
1087         DBG("%s", mac_addr);
1088         config_ids = _get_list(mac_addr);
1089         if (config_ids == NULL) {
1090                 ERR("Fail to get config list");
1091                 netconfig_error_no_profile(context);
1092                 return TRUE;
1093         }
1094
1095         length = g_slist_length(config_ids);
1096         result = g_new0(gchar *, length + 1);
1097         for (i = 0; i < length; i++) {
1098                 gchar *config_id = g_slist_nth_data(config_ids, i);
1099                 result[i] = g_strdup(config_id);
1100         }
1101
1102         config_ids = g_slist_nth(config_ids, 0);
1103         g_slist_free_full(config_ids, g_free);
1104
1105         wifi_complete_get_config_ids(wifi, context, (const gchar * const *)result);
1106
1107         for (i = 0; i < length; i++)
1108                 if (result[i])
1109                         g_free(result[i]);
1110
1111         if (result)
1112                 g_free(result);
1113
1114         return TRUE;
1115 }
1116
1117 gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1118                 const gchar *ifname, const gchar *config_id)
1119 {
1120         gboolean ret = FALSE;
1121         GVariantBuilder *b = NULL;
1122         struct wifi_config *conf = NULL;
1123
1124         g_return_val_if_fail(wifi != NULL, TRUE);
1125
1126         conf = g_new0(struct wifi_config, 1);
1127         conf->ip_info = g_new0(wifi_ip_info_s, 1);
1128
1129         ret = _load_configuration(ifname, config_id, conf);
1130         if (ret != TRUE) {
1131                 g_free(conf->ip_info);
1132                 g_free(conf);
1133                 ERR("Fail to _load_configuration");
1134                 netconfig_error_no_profile(context);
1135                 return TRUE;
1136         }
1137
1138         b = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1139         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_NAME, g_variant_new_string(conf->name));
1140         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
1141         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PASSPHRASE, g_variant_new_string(conf->passphrase));
1142         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
1143         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_int32(conf->frequency));
1144
1145         if (conf->proxy_address != NULL)
1146                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
1147         else
1148                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string("NONE"));
1149
1150         if (conf->ip_info->ip_type != NULL)
1151                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_METHOD, g_variant_new_string(conf->ip_info->ip_type));
1152
1153         if (conf->ip_info->ip_address != NULL)
1154                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_ADDRESS, g_variant_new_string(conf->ip_info->ip_address));
1155
1156         if (conf->ip_info->subnet_mask != NULL)
1157                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_SUBNET_MASK, g_variant_new_string(conf->ip_info->subnet_mask));
1158
1159         if (conf->ip_info->prefix_length > 0)
1160                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV6_PREFIX_LEN, g_variant_new_int32(conf->ip_info->prefix_length));
1161
1162         if (conf->ip_info->gateway_address != NULL)
1163                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, g_variant_new_string(conf->ip_info->gateway_address));
1164
1165         if (conf->ip_info->dns_type != NULL)
1166                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_DNS_METHOD, g_variant_new_string(conf->ip_info->dns_type));
1167
1168         int i = 0, count = conf->ip_info->dns_count;
1169         while (i < count) {
1170                 if (conf->ip_info->dns_address[i] != NULL)
1171                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_DNS_ADDRESS, g_variant_new_string(conf->ip_info->dns_address[i]));
1172
1173                 i += 1;
1174         }
1175
1176         if (conf->last_error != NULL)
1177                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string(conf->last_error));
1178         else
1179                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string("ERROR_NONE"));
1180
1181         __free_wifi_configuration(conf);
1182
1183         INFO("Success to load configuration [%s:%s]", ifname, config_id);
1184
1185         wifi_complete_load_configuration(wifi, context, g_variant_builder_end(b));
1186         g_variant_builder_unref(b);
1187         return TRUE;
1188 }
1189
1190 static unsigned char __netconfig_convert_netmask_to_prefixlen(
1191                                                           const char *netmask)
1192 {
1193         unsigned char bits;
1194         in_addr_t mask;
1195         in_addr_t host;
1196
1197         if (!netmask)
1198                 return 32;
1199
1200         mask = inet_network(netmask);
1201         host = ~mask;
1202
1203         /* a valid netmask must be 2^n - 1 */
1204         if ((host & (host + 1)) != 0)
1205                 return -1;
1206
1207         bits = 0;
1208         for (; mask; mask <<= 1)
1209                 ++bits;
1210
1211         return bits;
1212 }
1213
1214 gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1215                 const gchar *ifname, const gchar *config_id, GVariant *configuration)
1216 {
1217         gboolean ret = FALSE;
1218         struct wifi_config *conf = NULL;
1219         GKeyFile *keyfile = NULL;
1220         GVariantIter *iter;
1221         GVariant *value;
1222         gchar *field;
1223         gchar *group_name = NULL;
1224         int order = 0;
1225
1226         if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
1227                 ERR("Invalid parameter");
1228                 netconfig_error_invalid_parameter(context);
1229                 return TRUE;
1230         }
1231
1232         conf = g_new0(struct wifi_config, 1);
1233         conf->ip_info = g_new0(wifi_ip_info_s, 1);
1234
1235         g_variant_get(configuration, "a{sv}", &iter);
1236         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1237                 if (g_strcmp0(field, WIFI_CONFIG_NAME) == 0) {
1238                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1239                                 conf->name = g_strdup(g_variant_get_string(value, NULL));
1240                                 DBG("name [%s]", conf->name);
1241                         } else {
1242                                 conf->name = NULL;
1243                         }
1244                 } else if (g_strcmp0(field, WIFI_CONFIG_SSID) == 0) {
1245                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1246                                 conf->ssid = g_strdup(g_variant_get_string(value, NULL));
1247                                 DBG("ssid [%s]", conf->ssid);
1248                         } else {
1249                                 conf->ssid = NULL;
1250                         }
1251                 } else if (g_strcmp0(field, WIFI_CONFIG_PASSPHRASE) == 0) {
1252                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1253                                 conf->passphrase = g_strdup(g_variant_get_string(value, NULL));
1254                                 DBG("passphrase []");
1255                         } else {
1256                                 conf->passphrase = NULL;
1257                         }
1258                 } else if (g_strcmp0(field, WIFI_CONFIG_HIDDEN) == 0) {
1259                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1260                                 conf->is_hidden = g_strdup(g_variant_get_string(value, NULL));
1261                                 DBG("is_hidden [%s]", conf->is_hidden);
1262                         } else {
1263                                 conf->is_hidden = NULL;
1264                         }
1265                 } else if (g_strcmp0(field, WIFI_CONFIG_FREQUENCY) == 0) {
1266                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1267                                 conf->frequency = g_variant_get_uint32(value);
1268                                 DBG("frequency [%d]", conf->frequency);
1269                         } else {
1270                                 conf->frequency = 0;
1271                         }
1272                 } else if (g_strcmp0(field, WIFI_CONFIG_CREATED) == 0) {
1273                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
1274                                 conf->is_created = g_variant_get_boolean(value);
1275                                 DBG("is_created [%d]", conf->is_created);
1276                         } else {
1277                                 conf->is_created = FALSE;
1278                         }
1279                 } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_METHOD) == 0) {
1280                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1281                                 conf->ip_info->ip_type = g_strdup(g_variant_get_string(value, NULL));
1282                                 DBG("IP config type [%s]", conf->ip_info->ip_type);
1283                         } else {
1284                                 conf->ip_info->ip_type = NULL;
1285                         }
1286                 } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_ADDRESS) == 0) {
1287                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1288                                 conf->ip_info->ip_address = g_strdup(g_variant_get_string(value, NULL));
1289                                 DBG("IP address [%s]", conf->ip_info->ip_address);
1290                         } else {
1291                                 conf->ip_info->ip_address = NULL;
1292                         }
1293                 } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_SUBNET_MASK) == 0) {
1294                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1295                                 conf->ip_info->subnet_mask = g_strdup(g_variant_get_string(value, NULL));
1296                                 DBG("Subnet Mask [%s]", conf->ip_info->subnet_mask);
1297                         } else {
1298                                 conf->ip_info->subnet_mask = NULL;
1299                         }
1300                 } else if (g_strcmp0(field, WIFI_CONFIG_IPV6_PREFIX_LEN) == 0) {
1301                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_INT32)) {
1302                                 conf->ip_info->prefix_length = g_variant_get_int32(value);
1303                                 DBG("IPv6 Prefix Length [%d]", conf->ip_info->prefix_length);
1304                         } else {
1305                                 conf->ip_info->prefix_length = 0;
1306                         }
1307                 } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_GATEWAY_ADDRESS) == 0) {
1308                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1309                                 conf->ip_info->gateway_address = g_strdup(g_variant_get_string(value, NULL));
1310                                 DBG("Gateway address [%s]", conf->ip_info->gateway_address);
1311                         } else {
1312                                 conf->ip_info->gateway_address = NULL;
1313                         }
1314                 } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_DNS_METHOD) == 0) {
1315                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1316                                 conf->ip_info->dns_type = g_strdup(g_variant_get_string(value, NULL));
1317                                 DBG("DNS config type [%s]", conf->ip_info->dns_type);
1318                         } else {
1319                                 conf->ip_info->dns_type = NULL;
1320                         }
1321                 } else if (g_strcmp0(field, WIFI_CONFIG_DNS_ADDRESS) == 0) {
1322                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1323                                 conf->ip_info->dns_address[order] = g_strdup(g_variant_get_string(value, NULL));
1324                                 DBG("DNS address [%s]", conf->ip_info->dns_address[order]);
1325                                 conf->ip_info->dns_count = order + 1;
1326                                 order++;
1327                         } else {
1328                                 conf->ip_info->dns_address[order++] = NULL;
1329                         }
1330                 } else if (g_strcmp0(field, WIFI_CONFIG_PROXYADDRESS) == 0) {
1331                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1332                                 conf->proxy_address = g_strdup(g_variant_get_string(value, NULL));
1333                                 DBG("proxy_address [%s]", conf->proxy_address);
1334                         } else {
1335                                 conf->proxy_address = NULL;
1336                         }
1337                 }
1338         }
1339         conf->favorite = TRUE;
1340         conf->autoconnect = TRUE;
1341
1342         ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
1343                         ifname, config_id, &group_name);
1344         if (ret != TRUE) {
1345                 __free_wifi_configuration(conf);
1346                 ERR("Fail to get_wifi_config_group_name");
1347                 netconfig_error_fail_save_congifuration(context);
1348                 return TRUE;
1349         }
1350
1351         keyfile = g_key_file_new();
1352         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_NAME, conf->name);
1353         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_SSID, conf->ssid);
1354
1355         if (conf->passphrase != NULL) {
1356                 gchar *enc_data = NULL;
1357
1358                 if (conf->is_created == true)
1359                         enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
1360                 else
1361                         enc_data = g_strdup(conf->passphrase);
1362
1363                 if (!enc_data) {
1364                         ERR("Failed to encrypt the passphrase");
1365                 } else {
1366                         g_free(conf->passphrase);
1367                         conf->passphrase = enc_data;
1368                 }
1369
1370                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, conf->passphrase);
1371         }
1372
1373         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_FAVORITE, conf->favorite);
1374         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_AUTOCONNECT, conf->autoconnect);
1375
1376 #if GLIB_CHECK_VERSION(2,62,0)
1377         gint64 real_time = 0;
1378         GDateTime *dt_real_time = NULL;
1379
1380         real_time = g_get_real_time();
1381         dt_real_time = g_date_time_new_from_unix_utc(real_time);
1382         if (dt_real_time) {
1383                 gchar *str = g_date_time_format_iso8601(dt_real_time);
1384                 g_date_time_unref(dt_real_time);
1385                 if (str) {
1386                         g_key_file_set_string(keyfile, group_name,
1387                                               WIFI_CONFIG_MODIFIED, str);
1388                         g_free(str);
1389                 }
1390         }
1391 #else /* GLIB_CHECK_VERSION(2,62,0) */
1392         GTimeVal modified;
1393         g_get_current_time(&modified);
1394         gchar *str = g_time_val_to_iso8601(&modified);
1395         if (str) {
1396                 g_key_file_set_string(keyfile, group_name,
1397                                       WIFI_CONFIG_MODIFIED, str);
1398                 g_free(str);
1399         }
1400 #endif /* GLIB_CHECK_VERSION(2,62,0) */
1401
1402         /* Optional field */
1403         if (conf->proxy_address != NULL) {
1404                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_METHOD, "manual");
1405                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, conf->proxy_address);
1406         }
1407
1408         if (conf->is_hidden != NULL) {
1409                 gboolean hidden = FALSE;
1410                 if (g_strcmp0(conf->is_hidden, "TRUE") == 0)
1411                         hidden = TRUE;
1412                 g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
1413         }
1414
1415         if (conf->frequency > 0)
1416                 g_key_file_set_integer(keyfile, group_name,
1417                         WIFI_CONFIG_FREQUENCY, conf->frequency);
1418
1419         if (conf->ip_info->ip_type != NULL)
1420                 g_key_file_set_string(keyfile, group_name,
1421                         WIFI_CONFIG_IPV4_METHOD, conf->ip_info->ip_type);
1422
1423         if (conf->ip_info->ip_address != NULL)
1424                 g_key_file_set_string(keyfile, group_name,
1425                         WIFI_CONFIG_IPV4_ADDRESS, conf->ip_info->ip_address);
1426
1427         if (conf->ip_info->subnet_mask != NULL) {
1428                 unsigned char prefix_len;
1429                 prefix_len = __netconfig_convert_netmask_to_prefixlen(
1430                                 conf->ip_info->subnet_mask);
1431                 if (prefix_len > 0 && prefix_len < 32)
1432                         g_key_file_set_integer(keyfile, group_name,
1433                                         WIFI_CONFIG_IPV4_SUBNET_MASK, prefix_len);
1434         }
1435
1436         if (conf->ip_info->prefix_length > 0)
1437                 g_key_file_set_integer(keyfile, group_name,
1438                                 WIFI_CONFIG_IPV6_PREFIX_LEN, conf->ip_info->prefix_length);
1439
1440         if (conf->ip_info->gateway_address != NULL)
1441                 g_key_file_set_string(keyfile, group_name,
1442                         WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, conf->ip_info->gateway_address);
1443
1444         if (conf->ip_info->dns_type != NULL)
1445                 g_key_file_set_string(keyfile, group_name,
1446                         WIFI_CONFIG_IPV4_DNS_METHOD, conf->ip_info->dns_type);
1447
1448         int i = 0, count = conf->ip_info->dns_count;
1449         while (i < count) {
1450                 if (conf->ip_info->dns_address[i] != NULL)
1451                         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_DNS_ADDRESS,
1452                                                                   conf->ip_info->dns_address[i]);
1453
1454                 i += 1;
1455         }
1456
1457         ret = wifi_config_save_configuration(ifname, config_id, keyfile);
1458         if (ret == TRUE) {
1459                 INFO("Success to save configuration [%s]", config_id);
1460                 wifi_complete_save_configuration(wifi, context);
1461                 char *file;
1462                 if (get_files_count(CONNMAN_STORAGE) > MAX_WIFI_PROFILES) {
1463                         file = get_least_recently_profile(CONNMAN_STORAGE);
1464                         if (file) {
1465                                 gchar *profileName = g_strdup_printf(CONNMAN_STORAGE "/%s", file);
1466                                 INFO("least modified file:  %s", profileName);
1467                                 if (profileName) {
1468                                         if (__remove_configuration(profileName) != TRUE)
1469                                                 DBG("Failed to remove profile: [%s]", profileName);
1470                                 } else
1471                                         ERR("Profile: [%s] does not exist", file);
1472
1473                                 g_free(profileName);
1474                         }
1475                 }
1476         } else {
1477                 INFO("Fail to save configuration [%s]", config_id);
1478                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailSaveConfiguration");
1479         }
1480
1481         g_key_file_free(keyfile);
1482         g_free(group_name);
1483         __free_wifi_configuration(conf);
1484
1485         g_variant_iter_free(iter);
1486
1487         return TRUE;
1488 }
1489
1490 gboolean handle_load_eap_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1491                 const gchar *ifname, const gchar *config_id)
1492 {
1493         gboolean ret = FALSE;
1494         GVariantBuilder *b = NULL;
1495         struct wifi_config *conf = NULL;
1496
1497         g_return_val_if_fail(wifi != NULL, TRUE);
1498
1499         conf = g_new0(struct wifi_config, 1);
1500         conf->eap_config = g_new0(struct wifi_eap_config, 1);
1501         conf->ip_info = g_new0(wifi_ip_info_s, 1);
1502
1503         ret = _load_configuration(ifname, config_id, conf);
1504         if (ret != TRUE) {
1505                 g_free(conf->eap_config);
1506                 g_free(conf->ip_info);
1507                 g_free(conf);
1508                 ERR("Fail to _load_configuration");
1509                 netconfig_error_no_profile(context);
1510                 return TRUE;
1511         }
1512
1513         b = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1514         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_NAME, g_variant_new_string(conf->name));
1515         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
1516         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
1517         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_int32(conf->frequency));
1518
1519         if (conf->proxy_address != NULL)
1520                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
1521         else
1522                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string("NONE"));
1523
1524         if (conf->last_error != NULL)
1525                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string(conf->last_error));
1526         else
1527                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string("ERROR_NONE"));
1528
1529         if (conf->eap_config != NULL) {
1530                 if (conf->eap_config->anonymous_identity != NULL)
1531                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, g_variant_new_string(conf->eap_config->anonymous_identity));
1532                 else
1533                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, g_variant_new_string("NONE"));
1534
1535                 if (conf->eap_config->ca_cert != NULL)
1536                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CACERT, g_variant_new_string(conf->eap_config->ca_cert));
1537                 else
1538                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CACERT, g_variant_new_string("NONE"));
1539
1540                 if (conf->eap_config->client_cert != NULL)
1541                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CLIENTCERT, g_variant_new_string(conf->eap_config->client_cert));
1542                 else
1543                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CLIENTCERT, g_variant_new_string("NONE"));
1544
1545                 if (conf->eap_config->private_key != NULL)
1546                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY, g_variant_new_string(conf->eap_config->private_key));
1547                 else
1548                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY, g_variant_new_string("NONE"));
1549
1550                 if (conf->eap_config->private_key_password != NULL)
1551                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, g_variant_new_string(conf->eap_config->private_key_password));
1552                 else
1553                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, g_variant_new_string("NONE"));
1554
1555                 if (conf->eap_config->identity != NULL)
1556                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_IDENTITY, g_variant_new_string(conf->eap_config->identity));
1557                 else
1558                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_IDENTITY, g_variant_new_string("NONE"));
1559
1560                 if (conf->eap_config->eap_type != NULL)
1561                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_TYPE, g_variant_new_string(conf->eap_config->eap_type));
1562                 else
1563                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_TYPE, g_variant_new_string("NONE"));
1564
1565                 if (conf->eap_config->eap_auth_type != NULL)
1566                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_AUTH_TYPE, g_variant_new_string(conf->eap_config->eap_auth_type));
1567                 else
1568                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_AUTH_TYPE, g_variant_new_string("NONE"));
1569
1570                 if (conf->eap_config->subject_match != NULL)
1571                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_SUBJECT_MATCH, g_variant_new_string(conf->eap_config->subject_match));
1572                 else
1573                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_SUBJECT_MATCH, g_variant_new_string("NONE"));
1574         }
1575
1576         __free_wifi_configuration(conf);
1577
1578         wifi_complete_load_eap_configuration(wifi, context, g_variant_builder_end(b));
1579         g_variant_builder_unref(b);
1580         return TRUE;
1581 }
1582
1583 gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1584                 const gchar *ifname, const gchar *config_id, GVariant *configuration)
1585 {
1586         gboolean ret = FALSE;
1587         struct wifi_config *conf = NULL;
1588         GKeyFile *keyfile = NULL;
1589         GVariantIter *iter;
1590         GVariant *value;
1591         gchar *field;
1592         gchar *group_name = NULL;
1593
1594         if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
1595                 ERR("Invalid parameter");
1596                 netconfig_error_invalid_parameter(context);
1597                 return TRUE;
1598         }
1599
1600         conf = g_new0(struct wifi_config, 1);
1601         conf->eap_config = g_new0(struct wifi_eap_config, 1);
1602
1603         g_variant_get(configuration, "a{sv}", &iter);
1604         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1605                 if (g_strcmp0(field, WIFI_CONFIG_NAME) == 0) {
1606                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1607                                 conf->name = g_strdup(g_variant_get_string(value, NULL));
1608                                 DBG("name [%s]", conf->name);
1609                         } else {
1610                                 conf->name = NULL;
1611                         }
1612                 } else if (g_strcmp0(field, WIFI_CONFIG_SSID) == 0) {
1613                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1614                                 conf->ssid = g_strdup(g_variant_get_string(value, NULL));
1615                                 DBG("ssid [%s]", conf->ssid);
1616                         } else {
1617                                 conf->ssid = NULL;
1618                         }
1619                 } else if (g_strcmp0(field, WIFI_CONFIG_PASSPHRASE) == 0) {
1620                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1621                                 conf->passphrase = g_strdup(g_variant_get_string(value, NULL));
1622                                 DBG("passphrase [%s]", conf->passphrase);
1623                         } else {
1624                                 conf->passphrase = NULL;
1625                         }
1626                 } else if (g_strcmp0(field, WIFI_CONFIG_HIDDEN) == 0) {
1627                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1628                                 conf->is_hidden = g_strdup(g_variant_get_string(value, NULL));
1629                                 DBG("is_hidden [%s]", conf->is_hidden);
1630                         } else {
1631                                 conf->is_hidden = NULL;
1632                         }
1633                 } else if (g_strcmp0(field, WIFI_CONFIG_FREQUENCY) == 0) {
1634                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1635                                 conf->frequency = g_variant_get_uint32(value);
1636                                 DBG("frequency [%d]", conf->frequency);
1637                         } else {
1638                                 conf->frequency = 0;
1639                         }
1640                 } else if (g_strcmp0(field, WIFI_CONFIG_CREATED) == 0) {
1641                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
1642                                 conf->is_created = g_variant_get_boolean(value);
1643                                 DBG("is_created [%d]", conf->is_created);
1644                         } else {
1645                                 conf->is_created = FALSE;
1646                         }
1647                 } else if (g_strcmp0(field, WIFI_CONFIG_PROXYADDRESS) == 0) {
1648                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1649                                 conf->proxy_address = g_strdup(g_variant_get_string(value, NULL));
1650                                 DBG("proxy_address [%s]", conf->proxy_address);
1651                         } else {
1652                                 conf->proxy_address = NULL;
1653                         }
1654                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
1655                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1656                                 conf->eap_config->anonymous_identity = g_strdup(g_variant_get_string(value, NULL));
1657                                 DBG("anonymous_identity [%s]", conf->eap_config->anonymous_identity);
1658                         } else {
1659                                 conf->eap_config->anonymous_identity = NULL;
1660                         }
1661                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_CACERT) == 0) {
1662                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1663                                 conf->eap_config->ca_cert = g_strdup(g_variant_get_string(value, NULL));
1664                                 DBG("ca_cert [%s]", conf->eap_config->ca_cert);
1665                         } else {
1666                                 conf->eap_config->ca_cert = NULL;
1667                         }
1668                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
1669                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1670                                 conf->eap_config->client_cert = g_strdup(g_variant_get_string(value, NULL));
1671                                 DBG("client_cert [%s]", conf->eap_config->client_cert);
1672                         } else {
1673                                 conf->eap_config->client_cert = NULL;
1674                         }
1675                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
1676                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1677                                 conf->eap_config->private_key = g_strdup(g_variant_get_string(value, NULL));
1678                                 DBG("private_key [%s]", conf->eap_config->private_key);
1679                         } else {
1680                                 conf->eap_config->private_key = NULL;
1681                         }
1682                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD) == 0) {
1683                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1684                                 conf->eap_config->private_key_password = g_strdup(g_variant_get_string(value, NULL));
1685                                 DBG("private_key_password[%s]", conf->eap_config->private_key_password);
1686                         } else {
1687                                 conf->eap_config->private_key_password = NULL;
1688                         }
1689                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_IDENTITY) == 0) {
1690                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1691                                 conf->eap_config->identity = g_strdup(g_variant_get_string(value, NULL));
1692                                 DBG("identity [%s]", conf->eap_config->identity);
1693                         } else {
1694                                 conf->eap_config->identity = NULL;
1695                         }
1696                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_TYPE) == 0) {
1697                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1698                                 conf->eap_config->eap_type = g_strdup(g_variant_get_string(value, NULL));
1699                                 DBG("eap_type [%s]", conf->eap_config->eap_type);
1700                         } else {
1701                                 conf->eap_config->eap_type = NULL;
1702                         }
1703                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
1704                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1705                                 conf->eap_config->eap_auth_type = g_strdup(g_variant_get_string(value, NULL));
1706                                 DBG("eap_auth_type [%s]", conf->eap_config->eap_auth_type);
1707                         } else {
1708                                 conf->eap_config->eap_auth_type = NULL;
1709                         }
1710                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
1711                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1712                                 conf->eap_config->subject_match = g_strdup(g_variant_get_string(value, NULL));
1713                                 DBG("subject_match [%s]", conf->eap_config->subject_match);
1714                         } else {
1715                                 conf->eap_config->subject_match = NULL;
1716                         }
1717                 }
1718         }
1719         conf->favorite = TRUE;
1720         conf->autoconnect = TRUE;
1721
1722         ret = wifi_config_get_group_name(WIFI_CONFIG_PREFIX,
1723                         ifname, config_id, &group_name);
1724         if (ret != TRUE) {
1725                 __free_wifi_configuration(conf);
1726                 ERR("Fail to get_wifi_config_group_name");
1727                 return TRUE;
1728         }
1729
1730         keyfile = g_key_file_new();
1731         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_NAME, conf->name);
1732         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_SSID, conf->ssid);
1733
1734         if (conf->passphrase != NULL) {
1735                 gchar *enc_data = NULL;
1736
1737                 if (conf->is_created == true)
1738                         enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
1739                 else
1740                         enc_data = g_strdup(conf->passphrase);
1741
1742                 if (!enc_data) {
1743                         ERR("Failed to encrypt the passphrase");
1744                 } else {
1745                         g_free(conf->passphrase);
1746                         conf->passphrase = enc_data;
1747                 }
1748                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, conf->passphrase);
1749         }
1750
1751         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_FAVORITE, conf->favorite);
1752         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_AUTOCONNECT, conf->autoconnect);
1753
1754         /* Optional field */
1755         if (conf->proxy_address != NULL) {
1756                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_METHOD, "manual");
1757                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, conf->proxy_address);
1758         }
1759
1760         if (conf->is_hidden != NULL) {
1761                 gboolean hidden = FALSE;
1762                 if (g_strcmp0(conf->is_hidden, "TRUE") == 0)
1763                         hidden = TRUE;
1764                 g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
1765         }
1766
1767         if (conf->frequency > 0)
1768                 g_key_file_set_integer(keyfile, group_name,
1769                         WIFI_CONFIG_FREQUENCY, conf->frequency);
1770
1771         if (conf->eap_config->anonymous_identity != NULL)
1772                 g_key_file_set_string(keyfile, group_name,
1773                         WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, conf->eap_config->anonymous_identity);
1774
1775         if (conf->eap_config->ca_cert != NULL)
1776                 g_key_file_set_string(keyfile, group_name,
1777                         WIFI_CONFIG_EAP_CACERT, conf->eap_config->ca_cert);
1778
1779         if (conf->eap_config->client_cert != NULL)
1780                 g_key_file_set_string(keyfile, group_name,
1781                         WIFI_CONFIG_EAP_CLIENTCERT, conf->eap_config->client_cert);
1782
1783         if (conf->eap_config->private_key != NULL)
1784                 g_key_file_set_string(keyfile, group_name,
1785                         WIFI_CONFIG_EAP_PRIVATEKEY, conf->eap_config->private_key);
1786
1787         if (conf->eap_config->private_key_password != NULL)
1788                 g_key_file_set_string(keyfile, group_name,
1789                         WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, conf->eap_config->private_key_password);
1790
1791         if (conf->eap_config->identity != NULL)
1792                 g_key_file_set_string(keyfile, group_name,
1793                         WIFI_CONFIG_EAP_IDENTITY, conf->eap_config->identity);
1794
1795         if (conf->eap_config->eap_type != NULL)
1796                 g_key_file_set_string(keyfile, group_name,
1797                         WIFI_CONFIG_EAP_TYPE, conf->eap_config->eap_type);
1798
1799         if (conf->eap_config->eap_auth_type != NULL)
1800                 g_key_file_set_string(keyfile, group_name,
1801                         WIFI_CONFIG_EAP_AUTH_TYPE, conf->eap_config->eap_auth_type);
1802
1803         if (conf->eap_config->subject_match != NULL)
1804                 g_key_file_set_string(keyfile, group_name,
1805                         WIFI_CONFIG_EAP_SUBJECT_MATCH, conf->eap_config->subject_match);
1806
1807         ret = wifi_config_save_configuration(ifname, config_id, keyfile);
1808         if (ret == TRUE) {
1809                 INFO("Success to save eap configuration [%s]", config_id);
1810                 wifi_complete_save_eap_configuration(wifi, context);
1811         } else {
1812                 INFO("Fail to save eap configuration [%s]", config_id);
1813                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailSaveEapConfiguration");
1814         }
1815
1816         g_key_file_free(keyfile);
1817         g_free(group_name);
1818         __free_wifi_configuration(conf);
1819
1820         g_variant_iter_free(iter);
1821
1822         return TRUE;
1823 }
1824
1825 gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1826                         const gchar *ifname, const gchar *config_id)
1827 {
1828         gboolean ret = FALSE;
1829
1830         if ((wifi == NULL) || (config_id == NULL)) {
1831                 ERR("Invalid parameter");
1832                 netconfig_error_invalid_parameter(context);
1833                 return TRUE;
1834         }
1835
1836         ret = _remove_configuration(ifname, config_id);
1837         if (ret != TRUE) {
1838                 /* no configuration or error */
1839                 ERR("No [%s] configuration", config_id);
1840                 netconfig_error_no_profile(context);
1841                 return TRUE;
1842         }
1843
1844         wifi_complete_remove_configuration(wifi, context);
1845         return TRUE;
1846 }
1847
1848 gboolean handle_reset_wifi_config(Wifi *wifi, GDBusMethodInvocation *context)
1849 {
1850         DIR *dir_ptr = NULL;
1851         struct dirent *file = NULL;
1852         struct stat buf;
1853         char dir_name[512] = { 0, };
1854         char file_name[1024] = { 0, };
1855
1856         g_return_val_if_fail(wifi != NULL, TRUE);
1857
1858         DBG("Try to remove connman Wi-Fi config files...");
1859
1860         if ((dir_ptr = opendir(CONNMAN_STORAGE)) != NULL) {
1861                 while ((file = readdir(dir_ptr)) != NULL) {
1862                         if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0 ||
1863                                         strncmp(file->d_name, WIFI_CONFIG_PREFIX, strlen(WIFI_CONFIG_PREFIX)) != 0) {
1864                                 continue;
1865                         }
1866
1867                         snprintf(dir_name, 512, CONNMAN_STORAGE"/%s", file->d_name);
1868
1869                         if (lstat(dir_name, &buf) == -1)
1870                                 continue;
1871
1872                         DBG("Remove wifi config: %s", file->d_name);
1873
1874                         if (S_ISDIR(buf.st_mode)) {
1875                                 memset(file_name, 0, 1024);
1876                                 snprintf(file_name, 1024, "%s/data", dir_name);
1877                                 unlink(file_name);
1878                                 memset(file_name, 0, 1024);
1879                                 snprintf(file_name, 1024, "%s/settings", dir_name);
1880                                 unlink(file_name);
1881                         }
1882                         rmdir(dir_name);
1883                 }
1884
1885                 closedir(dir_ptr);
1886                 sync();
1887         }
1888
1889         wifi_complete_reset_wifi_config(wifi, context);
1890
1891         return TRUE;
1892 }
1893
1894 /* config field key / value */
1895 /*
1896  * [wifi_macaddress_config_id]
1897  * Name=name (mandatory)
1898  * SSID=SSID (mandatory)
1899  * Frequency=2462 (X)
1900  * Favorite=true (X)
1901  * AutoConnect=true (Default true)
1902  * Modified=2015-03-20 (X)
1903  * IPv4.method=manual (O)
1904  * IPv4.DHCP.LastAddress=192.0.0.1 (X)
1905  * IPv6.method=auto (X)
1906  * IPv6.privacy=disabled (X)
1907  * IPv4.netmask_prefixlen=24 (X)
1908  * IPv4.local_address=192.0.0.1 (O)
1909  * IPv4.gateway=192.0.0.1 (O ? X ?)
1910  * Nameservers=192.168.43.22; (O)
1911  * Proxy.Method=manual (O)
1912  * Proxy.Servers=trst.com:8888; (O)
1913  */
1914 gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
1915                 const gchar *ifname, const gchar *config_id, const gchar *key, const gchar *value)
1916 {
1917         gboolean ret = FALSE;
1918         gchar *keyfile_key = NULL;
1919
1920         g_return_val_if_fail(wifi != NULL, TRUE);
1921         g_return_val_if_fail(config_id != NULL, TRUE);
1922         g_return_val_if_fail(key != NULL, TRUE);
1923
1924         DBG("Key[%s] Value[%s]", key, value);
1925
1926         if (g_strcmp0(key, WIFI_CONFIG_PROXYADDRESS) == 0) {
1927                 ret = _set_field(ifname, config_id, WIFI_CONFIG_PROXY_METHOD, "manual");
1928                 if (!ret) {
1929                         ERR("Fail to [%s]set_wifi_config_field(%s/manual)", config_id, WIFI_CONFIG_PROXY_METHOD);
1930                         netconfig_error_invalid_parameter(context);
1931                         return TRUE;
1932                 }
1933                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_PROXY_SERVER);
1934         } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
1935                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_HIDDEN);
1936         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
1937                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY);
1938         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CACERT) == 0) {
1939                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_CACERT);
1940         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
1941                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_CLIENTCERT);
1942         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
1943                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_PRIVATEKEY);
1944         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_IDENTITY) == 0) {
1945                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_IDENTITY);
1946         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_TYPE) == 0) {
1947                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_TYPE);
1948         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
1949                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_AUTH_TYPE);
1950         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
1951                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_SUBJECT_MATCH);
1952         } else {
1953                 ERR("Not supported key[%s]", key);
1954                 netconfig_error_invalid_parameter(context);
1955                 return TRUE;
1956         }
1957
1958         ret = _set_field(ifname, config_id, keyfile_key, (const gchar *)value);
1959         if (!ret) {
1960                 ERR("Fail to [%s]set_wifi_config_field(%s/%s)", config_id, key, value);
1961         }
1962
1963         if (keyfile_key != NULL)
1964                 g_free(keyfile_key);
1965
1966         wifi_complete_set_config_field(wifi, context);
1967         return TRUE;
1968 }
1969
1970 gboolean handle_get_config_passphrase(Wifi *wifi, GDBusMethodInvocation *context,
1971                         const gchar *ifname, const gchar *config_id)
1972 {
1973         gboolean ret = FALSE;
1974         gchar *passphrase = NULL;
1975
1976         if ((wifi == NULL) || (config_id == NULL)) {
1977                 ERR("Invalid parameter");
1978                 netconfig_error_invalid_parameter(context);
1979                 return TRUE;
1980         }
1981
1982         ret = _get_field(ifname, config_id, WIFI_CONFIG_PASSPHRASE, &passphrase);
1983         if (!ret) {
1984                 ERR("Fail to [%s] _get_field(%s)", config_id, WIFI_CONFIG_PASSPHRASE);
1985                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
1986                 return TRUE;
1987         }
1988
1989         wifi_complete_get_config_passphrase(wifi, context, passphrase);
1990         g_free(passphrase);
1991
1992         return TRUE;
1993 }
1994
1995 gboolean handle_add_vsie(Wifi *wifi, GDBusMethodInvocation *context,
1996                 const gchar *ifname, int frame_id, const gchar *vsie)
1997 {
1998         DBG("Frame ID: [%d] VSIE: [%s]", frame_id, vsie);
1999
2000         g_return_val_if_fail(wifi != NULL, TRUE);
2001         g_return_val_if_fail(vsie != NULL, TRUE);
2002
2003         gboolean ret = FALSE;
2004
2005         ret = _add_vsie(ifname, frame_id, vsie);
2006         if (!ret) {
2007                 DBG("Failed to add vsie: %s", vsie);
2008                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
2009                 return TRUE;
2010         }
2011
2012         wifi_complete_add_vsie(wifi, context);
2013         return TRUE;
2014 }
2015
2016 gboolean handle_get_vsie(Wifi *wifi, GDBusMethodInvocation *context,
2017                 const gchar *ifname, int frame_id)
2018 {
2019         DBG("Frame ID: [%d]", frame_id);
2020
2021         g_return_val_if_fail(wifi != NULL, TRUE);
2022
2023         gboolean ret = FALSE;
2024         gchar *vsie = NULL;
2025
2026         ret = _get_vsie(ifname, frame_id, &vsie);
2027         if (!ret) {
2028                 DBG("Failed to get vsie for frame:[%d]", frame_id);
2029                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
2030                 return TRUE;
2031         }
2032
2033         DBG("Received vsie: %s", vsie);
2034         wifi_complete_get_vsie(wifi, context, vsie);
2035
2036         return TRUE;
2037 }
2038
2039 gboolean handle_remove_vsie(Wifi *wifi, GDBusMethodInvocation *context,
2040                 const gchar *ifname, int frame_id, const gchar *vsie)
2041 {
2042         DBG("Frame ID: [%d] VSIE: [%s]", frame_id, vsie);
2043
2044         g_return_val_if_fail(wifi != NULL, TRUE);
2045         g_return_val_if_fail(vsie != NULL, TRUE);
2046
2047         gboolean ret = FALSE;
2048
2049         ret = _remove_vsie(ifname, frame_id, vsie);
2050         if (!ret) {
2051                 DBG("Failed to remove vsie: %s", vsie);
2052                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
2053                 return TRUE;
2054         }
2055
2056         wifi_complete_remove_vsie(wifi, context);
2057         return TRUE;
2058 }