Rectify gvariant type for frequency
[platform/core/connectivity/net-config.git] / src / network-state.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 <vconf.h>
21 #include <vconf-keys.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <net/if.h>
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
29 #include <sys/ioctl.h>
30
31 #include "log.h"
32 #include "util.h"
33 #include "setting.h"
34 #include "netdbus.h"
35 #include "neterror.h"
36 #include "emulator.h"
37 #include "wifi-state.h"
38 #include "wifi-power.h"
39 #include "network-state.h"
40 #include "network-dpm.h"
41 #include "network-monitor.h"
42 #include "netsupplicant.h"
43 #include "clatd-handler.h"
44 #if defined TIZEN_DEBUG_ENABLE
45 #include "network-dump.h"
46 #endif
47
48 #include "generated-code.h"
49 /* Define TCP buffer sizes for various networks */
50 /* ReadMin, ReadInitial, ReadMax */ /* WriteMin, WriteInitial, WriteMax */
51 #define NET_TCP_BUFFERSIZE_DEFAULT_READ         "4096 87380 704512"
52 #define NET_TCP_BUFFERSIZE_DEFAULT_WRITE        "4096 16384 110208"
53 #define NET_TCP_BUFFERSIZE_WIFI_READ            "524288 1048576 2560000"
54 #define NET_TCP_BUFFERSIZE_WIFI_WRITE           "524288 1048576 2560000"
55 #define NET_TCP_BUFFERSIZE_LTE_READ             "524288 1048576 2560000"
56 #define NET_TCP_BUFFERSIZE_LTE_WRITE            "524288 1048576 2560000"
57 #define NET_TCP_BUFFERSIZE_UMTS_READ            "4094 87380 704512"
58 #define NET_TCP_BUFFERSIZE_UMTS_WRITE           "4096 16384 110208"
59 #define NET_TCP_BUFFERSIZE_HSPA_READ            "4092 87380 704512"
60 #define NET_TCP_BUFFERSIZE_HSPA_WRITE           "4096 16384 262144"
61 #define NET_TCP_BUFFERSIZE_HSDPA_READ           "4092 87380 704512"
62 #define NET_TCP_BUFFERSIZE_HSDPA_WRITE          "4096 16384 262144"
63 #define NET_TCP_BUFFERSIZE_HSUPA_READ           "4092 87380 704512"
64 #define NET_TCP_BUFFERSIZE_HSUPA_WRITE          "4096 16384 262144"
65 #define NET_TCP_BUFFERSIZE_HSPAP_READ           "4092 87380 1220608"
66 #define NET_TCP_BUFFERSIZE_HSPAP_WRITE          "4096 16384 1220608"
67 #define NET_TCP_BUFFERSIZE_EDGE_READ            "4093 26280 35040"
68 #define NET_TCP_BUFFERSIZE_EDGE_WRITE           "4096 16384 35040"
69 #define NET_TCP_BUFFERSIZE_GPRS_READ            "4096 30000 30000"
70 #define NET_TCP_BUFFERSIZE_GPRS_WRITE           "4096 8760 11680"
71
72 #define NET_TCP_BUFFERSIZE_WIFI_RMEM_MAX        "1048576"
73 #define NET_TCP_BUFFERSIZE_WIFI_WMEM_MAX        "2097152"
74 #define NET_TCP_BUFFERSIZE_LTE_RMEM_MAX         "5242880"
75
76 #define NET_TCP_BUFFERSIZE_WIFID_WMEM_MAX       "2097152"
77
78 #define NET_PROC_SYS_NET_IPV4_TCP_RMEM                  "/proc/sys/net/ipv4/tcp_rmem"
79 #define NET_PROC_SYS_NET_IPv4_TCP_WMEM                  "/proc/sys/net/ipv4/tcp_wmem"
80 #define NET_PROC_SYS_NET_IPV4_UDP_MEM                   "/proc/sys/net/ipv4/udp_mem"
81 #define NET_PROC_SYS_NET_CORE_RMEM_DEFAULT              "/proc/sys/net/core/rmem_default"
82 #define NET_PROC_SYS_NET_CORE_RMEM_MAX                  "/proc/sys/net/core/rmem_max"
83 #define NET_PROC_SYS_NET_CORE_WMEM_DEFAULT              "/proc/sys/net/core/wmem_default"
84 #define NET_PROC_SYS_NET_CORE_WMEM_MAX                  "/proc/sys/net/core/wmem_max"
85
86 #define ROUTE_EXEC_PATH                                         "/sbin/route"
87
88 #define TELEPHONY_SERVICE                       "com.tcore.ps"
89 #define TELEPHONY_MASTER_INTERFACE              TELEPHONY_SERVICE ".master"
90 #define TELEPHONY_MODEM_INTERFACE               TELEPHONY_SERVICE ".modem"
91 #define TELEPHONY_PROFILE_INTERFACE             TELEPHONY_SERVICE ".context"
92 #define TELEPHONY_MASTER_PATH                   "/"
93 #define NET_PROFILE_NAME_LEN_MAX 512
94
95 typedef struct {
96         char                    profile_name[NET_PROFILE_NAME_LEN_MAX];
97 } net_profile_name_t;
98
99 static Network *netconfigstate = NULL;
100 #if defined TIZEN_DEBUG_ENABLE
101 static Tcpdump *tcpdump_object = NULL;
102 #endif
103 static Battery *battery_object = NULL;
104
105 struct netconfig_default_connection {
106         char *profile;
107         char *ifname;
108         char *mac_address;
109         char *ipaddress;
110         char *ipaddress6;
111         char *proxy;
112         char *essid;
113         unsigned int freq;
114         gboolean is_metered;
115         gboolean is_internet;
116 };
117
118 struct netconfig_vconf_key_t {
119         const char *key;
120         enum vconf_t type;
121 };
122
123 static struct netconfig_vconf_key_t network_vconf_keys[] = {
124         {VCONFKEY_NETWORK_IP, VCONF_TYPE_STRING},
125         {VCONFKEY_NETWORK_PROXY, VCONF_TYPE_STRING},
126         {VCONFKEY_NETWORK_IP6, VCONF_TYPE_STRING},
127         {VCONF_ETH_MAC_ADDRESS, VCONF_TYPE_STRING},
128         {VCONFKEY_WIFI_CONNECTED_AP_NAME, VCONF_TYPE_STRING},
129         {VCONFKEY_WIFI_BSSID_ADDRESS, VCONF_TYPE_STRING},
130         {VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, VCONF_TYPE_INT},
131         {VCONFKEY_NETWORK_STATUS, VCONF_TYPE_INT},
132         {VCONFKEY_DNET_STATE, VCONF_TYPE_INT},
133         {VCONF_WIFI_OFF_STATE_BY_EMERGENCY, VCONF_TYPE_INT},
134         {VCONF_WIFI_OFF_STATE_BY_AIRPLANE, VCONF_TYPE_INT},
135         {VCONFKEY_NETWORK_WIFI_OFF_BY_AIRPLANE, VCONF_TYPE_INT},
136         {VCONFKEY_WIFI_TRANSFER_STATE, VCONF_TYPE_INT},
137         {VCONF_WIFI_OFF_STATE_BY_RESTRICTED, VCONF_TYPE_INT},
138         {VCONFKEY_WIFI_STRENGTH, VCONF_TYPE_INT},
139         {VCONFKEY_WIFI_STATE, VCONF_TYPE_INT},
140         {VCONFKEY_NETWORK_WIFI_STATE, VCONF_TYPE_INT},
141         {VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, VCONF_TYPE_INT},
142         {VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, VCONF_TYPE_INT},
143         {VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV, VCONF_TYPE_INT},
144         {VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT, VCONF_TYPE_INT},
145         {VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, VCONF_TYPE_INT},
146         {VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, VCONF_TYPE_INT},
147         {VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, VCONF_TYPE_INT},
148         {VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, VCONF_TYPE_INT},
149         {NULL, }
150 };
151
152 static struct netconfig_default_connection
153                                 netconfig_default_connection_info = { NULL, };
154
155 gboolean netconfig_iface_network_state_ethernet_cable_state(gint32 *state);
156
157 static gboolean __netconfig_is_connected(GVariantIter *array)
158 {
159         gboolean is_connected = FALSE;
160         GVariant *variant = NULL;
161         gchar *key = NULL;
162         const gchar *value = NULL;
163
164         while (g_variant_iter_loop(array, "{sv}", &key, &variant)) {
165                 if (g_strcmp0(key, "State") != 0)
166                         continue;
167
168                 if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
169                         value = g_variant_get_string(variant, NULL);
170                         if (g_strcmp0(value, "ready") == 0 || g_strcmp0(value, "online") == 0)
171                                 is_connected = TRUE;
172                 }
173
174                 g_free(key);
175                 g_variant_unref(variant);
176                 break;
177         }
178
179         return is_connected;
180 }
181
182 static int __netconfig_telephony_get_modem_object_path(GSList **modem_path_list)
183 {
184         GVariant *result;
185         GVariantIter *iter_modem = NULL;
186         GVariantIter *modem_properties = NULL;
187         const char *modem_path;
188
189         result = netconfig_invoke_dbus_method(TELEPHONY_SERVICE, TELEPHONY_MASTER_PATH,
190                         TELEPHONY_MASTER_INTERFACE, "GetModems", NULL);
191         if (result == NULL) {
192                 ERR("Failed to get modem path list");
193                 return -1;
194         }
195
196         g_variant_get(result, "(a{sa{ss}})", &iter_modem);
197         while (g_variant_iter_loop(iter_modem, "{sa{ss}}", &modem_path, &modem_properties)) {
198                 *modem_path_list = g_slist_append(*modem_path_list, g_strdup(modem_path));
199                 DBG("modem object path: %s",    modem_path);
200         }
201
202         g_variant_iter_free(iter_modem);
203         g_variant_unref(result);
204
205         return 0;
206 }
207
208 static int __netconfig_telephony_get_profile_list(net_profile_name_t **profile_list,
209                 int *profile_count)
210 {
211         int ret = 0;
212         int count = 0, i = 0;
213         const char *str = NULL;
214         GVariant *result;
215         GVariantIter *iter = NULL;
216         GSList *profiles = NULL, *list = NULL;
217         net_profile_name_t *plist = NULL;
218
219         GSList *modem_path_list = NULL;
220         const char *path = NULL;
221
222         ret = __netconfig_telephony_get_modem_object_path(&modem_path_list);
223         if (ret < 0) {
224                 ERR("Failed to get modems path list");
225
226                 g_slist_free_full(modem_path_list, g_free);
227                 return ret;
228         }
229
230         for (list = modem_path_list; list != NULL; list = list->next) {
231                 path = (const char *)list->data;
232
233                 DBG("path: %s", path);
234                 result = netconfig_invoke_dbus_method(TELEPHONY_SERVICE, path,
235                                 TELEPHONY_MODEM_INTERFACE, "GetProfileList", NULL);
236                 if (result == NULL) {
237                         DBG("Failed to get profiles: %s", path);
238                         continue;
239                 }
240
241                 g_variant_get(result, "(as)", &iter);
242                 while (g_variant_iter_loop(iter, "s", &str))
243                         profiles = g_slist_append(profiles, g_strdup(str));
244
245                 g_variant_iter_free(iter);
246                 g_variant_unref(result);
247         }
248
249         g_slist_free_full(modem_path_list, g_free);
250
251         count = g_slist_length(profiles);
252         if (count > 0) {
253                 plist = (net_profile_name_t*)malloc(sizeof(net_profile_name_t) * count);
254         } else {
255                 *profile_count = 0;
256                 goto out;
257         }
258
259         if (plist == NULL) {
260                 ERR("Failed to allocate memory");
261                 *profile_count = 0;
262                 ret = -1;
263                 goto out;
264         }
265
266         for (list = profiles, i = 0; list != NULL; list = list->next, i++)
267                 g_strlcpy(plist[i].profile_name,
268                                 (const char *)list->data, NET_PROFILE_NAME_LEN_MAX);
269
270         *profile_list = plist;
271         *profile_count = count;
272
273 out:
274         g_slist_free_full(profiles, g_free);
275
276         return ret;
277 }
278
279 static int __netconfig_telephony_search_pdp_profile(const char* profile_name, net_profile_name_t* pdp_name)
280 {
281         int ret;
282         net_profile_name_t* profile_list = NULL;
283         char* prof_name = NULL;
284         char* tel_prof_name = NULL;
285         char* found_ptr = NULL;
286         int profile_count = 0;
287         int i;
288
289         /* Get pdp profile list from telephony service */
290         ret = __netconfig_telephony_get_profile_list(&profile_list, &profile_count);
291         if (ret < 0) {
292                 ERR("Failed to get profile list from telephony service");
293                 g_free(profile_list);
294                 return ret;
295         }
296
297         if (profile_list == NULL || profile_count <= 0) {
298                 ERR("There is no PDP profiles");
299                 g_free(profile_list);
300                 return -1;
301         }
302
303         /* Find matching profile */
304         prof_name = strrchr(profile_name, '/') + 1;
305         for (i = 0; i < profile_count; i++) {
306                 tel_prof_name = strrchr(profile_list[i].profile_name, '/') + 1;
307                 found_ptr = strstr(prof_name, tel_prof_name);
308
309                 if (found_ptr != NULL && g_strcmp0(found_ptr, tel_prof_name) == 0) {
310                         g_strlcpy(pdp_name->profile_name,
311                                         profile_list[i].profile_name, NET_PROFILE_NAME_LEN_MAX);
312
313                         DBG("PDP profile name found in cellular profile: %s", pdp_name->profile_name);
314                         break;
315                 }
316         }
317
318         if (i >= profile_count) {
319                 ERR("There is no matching PDP profiles");
320                 g_free(profile_list);
321                 return -1;
322         }
323
324         g_free(profile_list);
325
326         return ret;
327 }
328
329 static gboolean __netconfig_telephony_get_metered_info(net_profile_name_t* pdp_name)
330 {
331         GVariant *result;
332         GVariantIter *iter;
333         const gchar *key = NULL;
334         const gchar *value = NULL;
335         gboolean ret = FALSE;
336
337         if (pdp_name == NULL) {
338                 ERR("Invalid parameter!");
339                 return ret;
340         }
341
342         result = netconfig_invoke_dbus_method(TELEPHONY_SERVICE, pdp_name->profile_name,
343                         TELEPHONY_PROFILE_INTERFACE, "GetProfile", NULL);
344         if (result == NULL) {
345                 ERR("_net_invoke_dbus_method failed");
346                 return ret;
347         }
348
349         g_variant_get(result, "(a{ss})", &iter);
350         while (g_variant_iter_next(iter, "{ss}", &key, &value)) {
351                 if (g_strcmp0(key, "is_metered") == 0) {
352                         if (value == NULL)
353                                 continue;
354
355                         if (g_strcmp0(value, "TRUE") == 0)
356                                 ret = TRUE;
357                 }
358         }
359
360         g_variant_iter_free(iter);
361         g_variant_unref(result);
362
363         DBG("is_metered = %s", ret ? "TRUE" : "FALSE");
364
365         return ret;
366 }
367
368 static int __netconfig_reset_ipv4_socket(const char *interface_name)
369 {
370         int ret;
371         int fd;
372         struct ifreq ifr;
373         struct sockaddr_in sai;
374         const char *ipaddr = netconfig_get_default_ipaddress();
375         DBG("ipaddr-[%s]", ipaddr);
376
377         if (!ipaddr)
378                 return -1;
379
380         fd = socket(AF_INET, SOCK_DGRAM, 0);
381         if (fd < 0)
382                 return -1;
383
384         memset(&sai, 0, sizeof(struct sockaddr_in));
385         sai.sin_family = AF_INET;
386         sai.sin_port = 0;
387         if (!inet_aton(ipaddr, &sai.sin_addr)) {
388                 DBG("fail to inet_aton()");
389                 close(fd);
390                 return -1;
391         }
392
393         memset(&ifr, 0, sizeof(struct ifreq));
394         memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
395         g_strlcpy((char *)ifr.ifr_name, interface_name, IFNAMSIZ);
396
397 #ifndef SIOCKILLADDR
398 #define SIOCKILLADDR    0x8939
399 #endif
400
401         ret = ioctl(fd, SIOCKILLADDR, &ifr);
402         if (ret < 0) {
403                 DBG("fail to ioctl[SIOCKILLADDR]");
404                 close(fd);
405                 return -1;
406         }
407
408         close(fd);
409         return 0;
410 }
411
412 static void __netconfig_clear_default_connection_info(void)
413 {
414         static char *old_profile = NULL;
415
416         if (netconfig_default_connection_info.profile != NULL) {
417
418                 netconfig_notify_online_state(netconfig_default_connection_info.ifname, FALSE);
419
420                 if (netconfig_is_wifi_profile(netconfig_default_connection_info.profile))
421                         __netconfig_reset_ipv4_socket(netconfig_default_connection_info.ifname);
422
423                 g_free(old_profile);
424                 old_profile = strdup(netconfig_default_connection_info.profile);
425
426                 g_free(netconfig_default_connection_info.profile);
427                 netconfig_default_connection_info.profile = NULL;
428
429                 g_free(netconfig_default_connection_info.ifname);
430                 netconfig_default_connection_info.ifname = NULL;
431
432                 g_free(netconfig_default_connection_info.ipaddress);
433                 netconfig_default_connection_info.ipaddress = NULL;
434
435                 g_free(netconfig_default_connection_info.ipaddress6);
436                 netconfig_default_connection_info.ipaddress6 = NULL;
437
438                 g_free(netconfig_default_connection_info.proxy);
439                 netconfig_default_connection_info.proxy = NULL;
440
441                 g_free(netconfig_default_connection_info.mac_address);
442                 netconfig_default_connection_info.mac_address = NULL;
443
444                 netconfig_default_connection_info.freq = 0;
445                 netconfig_default_connection_info.is_metered = FALSE;
446                 netconfig_default_connection_info.is_internet = FALSE;
447
448                 g_free(netconfig_default_connection_info.essid);
449                 netconfig_default_connection_info.essid = NULL;
450         }
451 }
452
453 static gboolean __netconfig_get_default_connection_info(void)
454 {
455         GVariant *message = NULL, *variant = NULL, *variant2 = NULL;
456         GVariantIter *iter = NULL, *iter1 = NULL;
457         GVariant *var = NULL;
458         gchar *obj_path;
459         gchar *key = NULL;
460         gchar *key1 = NULL;
461         gchar *key2 = NULL;
462
463         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
464                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
465                         "GetDefaultService", NULL);
466         if (message == NULL) {
467                 ERR("Failed to get services informations");
468                 return FALSE;
469         }
470
471         if (!g_variant_is_of_type(message, G_VARIANT_TYPE("(oa{sv})"))) {
472                 DBG("There is no default service");
473                 __netconfig_clear_default_connection_info();
474                 g_variant_unref(message);
475                 return TRUE;
476         }
477
478         g_variant_get(message, "(oa{sv})", &obj_path, &iter);
479
480         if (g_strcmp0(obj_path, netconfig_default_connection_info.profile) == 0) {
481                 g_variant_unref(message);
482                 g_variant_iter_free(iter);
483                 return FALSE;
484         }
485
486         __netconfig_clear_default_connection_info();
487
488         netconfig_default_connection_info.profile = g_strdup(obj_path);
489
490         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
491                 const gchar *value = NULL;
492                 guint16 freq = 0;
493                 if (g_strcmp0(key, "Name") == 0 &&
494                                 netconfig_is_wifi_profile(obj_path) == TRUE) {
495                         if (g_variant_is_of_type(var, G_VARIANT_TYPE_STRING)) {
496                                 value = g_variant_get_string(var, NULL);
497
498                                 netconfig_default_connection_info.essid = g_strdup(value);
499                         }
500                 } else if (g_strcmp0(key, "State") == 0) {
501                         if (g_variant_is_of_type(var, G_VARIANT_TYPE_STRING)) {
502                                 value = g_variant_get_string(var, NULL);
503
504                                 if (g_strcmp0(value, "online") == 0) {
505                                         netconfig_default_connection_info.is_internet = TRUE;
506                                         netconfig_notify_online_state(netconfig_default_connection_info.ifname, TRUE);
507                                 }
508                         }
509                 } else if (g_strcmp0(key, "Ethernet") == 0) {
510                         g_variant_get(var, "a{sv}", &iter1);
511                         if (iter1 == NULL)
512                                 continue;
513                         while (g_variant_iter_loop(iter1, "{sv}", &key1, &variant)) {
514                                 if (g_strcmp0(key1, "Interface") == 0) {
515                                         value = g_variant_get_string(variant, NULL);
516                                         netconfig_default_connection_info.ifname = g_strdup(value);
517                                 } else if (g_strcmp0(key1, "Address") == 0) {
518                                         value = g_variant_get_string(variant, NULL);
519                                         netconfig_default_connection_info.mac_address = g_strdup(value);
520                                 }
521                         }
522                         g_variant_iter_free(iter1);
523                 } else if (g_strcmp0(key, "IPv4") == 0) {
524                         g_variant_get(var, "a{sv}", &iter1);
525                         if (iter1 == NULL)
526                                 continue;
527                         while (g_variant_iter_loop(iter1, "{sv}", &key1, &variant)) {
528                                 if (g_strcmp0(key1, "Address") == 0) {
529                                         value = g_variant_get_string(variant, NULL);
530                                         netconfig_default_connection_info.ipaddress = g_strdup(value);
531                                 }
532                         }
533                         g_variant_iter_free(iter1);
534                 } else if (g_strcmp0(key, "IPv6") == 0) {
535                         g_variant_get(var, "a{sv}", &iter1);
536                         if (iter1 == NULL)
537                                 continue;
538                         while (g_variant_iter_loop(iter1, "{sv}", &key1, &variant)) {
539                                 if (g_strcmp0(key1, "Address") == 0) {
540                                         value = g_variant_get_string(variant, NULL);
541                                         netconfig_default_connection_info.ipaddress6 = g_strdup(value);
542                                 }
543                         }
544                         g_variant_iter_free(iter1);
545
546                 } else if (g_strcmp0(key, "Proxy") == 0) {
547                         g_variant_get(var, "a{sv}", &iter1);
548                         if (iter1 == NULL)
549                                 continue;
550                         while (g_variant_iter_loop(iter1, "{sv}", &key2, &variant2)) {
551                                 GVariantIter *iter_sub = NULL;
552
553                                 if (g_strcmp0(key2, "Servers") == 0) {
554                                         if (!g_variant_is_of_type(variant2, G_VARIANT_TYPE_STRING_ARRAY)) {
555                                                 g_free(key2);
556                                                 g_variant_unref(variant2);
557                                                 break;
558                                         }
559
560                                         g_variant_get(variant2, "as", &iter_sub);
561                                         g_variant_iter_loop(iter_sub, "s", &value);
562                                         g_variant_iter_free(iter_sub);
563                                         if (value != NULL && (strlen(value) > 0))
564                                                 netconfig_default_connection_info.proxy = g_strdup(value);
565                                 } else if (g_strcmp0(key2, "Method") == 0) {
566                                         if (g_variant_is_of_type(variant2, G_VARIANT_TYPE_STRING)) {
567                                                 g_free(key2);
568                                                 g_variant_unref(variant2);
569                                                 break;
570                                         }
571
572                                         value = g_variant_get_string(variant2, NULL);
573                                         if (g_strcmp0(value, "direct") == 0) {
574                                                 g_free(netconfig_default_connection_info.proxy);
575                                                 netconfig_default_connection_info.proxy = NULL;
576
577                                                 g_free(key2);
578                                                 g_variant_unref(variant2);
579                                                 break;
580                                         }
581                                 }
582                         }
583                         g_variant_iter_free(iter1);
584                 } else if (g_strcmp0(key, "Frequency") == 0) {
585                         if (g_variant_is_of_type(var, G_VARIANT_TYPE_UINT16)) {
586                                 freq = g_variant_get_uint16(var);
587                                 netconfig_default_connection_info.freq = freq;
588                         }
589                 }
590         }
591
592         if (netconfig_is_cellular_profile(obj_path) == TRUE) {
593                 net_profile_name_t pdp_name;
594                 int ret;
595
596                 ret = __netconfig_telephony_search_pdp_profile(obj_path, &pdp_name);
597                 if (ret >= 0 && strlen(pdp_name.profile_name) > 0)
598                         if (__netconfig_telephony_get_metered_info(&pdp_name))
599                                 netconfig_default_connection_info.is_metered = TRUE;
600         }
601
602         g_variant_unref(message);
603         g_variant_iter_free(iter);
604
605         return TRUE;
606 }
607
608 static char *__netconfig_get_preferred_ipv6_address(char *profile)
609 {
610         GVariant *message = NULL, *variant = NULL, *next = NULL;
611         GVariantIter *iter = NULL, *sub_iter = NULL, *service = NULL;
612         gchar *obj_path;
613         gchar *key = NULL;
614         gchar *sub_key = NULL;
615         gchar *preferred_address6 = NULL;
616         gboolean found_profile = 0;
617
618         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
619                                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
620                                         "GetServices", NULL);
621         if (message == NULL) {
622                 ERR("Failed to get service informations");
623                 goto done;
624         }
625
626         g_variant_get(message, "(a(oa{sv}))", &service);
627         if (service == NULL) {
628                 ERR("Failed to get services iter");
629                 goto done;
630         }
631
632         while (g_variant_iter_loop(service, "(oa{sv})", &obj_path, &iter)) {
633                 if (g_strcmp0(obj_path, profile) == 0) {
634                         g_free(obj_path);
635                         found_profile = 1;
636                         break;
637                 }
638         }
639
640         if (iter == NULL || found_profile == 0) {
641                 ERR("Profile %s doesn't exist", profile);
642                         goto done;
643         }
644
645         while (g_variant_iter_loop(iter, "{sv}", &key, &next)) {
646                 const gchar *value = NULL;
647                 if (g_strcmp0(key, "IPv6") == 0) {
648                         g_variant_get(next, "a{sv}", &sub_iter);
649                         if (sub_iter == NULL)
650                                 continue;
651                         while (g_variant_iter_loop(sub_iter, "{sv}", &sub_key, &variant)) {
652                                 if (g_strcmp0(sub_key, "Address") == 0) {
653                                         value = g_variant_get_string(variant, NULL);
654                                         if (!preferred_address6)
655                                                 preferred_address6 = g_strdup(value);
656                                 }
657                         }
658                         g_variant_iter_free(sub_iter);
659                 }
660         }
661
662 done:
663         if (message)
664                 g_variant_unref(message);
665
666         if (iter)
667                 g_variant_iter_free(iter);
668
669         if (service)
670                 g_variant_iter_free(service);
671
672         return preferred_address6;
673 }
674
675 static void __netconfig_adjust_tcp_buffer_size(void)
676 {
677         int fdr = 0, fdw = 0;
678         int fdrmax = 0, fdwmax = 0;
679         const char *rbuf_size = NULL;
680         const char *wbuf_size = NULL;
681         const char *rmax_size = NULL;
682         const char *wmax_size = NULL;
683         const char *profile = netconfig_get_default_profile();
684
685         if (profile == NULL) {
686                 DBG("There is no default connection");
687
688                 rbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_READ;
689                 wbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_WRITE;
690         } else if (netconfig_is_wifi_profile(profile) == TRUE) {
691                 DBG("Default connection: Wi-Fi");
692
693                 rbuf_size = NET_TCP_BUFFERSIZE_WIFI_READ;
694                 wbuf_size = NET_TCP_BUFFERSIZE_WIFI_WRITE;
695                 rmax_size = NET_TCP_BUFFERSIZE_WIFI_RMEM_MAX;
696                 wmax_size = NET_TCP_BUFFERSIZE_WIFI_WMEM_MAX;
697         } else if (netconfig_is_cellular_profile(profile) == TRUE) {
698                 int telephony_svctype = 0, telephony_pstype = 0;
699
700                 netconfig_get_telephony_network_type(&telephony_svctype, &telephony_pstype);
701                 DBG("Default cellular %d, %d", telephony_svctype, telephony_pstype);
702
703                 switch (telephony_pstype) {
704                 case VCONFKEY_TELEPHONY_PSTYPE_HSPA:
705                         rbuf_size = NET_TCP_BUFFERSIZE_HSPA_READ;
706                         wbuf_size = NET_TCP_BUFFERSIZE_HSPA_WRITE;
707                         break;
708                 case VCONFKEY_TELEPHONY_PSTYPE_HSUPA:
709                         rbuf_size = NET_TCP_BUFFERSIZE_HSUPA_READ;
710                         wbuf_size = NET_TCP_BUFFERSIZE_HSDPA_WRITE;
711                         break;
712                 case VCONFKEY_TELEPHONY_PSTYPE_HSDPA:
713                         rbuf_size = NET_TCP_BUFFERSIZE_HSDPA_READ;
714                         wbuf_size = NET_TCP_BUFFERSIZE_HSDPA_WRITE;
715                         break;
716 #if !defined TIZEN_WEARABLE
717                 case VCONFKEY_TELEPHONY_PSTYPE_HSPAP:
718                         rbuf_size = NET_TCP_BUFFERSIZE_HSPAP_READ;
719                         wbuf_size = NET_TCP_BUFFERSIZE_HSPAP_WRITE;
720                         break;
721 #endif
722                 default:
723                         switch (telephony_svctype) {
724                         case VCONFKEY_TELEPHONY_SVCTYPE_LTE:
725                                 rbuf_size = NET_TCP_BUFFERSIZE_LTE_READ;
726                                 wbuf_size = NET_TCP_BUFFERSIZE_LTE_WRITE;
727                                 rmax_size = NET_TCP_BUFFERSIZE_LTE_RMEM_MAX;
728                                 break;
729                         case VCONFKEY_TELEPHONY_SVCTYPE_3G:
730                                 rbuf_size = NET_TCP_BUFFERSIZE_UMTS_READ;
731                                 wbuf_size = NET_TCP_BUFFERSIZE_UMTS_WRITE;
732                                 break;
733                         case VCONFKEY_TELEPHONY_SVCTYPE_2_5G_EDGE:
734                                 rbuf_size = NET_TCP_BUFFERSIZE_EDGE_READ;
735                                 wbuf_size = NET_TCP_BUFFERSIZE_EDGE_WRITE;
736                                 break;
737                         case VCONFKEY_TELEPHONY_SVCTYPE_2_5G:
738                                 rbuf_size = NET_TCP_BUFFERSIZE_GPRS_READ;
739                                 wbuf_size = NET_TCP_BUFFERSIZE_GPRS_WRITE;
740                                 break;
741                         default:
742                                 /* TODO: Check LTE support */
743                                 rbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_READ;
744                                 wbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_WRITE;
745                                 break;
746                         }
747                         break;
748                 }
749         } else {
750                 DBG("Default TCP buffer configured");
751
752                 rbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_READ;
753                 wbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_WRITE;
754         }
755
756         if (rbuf_size != NULL) {
757                 fdr = open(NET_PROC_SYS_NET_IPV4_TCP_RMEM, O_RDWR | O_CLOEXEC);
758
759                 if (fdr < 0 || write(fdr, rbuf_size, strlen(rbuf_size)) < 0)
760                         ERR("Failed to set TCP read buffer size");
761
762                 if (fdr >= 0)
763                         close(fdr);
764         }
765
766         if (wbuf_size != NULL) {
767                 fdw = open(NET_PROC_SYS_NET_IPv4_TCP_WMEM, O_RDWR | O_CLOEXEC);
768
769                 if (fdw < 0 || write(fdw, wbuf_size, strlen(wbuf_size)) < 0)
770                         ERR("Failed to set TCP write buffer size");
771
772                 if (fdw >= 0)
773                         close(fdw);
774         }
775
776         /* As default */
777         if (rmax_size == NULL)
778                 rmax_size = NET_TCP_BUFFERSIZE_WIFI_RMEM_MAX;
779         if (wmax_size == NULL)
780                 wmax_size = NET_TCP_BUFFERSIZE_WIFI_WMEM_MAX;
781
782         if (rmax_size != NULL) {
783                 fdrmax = open(NET_PROC_SYS_NET_CORE_RMEM_MAX, O_RDWR | O_CLOEXEC);
784
785                 if (fdrmax < 0 || write(fdrmax, rmax_size, strlen(rmax_size)) < 0)
786                         ERR("Failed to set TCP rmem_max size");
787
788                 if (fdrmax >= 0)
789                         close(fdrmax);
790         }
791
792         if (wmax_size != NULL) {
793                 fdwmax = open(NET_PROC_SYS_NET_CORE_WMEM_MAX, O_RDWR | O_CLOEXEC);
794
795                 if (fdwmax < 0 || write(fdwmax, wmax_size, strlen(wmax_size)) < 0)
796                         ERR("Failed to set TCP wmem_max size");
797
798                 if (fdwmax >= 0)
799                         close(fdwmax);
800         }
801 }
802
803 static void __netconfig_write_socket_buffer_size(const char *path, int size)
804 {
805         int fd = 0;
806         char buf[11] = {0, };
807
808         snprintf(buf, sizeof(buf) - 1, "%d", size);
809         fd = open(path, O_RDWR | O_CLOEXEC);
810         if (fd < 0) {
811                 ERR("Failed to open %s", path);
812                 return;
813         }
814
815         if (write(fd, buf, strlen(buf)) < 0)
816                 ERR("Failed to set %s", path);
817         close(fd);
818 }
819
820 static void __netconfig_write_socket_buffer_size_list(const char *path, int *size)
821 {
822         int fd = 0;
823         char buf[33] = {0, };
824
825         snprintf(buf, sizeof(buf) - 1, "%d %d %d", size[0], size[1], size[2]);
826         fd = open(path, O_RDWR | O_CLOEXEC);
827         if (fd < 0) {
828                 ERR("Failed to open %s", path);
829                 return;
830         }
831
832         if (write(fd, buf, strlen(buf)) < 0)
833                 ERR("Failed to set %s", path);
834         close(fd);
835 }
836
837 static void __netconfig_adjust_udp_buffer_size(void)
838 {
839         int rmem_default = netconfig_setting_get_read_buffer_size_default();
840         int rmem_max = netconfig_setting_get_read_buffer_size_max();
841         int wmem_default = netconfig_setting_get_write_buffer_size_default();
842         int wmem_max = netconfig_setting_get_write_buffer_size_max();
843         int *udp_mem = netconfig_setting_get_ipv4_udp_buffer_size();
844
845         if (rmem_default == 0 || rmem_max == 0 ||
846                         wmem_default == 0 || wmem_max == 0 || udp_mem == NULL) {
847                 ERR("Failed to get udp buffer size information. Do nothing.");
848                 return;
849         }
850
851         __netconfig_write_socket_buffer_size(NET_PROC_SYS_NET_CORE_RMEM_DEFAULT, rmem_default);
852         __netconfig_write_socket_buffer_size(NET_PROC_SYS_NET_CORE_RMEM_MAX, rmem_max);
853         __netconfig_write_socket_buffer_size(NET_PROC_SYS_NET_CORE_WMEM_DEFAULT, wmem_default);
854         __netconfig_write_socket_buffer_size(NET_PROC_SYS_NET_CORE_WMEM_MAX, wmem_max);
855         __netconfig_write_socket_buffer_size_list(NET_PROC_SYS_NET_IPV4_UDP_MEM, udp_mem);
856 }
857
858 static void __netconfig_update_default_connection_info(void)
859 {
860         int old_network_status = 0;
861         const char *profile = netconfig_get_default_profile();
862         const char *ip_addr = netconfig_get_default_ipaddress();
863         const char *ip_addr6 = netconfig_get_default_ipaddress6();
864         const char *proxy_addr = netconfig_get_default_proxy();
865         unsigned int freq = netconfig_get_default_frequency();
866         GVariantBuilder *builder;
867         GVariant *params;
868
869         if (emulator_is_emulated() == TRUE) {
870                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
871
872                 if (ip_addr != NULL) {
873                         netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, ip_addr, TRUE);
874                         g_variant_builder_add(builder, "{sv}", "IPv4Address",
875                                                                   g_variant_new_string(ip_addr));
876                 } else {
877                         netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, "", TRUE);
878                         g_variant_builder_add(builder, "{sv}", "IPv4Address",
879                                                                   g_variant_new_string(""));
880                 }
881
882                 if (ip_addr6 != NULL) {
883                         netconfig_set_vconf_str(VCONFKEY_NETWORK_IP6, ip_addr6, TRUE);
884                         g_variant_builder_add(builder, "{sv}", "IPv6Address",
885                                                                   g_variant_new_string(ip_addr6));
886                 } else {
887                         netconfig_set_vconf_str(VCONFKEY_NETWORK_IP6, "", TRUE);
888                         g_variant_builder_add(builder, "{sv}", "IPv6Address",
889                                                                   g_variant_new_string(""));
890                 }
891
892                 params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
893                 g_variant_builder_unref(builder);
894
895                 netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH,
896                                                    NETCONFIG_NETWORK_INTERFACE, "NetworkConfigChanged",
897                                                    params);
898
899                 __netconfig_adjust_tcp_buffer_size();
900                 __netconfig_adjust_udp_buffer_size();
901                 return;
902         }
903
904         if (profile == NULL)
905                 DBG("Reset network state configuration");
906         else
907                 DBG("profile[%s] ipv4(%s) ipv6(%s) proxy(%s)", profile, ip_addr,
908                         ip_addr6, proxy_addr);
909
910         netconfig_vconf_get_int(VCONFKEY_NETWORK_STATUS, &old_network_status);
911
912         if (profile == NULL && old_network_status != VCONFKEY_NETWORK_OFF) {
913                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
914
915                 netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF, TRUE);
916                 g_variant_builder_add(builder, "{sv}", "NetworkStatus",
917                                                           g_variant_new_int32(VCONFKEY_NETWORK_OFF));
918
919                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, "", TRUE);
920                 g_variant_builder_add(builder, "{sv}", "IPv4Address",
921                                                           g_variant_new_string(""));
922
923                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP6, "", TRUE);
924                 g_variant_builder_add(builder, "{sv}", "IPv6Address",
925                                                           g_variant_new_string(""));
926
927                 netconfig_set_vconf_str(VCONFKEY_NETWORK_PROXY, "", TRUE);
928                 g_variant_builder_add(builder, "{sv}", "ProxyAddress",
929                                                           g_variant_new_string(""));
930
931                 params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
932
933                 netconfig_set_vconf_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 0, TRUE);
934                 netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH,
935                                                    NETCONFIG_NETWORK_INTERFACE, "NetworkConfigChanged",
936                                                    params);
937                 netconfig_set_vconf_int("memory/private/wifi/frequency", 0, TRUE);
938
939                 g_variant_builder_unref(builder);
940
941                 DBG("Successfully clear IP and PROXY up");
942
943                 /* Try to disable CLATD if it was enabled */
944                 DBG("Disable clatd");
945                 netconfig_clatd_disable();
946         } else if (profile != NULL) {
947                 char *old_ip = vconf_get_str(VCONFKEY_NETWORK_IP);
948                 char *old_ip6 = vconf_get_str(VCONFKEY_NETWORK_IP6);
949                 char *old_proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
950
951                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
952
953                 if (netconfig_is_wifi_profile(profile) == TRUE) {
954                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_WIFI, TRUE);
955                         g_variant_builder_add(builder, "{sv}", "NetworkStatus",
956                                                           g_variant_new_int32(VCONFKEY_NETWORK_WIFI));
957                         netconfig_set_vconf_int("memory/private/wifi/frequency", freq, TRUE);
958
959                         netconfig_set_system_event(SYS_EVT_NETWORK_STATUS,
960                                 EKEY_NETWORK_STATUS, EVAL_NETWORK_WIFI);
961                 } else if (netconfig_is_cellular_profile(profile)) {
962
963                         if (!netconfig_is_cellular_internet_profile(profile)) {
964                                 DBG("connection is not a internet profile - stop to update the cellular state");
965                                 if (old_ip)
966                                         free(old_ip);
967                                 if (old_ip6)
968                                         free(old_ip6);
969                                 if (old_proxy)
970                                         free(old_proxy);
971                                 return;
972                         }
973
974                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_CELLULAR, TRUE);
975                         g_variant_builder_add(builder, "{sv}", "NetworkStatus",
976                                                           g_variant_new_int32(VCONFKEY_NETWORK_CELLULAR));
977
978                         netconfig_set_system_event(SYS_EVT_NETWORK_STATUS,
979                                 EKEY_NETWORK_STATUS, EVAL_NETWORK_CELLULAR);
980                         /* Enable clatd if IPv6 is set and no IPv4 address */
981                         if (!ip_addr && ip_addr6) {
982                                 DBG("Enable clatd");
983                                 netconfig_clatd_enable();
984                         }
985                 } else if (netconfig_is_ethernet_profile(profile) == TRUE) {
986                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_ETHERNET, TRUE);
987                         g_variant_builder_add(builder, "{sv}", "NetworkStatus",
988                                                           g_variant_new_int32(VCONFKEY_NETWORK_ETHERNET));
989                         netconfig_set_system_event(SYS_EVT_NETWORK_STATUS,
990                                 EKEY_NETWORK_STATUS, EVAL_NETWORK_ETHERNET);
991                 } else if (netconfig_is_bluetooth_profile(profile) == TRUE) {
992                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_BLUETOOTH, TRUE);
993                         g_variant_builder_add(builder, "{sv}", "NetworkStatus",
994                                                           g_variant_new_int32(VCONFKEY_NETWORK_BLUETOOTH));
995                         netconfig_set_system_event(SYS_EVT_NETWORK_STATUS,
996                                 EKEY_NETWORK_STATUS, EVAL_NETWORK_BT);
997                 } else{
998                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF, TRUE);
999                         g_variant_builder_add(builder, "{sv}", "NetworkStatus",
1000                                                           g_variant_new_int32(VCONFKEY_NETWORK_OFF));
1001                         netconfig_set_system_event(SYS_EVT_NETWORK_STATUS,
1002                                 EKEY_NETWORK_STATUS, EVAL_NETWORK_DISCONNECTED);
1003                 }
1004
1005                 if (g_strcmp0(old_ip, ip_addr) != 0 || old_ip == NULL) {
1006                         if (ip_addr != NULL) {
1007                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, ip_addr, TRUE);
1008                                 g_variant_builder_add(builder, "{sv}", "IPv4Address",
1009                                                                   g_variant_new_string(ip_addr));
1010                         } else if (old_ip != NULL && strlen(old_ip) > 0) {
1011                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, "", TRUE);
1012                                 g_variant_builder_add(builder, "{sv}", "IPv4Address",
1013                                                                   g_variant_new_string(""));
1014                         }
1015                 }
1016                 if (old_ip)
1017                         free(old_ip);
1018
1019                 if (g_strcmp0(old_ip6, ip_addr6) != 0 || old_ip6 == NULL) {
1020                         if (ip_addr6 != NULL) {
1021                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP6, ip_addr6, TRUE);
1022                                 g_variant_builder_add(builder, "{sv}", "IPv6Address",
1023                                                                   g_variant_new_string(ip_addr6));
1024                         } else if (old_ip6 != NULL && strlen(old_ip6) > 0) {
1025                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP6, "", TRUE);
1026                                 g_variant_builder_add(builder, "{sv}", "IPv6Address",
1027                                                                   g_variant_new_string(""));
1028                         }
1029                 }
1030                 if (old_ip6)
1031                         free(old_ip6);
1032
1033                 if (g_strcmp0(old_proxy, proxy_addr) != 0) {
1034                         if (proxy_addr == NULL) {
1035                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_PROXY, "", TRUE);
1036                                 g_variant_builder_add(builder, "{sv}", "ProxyAddress",
1037                                                                   g_variant_new_string(""));
1038                         } else {
1039                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_PROXY, proxy_addr, TRUE);
1040                                 g_variant_builder_add(builder, "{sv}", "ProxyAddress",
1041                                                                   g_variant_new_string(proxy_addr));
1042                         }
1043                 }
1044                 if (old_proxy)
1045                         free(old_proxy);
1046
1047                 params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
1048
1049                 netconfig_set_vconf_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 1, TRUE);
1050                 netconfig_dbus_emit_signal(NULL, NETCONFIG_NETWORK_PATH,
1051                                                    NETCONFIG_NETWORK_INTERFACE, "NetworkConfigChanged",
1052                                                    params);
1053
1054                 g_variant_builder_unref(builder);
1055
1056                 DBG("Successfully update default network configuration");
1057         }
1058
1059         __netconfig_adjust_tcp_buffer_size();
1060         __netconfig_adjust_udp_buffer_size();
1061 }
1062
1063 static gboolean __netconfig_is_tech_state_connected(void)
1064 {
1065         gboolean ret = FALSE;
1066         GVariant *message = NULL, *variant;
1067         GVariantIter *iter, *next;
1068         gchar *path;
1069         gchar *key;
1070
1071         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
1072                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
1073                         "GetTechnologies", NULL);
1074
1075         if (message == NULL) {
1076                 DBG("Fail to get technology state");
1077                 return FALSE;
1078         }
1079
1080         g_variant_get(message, "(a(oa{sv}))", &iter);
1081         while (g_variant_iter_loop(iter, "(oa{sv})", &path, &next)) {
1082                 if (path == NULL)
1083                         continue;
1084
1085                 while (g_variant_iter_loop(next, "{sv}", &key, &variant)) {
1086                         gboolean data;
1087                         if (g_strcmp0(key, "Connected") == 0) {
1088                                 data = g_variant_get_boolean(variant);
1089                                 DBG("%s [%s: %s]", path, key, data ? "True" : "False");
1090                                 if (TRUE == data) {
1091                                         ret = TRUE;
1092                                         g_free(path);
1093                                         g_free(key);
1094                                         g_variant_unref(variant);
1095                                         g_variant_iter_free(next);
1096                                         goto done;
1097                                 }
1098                         }
1099                 }
1100         }
1101
1102 done:
1103         g_variant_iter_free(iter);
1104         g_variant_unref(message);
1105
1106         return ret;
1107 }
1108
1109 static void __netconfig_network_notify_result(const char *sig_name, const char *key)
1110 {
1111         GVariantBuilder *builder;
1112         GVariant *params;
1113
1114         INFO("[Signal] %s %s", sig_name, key);
1115
1116         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1117         g_variant_builder_add(builder, "{sv}", "key", g_variant_new_string(key));
1118
1119         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
1120         g_variant_builder_unref(builder);
1121
1122         netconfig_dbus_emit_signal(NULL,
1123                                 NETCONFIG_NETWORK_PATH,
1124                                 NETCONFIG_NETWORK_INTERFACE,
1125                                 sig_name,
1126                                 params);
1127
1128         return;
1129 }
1130
1131 static char *__netconfig_get_mac_address(const char *profile)
1132 {
1133         char mac_str[MAC_ADDRESS_MAX_LEN] = { 0, };
1134         const char *orgin = NULL;
1135         int org_index, dst_index;
1136         int i;
1137
1138         org_index = strlen(CONNMAN_WIFI_SERVICE_PROFILE_PREFIX);
1139         dst_index = 0;
1140
1141         for (i = 0; i < 6; i++) {
1142                 orgin = &profile[org_index];
1143
1144                 memcpy(&mac_str[dst_index], orgin, 2);
1145                 if (i < 5)
1146                         mac_str[dst_index + 2] = ':';
1147                 else
1148                         mac_str[dst_index + 2] = '\0';
1149
1150                 org_index += 2;
1151                 dst_index += 3;
1152         }
1153
1154         return g_strdup(mac_str);
1155 }
1156
1157 int netconfig_dbus_get_vconf_value(const char *key,
1158                 const char *type, int *ret, int *int_value, char **str_value)
1159 {
1160         GVariant *result = NULL;
1161         GVariant *params = NULL;
1162
1163         params = g_variant_new("(ss)", key, type);
1164
1165         result = netconfig_invoke_dbus_method(NETCONFIG_SERVICE,
1166                         NETCONFIG_NETWORK_PATH, NETCONFIG_NETWORK_INTERFACE,
1167                         "RequestVconfValue", params);
1168
1169         if (result == NULL) {
1170                 ERR("netconfig_invoke_dbus_method failed");
1171                 return FALSE;
1172         }
1173
1174         g_variant_get(result, "(iis)", ret, int_value, str_value);
1175
1176         INFO("Vconf key: %s, type: %s, ret: %d, int_value: %d, str_value: %s",
1177                         key, type, *ret, *int_value, *str_value);
1178
1179         g_variant_unref(result);
1180
1181         return TRUE;
1182 }
1183
1184 const char *netconfig_get_default_profile(void)
1185 {
1186         return netconfig_default_connection_info.profile;
1187 }
1188
1189 const char *netconfig_get_default_ifname(void)
1190 {
1191         return netconfig_default_connection_info.ifname;
1192 }
1193
1194 const char *netconfig_get_default_ipaddress(void)
1195 {
1196         return netconfig_default_connection_info.ipaddress;
1197 }
1198
1199
1200 const char *netconfig_get_default_ipaddress6(void)
1201 {
1202         return netconfig_default_connection_info.ipaddress6;
1203 }
1204
1205 const char *netconfig_get_default_proxy(void)
1206 {
1207         return netconfig_default_connection_info.proxy;
1208 }
1209
1210 unsigned int netconfig_get_default_frequency(void)
1211 {
1212         return netconfig_default_connection_info.freq;
1213 }
1214
1215 const char *netconfig_get_default_mac_address(void)
1216 {
1217         return netconfig_default_connection_info.mac_address;
1218 }
1219
1220 const char *netconfig_wifi_get_connected_essid(const char *default_profile)
1221 {
1222         if (default_profile == NULL)
1223                 return NULL;
1224
1225         if (netconfig_is_wifi_profile(default_profile) != TRUE)
1226                 return NULL;
1227
1228         if (g_strcmp0(default_profile, netconfig_default_connection_info.profile) != 0)
1229                 return NULL;
1230
1231         return netconfig_default_connection_info.essid;
1232 }
1233
1234 gboolean netconfig_get_default_is_metered(void)
1235 {
1236         return netconfig_default_connection_info.is_metered;
1237 }
1238
1239 gboolean netconfig_get_default_is_internet(void)
1240 {
1241         return netconfig_default_connection_info.is_internet;
1242 }
1243
1244 void netconfig_set_default_ipaddress(const char *ipaddr)
1245 {
1246         netconfig_default_connection_info.ipaddress = g_strdup(ipaddr);
1247 }
1248
1249 void netconfig_set_default_ipaddress6(const char *ipaddr)
1250 {
1251         netconfig_default_connection_info.ipaddress6 = g_strdup(ipaddr);
1252 }
1253
1254 void netconfig_set_default_proxy(const char *proxy)
1255 {
1256         netconfig_default_connection_info.proxy = g_strdup(proxy);
1257 }
1258
1259 void netconfig_set_default_is_internet(gboolean state)
1260 {
1261         netconfig_default_connection_info.is_internet = state;
1262         netconfig_notify_online_state(netconfig_default_connection_info.ifname, state);
1263 }
1264
1265 void netconfig_update_default_profile(void)
1266 {
1267         if (__netconfig_get_default_connection_info())
1268                 __netconfig_update_default_connection_info();
1269 }
1270
1271 void netconfig_update_default(void)
1272 {
1273         if (__netconfig_is_tech_state_connected() == TRUE) {
1274                 netconfig_update_default_profile();
1275         } else {
1276                 __netconfig_adjust_tcp_buffer_size();
1277                 __netconfig_adjust_udp_buffer_size();
1278         }
1279 }
1280
1281 void netconfig_update_initial_container_vconf(void)
1282 {
1283         char *str_value = NULL;
1284         int int_value = 0;
1285         int idx = 0;
1286
1287         while (network_vconf_keys[idx].key) {
1288                 switch (network_vconf_keys[idx].type) {
1289                 case VCONF_TYPE_STRING:
1290                         str_value = netconfig_vconf_get_str_dbus(network_vconf_keys[idx].key);
1291                         if (str_value)
1292                                 vconf_set_str(network_vconf_keys[idx].key, str_value);
1293                         g_free(str_value);
1294                         break;
1295                 case VCONF_TYPE_INT:
1296                         if (netconfig_vconf_get_int_dbus(network_vconf_keys[idx].key, &int_value) == VCONF_OK)
1297                                 vconf_set_int(network_vconf_keys[idx].key, int_value);
1298                         break;
1299                 default:
1300                         break;
1301                 }
1302
1303                 idx++;
1304         }
1305 }
1306
1307 const char *netconfig_get_ifname(const char *profile)
1308 {
1309         const char *ifname = NULL;
1310         char *mac_addr = NULL;
1311
1312         mac_addr = __netconfig_get_mac_address(profile);
1313         ifname = wifi_state_get_interface_name(mac_addr);
1314
1315         g_free(mac_addr);
1316         return ifname;
1317 }
1318
1319 /* Check Ethernet Cable Plug-in /Plug-out Status */
1320 void netconfig_network_notify_ethernet_cable_state(const char *key)
1321 {
1322         __netconfig_network_notify_result("EthernetCableState", key);
1323 }
1324
1325 static gboolean handle_add_route(
1326                 Network *object,
1327                 GDBusMethodInvocation *context,
1328                 gchar *ip_addr,
1329                 gchar *netmask,
1330                 gchar *interface,  gchar *gateway, gint address_family)
1331 {
1332         const gchar *path = ROUTE_EXEC_PATH;
1333         gchar gw_str[64] = {0,};
1334         if (gateway != NULL && strlen(gateway) > 1)
1335                 g_snprintf(gw_str, 64, "gw %s", gateway);
1336         gchar *const args[] = { "/sbin/route", "add", "-net", ip_addr, gw_str,
1337                 "netmask", netmask, "dev", interface, NULL };
1338         gchar *const envs[] = { NULL };
1339         const gchar* buf = NULL;
1340         gchar* ch = NULL;
1341         int prefix_len = 0;
1342         int pos = 0;
1343
1344         DBG("ip_addr(%s), netmask(%s), interface(%s), gateway(%s)", ip_addr, netmask, interface, gateway);
1345
1346         switch (address_family) {
1347         case AF_INET:
1348                 if (ip_addr == NULL || netmask == NULL || interface == NULL) {
1349                         ERR("Invalid parameter");
1350                         netconfig_error_invalid_parameter(context);
1351                         return TRUE;
1352                 }
1353
1354                 if (netconfig_execute_file(path, args, envs) < 0) {
1355                         DBG("Failed to add a new route");
1356                         netconfig_error_permission_denied(context);
1357                         return TRUE;
1358                 }
1359
1360                 break;
1361         case AF_INET6:
1362                 if (ip_addr == NULL || interface == NULL || gateway == NULL) {
1363                         ERR("Invalid parameter");
1364                         netconfig_error_invalid_parameter(context);
1365                         return TRUE;
1366                 }
1367
1368                 buf = ip_addr;
1369                 ch = strchr(buf, '/');
1370                 pos = ch - buf + 1;
1371                 if (ch) {
1372                         prefix_len = atoi(ch + 1);
1373                         ip_addr[pos-1] = '\0';
1374                 } else {
1375                         prefix_len = 128;
1376                 }
1377
1378                 if (netconfig_add_route_ipv6(ip_addr, interface, gateway, prefix_len) < 0) {
1379                         DBG("Failed to add a new route");
1380                         netconfig_error_permission_denied(context);
1381                         return TRUE;
1382                 }
1383                 break;
1384         default:
1385                 DBG("Unknown Address Family");
1386                 netconfig_error_invalid_parameter(context);
1387                 return TRUE;
1388         }
1389
1390         DBG("Successfully added a new route");
1391         network_complete_add_route(object, context, TRUE);
1392         return TRUE;
1393 }
1394
1395 static gboolean handle_remove_route(
1396                 Network *object,
1397                 GDBusMethodInvocation *context,
1398                 gchar *ip_addr,
1399                 gchar *netmask,
1400                 gchar *interface, gchar *gateway, gint address_family)
1401 {
1402         const char *path = ROUTE_EXEC_PATH;
1403         gchar gw_str[64] = {0,};
1404         if (gateway != NULL && strlen(gateway) > 1)
1405                 g_snprintf(gw_str, 64, "gw %s", gateway);
1406         gchar *const args[] = { "/sbin/route", "del", "-net", ip_addr, gw_str,
1407                 "netmask", netmask, "dev", interface, NULL };
1408         char *const envs[] = { NULL };
1409         const char* buf = NULL;
1410         char* ch = NULL;
1411         int prefix_len = 0;
1412         int pos = 0;
1413
1414         DBG("ip_addr(%s), netmask(%s), interface(%s), gateway(%s)", ip_addr, netmask, interface, gateway);
1415
1416         switch (address_family) {
1417         case AF_INET:
1418                 if (ip_addr == NULL || netmask == NULL || interface == NULL) {
1419                         DBG("Invalid parameter!");
1420                         netconfig_error_invalid_parameter(context);
1421                         return TRUE;
1422                 }
1423                 if (netconfig_execute_file(path, args, envs) < 0) {
1424                         DBG("Failed to remove the route");
1425                         netconfig_error_permission_denied(context);
1426                         return TRUE;
1427                 }
1428                 break;
1429         case AF_INET6:
1430                 if (ip_addr == NULL || interface == NULL || gateway == NULL) {
1431                         DBG("Invalid parameter!");
1432                         netconfig_error_invalid_parameter(context);
1433                         return TRUE;
1434                 }
1435
1436                 buf = ip_addr;
1437                 ch = strchr(buf, '/');
1438                 pos = ch - buf + 1;
1439                 if (ch) {
1440                         prefix_len = atoi(ch + 1);
1441                         ip_addr[pos-1] = '\0';
1442                 } else {
1443                         prefix_len = 128;
1444                 }
1445
1446                 if (netconfig_del_route_ipv6(ip_addr, interface, gateway, prefix_len) < 0) {
1447                         DBG("Failed to remove the route");
1448                         netconfig_error_permission_denied(context);
1449                         return TRUE;
1450                 }
1451                 break;
1452         default:
1453                 DBG("Unknown Address Family");
1454                 netconfig_error_invalid_parameter(context);
1455                 return TRUE;
1456         }
1457
1458         DBG("Successfully removed the route");
1459         network_complete_remove_route(object, context, TRUE);
1460         return TRUE;
1461 }
1462
1463 static gboolean handle_check_get_privilege(Network *object,
1464                 GDBusMethodInvocation *context)
1465 {
1466         network_complete_check_get_privilege(object, context);
1467         return TRUE;
1468 }
1469
1470
1471 static gboolean handle_check_profile_privilege(Network *object,
1472                 GDBusMethodInvocation *context)
1473 {
1474         network_complete_check_profile_privilege(object, context);
1475         return TRUE;
1476 }
1477
1478 static gboolean handle_check_internet_privilege(Network *object,
1479                 GDBusMethodInvocation *context)
1480 {
1481         network_complete_check_internet_privilege(object, context);
1482         return TRUE;
1483 }
1484
1485 gboolean handle_ethernet_cable_state(Network *object,
1486         GDBusMethodInvocation *context)
1487 {
1488         int ret = 0;
1489         int state = 0;
1490
1491         ret = netconfig_get_ethernet_cable_state(&state);
1492         if (ret != 0) {
1493                 DBG("Failed to get ethernet cable state");
1494                 netconfig_error_fail_ethernet_cable_state(context);
1495                 return TRUE;
1496         }
1497
1498         DBG("Successfully get ethernet cable state[%d]", state);
1499         network_complete_ethernet_cable_state(object, context, state);
1500         return TRUE;
1501 }
1502
1503 gboolean handle_get_metered_info(Network *object,
1504         GDBusMethodInvocation *context)
1505 {
1506         gboolean state = 0;
1507
1508         state = netconfig_get_default_is_metered();
1509
1510         DBG("Default metered state [%s]", state ? "TRUE" : "FALSE");
1511         network_complete_get_metered_info(object, context, state);
1512         return TRUE;
1513 }
1514
1515 gboolean handle_preferred_ipv6_address(Network *object,
1516         GDBusMethodInvocation *context, gchar *profile)
1517 {
1518         char *address = NULL;
1519
1520         address = __netconfig_get_preferred_ipv6_address(profile);
1521         if (address == NULL) {
1522                 DBG("Failed to get preferred IPv6 address");
1523                 netconfig_error_fail_preferred_ipv6_address(context);
1524                 return TRUE;
1525         }
1526
1527         DBG("Successfully get preferred IPv6 address[%s]", address);
1528         network_complete_preferred_ipv6_address(object, context, address);
1529         return TRUE;
1530 }
1531
1532 gboolean handle_request_vconf_value(Network *object,
1533         GDBusMethodInvocation *context, gchar *key, gchar *type)
1534 {
1535         int ret = 0;
1536         int int_value = 0;
1537         char *str_value = "";
1538
1539         if (!g_strcmp0(type, "string"))
1540                 str_value = vconf_get_str(key);
1541         else if (!g_strcmp0(type, "int"))
1542                 ret = vconf_get_int(key, &int_value);
1543         else if (!g_strcmp0(type, "bool"))
1544                 ret = vconf_get_bool(key, &int_value);
1545
1546         DBG("Vconf key: %s, type: %s, int_value: %d, str_value: %s, ret: %d",
1547                         key, type, int_value, str_value, ret);
1548         network_complete_request_vconf_value(object, context, ret, int_value, str_value);
1549
1550         if (!g_strcmp0(type, "string"))
1551                 g_free(str_value);
1552
1553         return TRUE;
1554 }
1555
1556 gboolean handle_get_battery_dn_list(Battery *object,
1557         GDBusMethodInvocation *context)
1558 {
1559         GVariantBuilder *builder = NULL;
1560         GVariant *ret_params = NULL;
1561         gchar *params_str = NULL;
1562
1563         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
1564
1565         netconfig_battery_get_dn_list(builder);
1566
1567         ret_params = g_variant_builder_end(builder);
1568         if (ret_params) {
1569                 params_str = g_variant_print(ret_params, TRUE);
1570                 DBG("DN list [%s]", params_str);
1571                 g_free(params_str);
1572         }
1573
1574         battery_complete_get_battery_dn_list(object, context, ret_params);
1575         g_variant_builder_unref(builder);
1576         return TRUE;
1577 }
1578
1579 gboolean handle_get_battery_wifi_list(Battery *object,
1580         GDBusMethodInvocation *context)
1581 {
1582         GVariantBuilder *builder = NULL;
1583         GVariant *ret_params = NULL;
1584         gchar *params_str = NULL;
1585
1586         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
1587
1588         netconfig_battery_get_wifi_list(builder);
1589
1590         ret_params = g_variant_builder_end(builder);
1591         if (ret_params) {
1592                 params_str = g_variant_print(ret_params, TRUE);
1593                 DBG("Wi-Fi list [%s]", params_str);
1594                 g_free(params_str);
1595         }
1596
1597         battery_complete_get_battery_wifi_list(object, context, ret_params);
1598         g_variant_builder_unref(builder);
1599         return TRUE;
1600 }
1601
1602 void state_object_create_and_init(void)
1603 {
1604         DBG("Creating network state object");
1605         GDBusInterfaceSkeleton *interface_network = NULL;
1606 #if defined TIZEN_DEBUG_ENABLE
1607         GDBusInterfaceSkeleton *interface_tcpdump = NULL;
1608 #endif
1609         GDBusInterfaceSkeleton *interface_battery = NULL;
1610         GDBusConnection *connection = NULL;
1611         GDBusObjectManagerServer *server = netdbus_get_state_manager();
1612         if (server == NULL)
1613                 return;
1614
1615         connection = netdbus_get_connection();
1616         g_dbus_object_manager_server_set_connection(server, connection);
1617
1618         /*Interface netconfig.network*/
1619         netconfigstate = network_skeleton_new();
1620
1621         interface_network = G_DBUS_INTERFACE_SKELETON(netconfigstate);
1622         g_signal_connect(netconfigstate, "handle-add-route",
1623                                 G_CALLBACK(handle_add_route), NULL);
1624         g_signal_connect(netconfigstate, "handle-check-get-privilege",
1625                                 G_CALLBACK(handle_check_get_privilege), NULL);
1626         g_signal_connect(netconfigstate, "handle-check-profile-privilege",
1627                                 G_CALLBACK(handle_check_profile_privilege), NULL);
1628         g_signal_connect(netconfigstate, "handle-check-internet-privilege",
1629                                 G_CALLBACK(handle_check_internet_privilege), NULL);
1630         g_signal_connect(netconfigstate, "handle-ethernet-cable-state",
1631                                 G_CALLBACK(handle_ethernet_cable_state), NULL);
1632         g_signal_connect(netconfigstate, "handle-preferred-ipv6-address",
1633                                 G_CALLBACK(handle_preferred_ipv6_address), NULL);
1634         g_signal_connect(netconfigstate, "handle-remove-route",
1635                                 G_CALLBACK(handle_remove_route), NULL);
1636         g_signal_connect(netconfigstate, "handle-device-policy-set-wifi",
1637                                 G_CALLBACK(handle_device_policy_set_wifi), NULL);
1638         g_signal_connect(netconfigstate, "handle-device-policy-get-wifi",
1639                                 G_CALLBACK(handle_device_policy_get_wifi), NULL);
1640         g_signal_connect(netconfigstate, "handle-device-policy-set-wifi-profile",
1641                                 G_CALLBACK(handle_device_policy_set_wifi_profile), NULL);
1642         g_signal_connect(netconfigstate, "handle-device-policy-get-wifi-profile",
1643                                 G_CALLBACK(handle_device_policy_get_wifi_profile), NULL);
1644         g_signal_connect(netconfigstate, "handle-get-metered-info",
1645                                 G_CALLBACK(handle_get_metered_info), NULL);
1646         g_signal_connect(netconfigstate, "handle-request-vconf-value",
1647                                 G_CALLBACK(handle_request_vconf_value), NULL);
1648
1649         if (!g_dbus_interface_skeleton_export(interface_network, connection,
1650                         NETCONFIG_NETWORK_STATE_PATH, NULL)) {
1651                 ERR("Export with path failed");
1652         }
1653
1654 #if defined TIZEN_DEBUG_ENABLE
1655         /*Interface netconfig.tcpdump*/
1656         tcpdump_object = tcpdump_skeleton_new();
1657
1658         interface_tcpdump = G_DBUS_INTERFACE_SKELETON(tcpdump_object);
1659         g_signal_connect(tcpdump_object, "handle-start-tcpdump",
1660                                 G_CALLBACK(handle_start_tcpdump), NULL);
1661         g_signal_connect(tcpdump_object, "handle-stop-tcpdump",
1662                                 G_CALLBACK(handle_stop_tcpdump), NULL);
1663         g_signal_connect(tcpdump_object, "handle-get-tcpdump-state",
1664                                 G_CALLBACK(handle_get_tcpdump_state), NULL);
1665
1666         if (!g_dbus_interface_skeleton_export(interface_tcpdump, connection,
1667                         NETCONFIG_NETWORK_STATE_PATH, NULL)) {
1668                 ERR("Export with path failed");
1669         }
1670 #endif
1671
1672         battery_object = battery_skeleton_new();
1673
1674         interface_battery = G_DBUS_INTERFACE_SKELETON(battery_object);
1675         g_signal_connect(battery_object, "handle-get-battery-dn-list",
1676                                 G_CALLBACK(handle_get_battery_dn_list), NULL);
1677         g_signal_connect(battery_object, "handle-get-battery-wifi-list",
1678                                 G_CALLBACK(handle_get_battery_wifi_list), NULL);
1679
1680         if (!g_dbus_interface_skeleton_export(interface_battery, connection,
1681                         NETCONFIG_NETWORK_STATE_PATH, NULL)) {
1682                 ERR("Export with path failed");
1683         }
1684 }
1685
1686 void state_object_deinit(void)
1687 {
1688         g_object_unref(netconfigstate);
1689 #if defined TIZEN_DEBUG_ENABLE
1690         g_object_unref(tcpdump_object);
1691 #endif
1692 }
1693
1694 static gboolean __netconfig_check_ipv6_address(const char *address)
1695 {
1696         unsigned char buf[sizeof(struct in6_addr)];
1697         int err;
1698
1699         if (!address)
1700                 return FALSE;
1701
1702         err = inet_pton(AF_INET6, address, buf);
1703         if (err > 0)
1704                 return TRUE;
1705
1706         return FALSE;
1707 }
1708
1709 char *netconfig_get_connected_cellular_internet_ipv6only_profile(struct clatd_ctrl_hint *hint)
1710 {
1711         GVariant *message = NULL;
1712         GVariantIter *iter = NULL;
1713         GVariantIter *next = NULL;
1714         gchar *cellular_internet_profile = NULL;
1715         gchar *object_path = NULL;
1716
1717         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
1718                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
1719                         "GetServices", NULL);
1720         if (message == NULL) {
1721                 ERR("Failed to get profiles");
1722                 return NULL;
1723         }
1724
1725         g_variant_get(message, "(a(oa{sv}))", &iter);
1726         while (g_variant_iter_loop(iter, "(oa{sv})", &object_path, &next)) {
1727                 if (object_path == NULL)
1728                         continue;
1729
1730                 if (netconfig_is_cellular_profile(object_path) == FALSE)
1731                         continue;
1732
1733                 if (netconfig_is_cellular_internet_profile(object_path) == FALSE)
1734                         continue;
1735
1736                 if (__netconfig_is_connected(next) == TRUE) {
1737                         DBG("found connected profiles");
1738                         gchar *key = NULL;
1739                         gboolean has_v4 = FALSE, has_v6 = FALSE;
1740
1741                         GVariant *variant = NULL;
1742                         while (g_variant_iter_loop(next, "{sv}", &key, &variant)) {
1743                                 if (g_strcmp0(key, "IPv4") == 0) {
1744                                         GVariantIter *ipv4_iter = NULL;
1745                                         GVariant *ipv4_variant = NULL;
1746                                         gchar *ipv4_key = NULL;
1747                                         const gchar *ipv4_value = NULL;
1748                                         g_variant_get(variant, "a{sv}", &ipv4_iter);
1749                                         while (g_variant_iter_loop(ipv4_iter, "{sv}",
1750                                                 &ipv4_key, &ipv4_variant)) {
1751                                                 if (g_strcmp0(ipv4_key, "Address") == 0) {
1752                                                         ipv4_value = g_variant_get_string(ipv4_variant, NULL);
1753                                                         DBG("ipv4: %s", ipv4_value);
1754                                                         has_v4 = TRUE;
1755                                                 }
1756                                         }
1757                                         g_variant_iter_free (ipv4_iter);
1758                                 } else if (g_strcmp0(key, "IPv6") == 0) {
1759                                         GVariantIter *ipv6_iter = NULL;
1760                                         GVariant *ipv6_variant = NULL;
1761                                         gchar *ipv6_key = NULL;
1762                                         const gchar *ipv6_value = NULL;
1763                                         g_variant_get(variant, "a{sv}", &ipv6_iter);
1764                                         while (g_variant_iter_loop(ipv6_iter, "{sv}",
1765                                                 &ipv6_key, &ipv6_variant)) {
1766                                                 if (g_strcmp0(ipv6_key, "Address") == 0) {
1767                                                         ipv6_value = g_variant_get_string(ipv6_variant, NULL);
1768                                                         DBG("ipv6: %s", ipv6_value);
1769                                                         has_v6 = TRUE;
1770                                                 }
1771                                         }
1772                                         g_variant_iter_free (ipv6_iter);
1773                                 } else if (hint && g_strcmp0(key, "Nameservers") == 0) {
1774                                         int idx = 0;
1775                                         GVariantIter *ns_iter = NULL;
1776                                         gchar *nameserver = NULL;
1777                                         g_variant_get(variant, "as", &ns_iter);
1778                                         while(g_variant_iter_loop(ns_iter, "s", &nameserver)) {
1779                                                 INFO("nameserver[%d]: %s", idx, nameserver);
1780                                                 if (idx >= MAX_DNS) {
1781                                                         INFO("index exceeded %d -- skip", idx);
1782                                                         continue;
1783                                                 }
1784                                                 if (__netconfig_check_ipv6_address(nameserver) == TRUE) {
1785                                                         hint->nameserver[idx] = g_strdup(nameserver);
1786                                                         idx++;
1787                                                 } else {
1788                                                         INFO("malformed address %s -- skip", nameserver);
1789                                                 }
1790                                         }
1791                                 }
1792                         }
1793
1794                         if (!has_v4 && has_v6) {
1795                                 DBG("found 'ipv6-only/connected/internet cellular profile'");
1796                                 cellular_internet_profile = g_strdup(object_path);
1797                                 g_free(object_path);
1798                                 g_variant_iter_free(next);
1799                                 break;
1800                         }
1801                 }
1802         }
1803         g_variant_iter_free(iter);
1804         g_variant_unref(message);
1805
1806         return cellular_internet_profile;
1807 }