Add aul dependency and Use syspopup API to lauch syspopup app
[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 <stdlib.h>
25 #include <net/if.h>
26 #include <arpa/inet.h>
27 #include <netinet/in.h>
28 #include <sys/ioctl.h>
29 #include <ITapiSim.h>
30 #include <TapiUtility.h>
31
32 #include "log.h"
33 #include "util.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-monitor.h"
41 #include "netsupplicant.h"
42 #include "wifi-tel-intf.h"
43 #include "clatd-handler.h"
44
45 #include "generated-code.h"
46 /* Define TCP buffer sizes for various networks */
47 /* ReadMin, ReadInitial, ReadMax */ /* WriteMin, WriteInitial, WriteMax */
48 #define NET_TCP_BUFFERSIZE_DEFAULT_READ         "4096 87380 704512"
49 #define NET_TCP_BUFFERSIZE_DEFAULT_WRITE        "4096 16384 110208"
50 #define NET_TCP_BUFFERSIZE_WIFI_READ            "524288 1048576 2560000"
51 #define NET_TCP_BUFFERSIZE_WIFI_WRITE           "524288 1048576 2560000"
52 #define NET_TCP_BUFFERSIZE_LTE_READ             "524288 1048576 2560000"
53 #define NET_TCP_BUFFERSIZE_LTE_WRITE            "524288 1048576 2560000"
54 #define NET_TCP_BUFFERSIZE_UMTS_READ            "4094 87380 704512"
55 #define NET_TCP_BUFFERSIZE_UMTS_WRITE           "4096 16384 110208"
56 #define NET_TCP_BUFFERSIZE_HSPA_READ            "4092 87380 704512"
57 #define NET_TCP_BUFFERSIZE_HSPA_WRITE           "4096 16384 262144"
58 #define NET_TCP_BUFFERSIZE_HSDPA_READ           "4092 87380 704512"
59 #define NET_TCP_BUFFERSIZE_HSDPA_WRITE          "4096 16384 262144"
60 #define NET_TCP_BUFFERSIZE_HSUPA_READ           "4092 87380 704512"
61 #define NET_TCP_BUFFERSIZE_HSUPA_WRITE          "4096 16384 262144"
62 #define NET_TCP_BUFFERSIZE_HSPAP_READ           "4092 87380 1220608"
63 #define NET_TCP_BUFFERSIZE_HSPAP_WRITE          "4096 16384 1220608"
64 #define NET_TCP_BUFFERSIZE_EDGE_READ            "4093 26280 35040"
65 #define NET_TCP_BUFFERSIZE_EDGE_WRITE           "4096 16384 35040"
66 #define NET_TCP_BUFFERSIZE_GPRS_READ            "4096 30000 30000"
67 #define NET_TCP_BUFFERSIZE_GPRS_WRITE           "4096 8760 11680"
68
69 #define NET_TCP_BUFFERSIZE_WIFI_RMEM_MAX        "1048576"
70 #define NET_TCP_BUFFERSIZE_WIFI_WMEM_MAX        "2097152"
71 #define NET_TCP_BUFFERSIZE_LTE_RMEM_MAX         "5242880"
72
73 #define NET_TCP_BUFFERSIZE_WIFID_WMEM_MAX       "2097152"
74
75 #define NET_PROC_SYS_NET_IPV4_TCP_RMEM          "/proc/sys/net/ipv4/tcp_rmem"
76 #define NET_PROC_SYS_NET_IPv4_TCP_WMEM          "/proc/sys/net/ipv4/tcp_wmem"
77 #define NET_PROC_SYS_NET_CORE_RMEM_MAX          "/proc/sys/net/core/rmem_max"
78 #define NET_PROC_SYS_NET_CORE_WMEM_MAX          "/proc/sys/net/core/wmem_max"
79
80 #define ROUTE_EXEC_PATH                                         "/sbin/route"
81
82 static Network *netconfigstate = NULL;
83
84 struct netconfig_default_connection {
85         char *profile;
86         char *ifname;
87         char *ipaddress;
88         char *ipaddress6;
89         char *proxy;
90         char *essid;
91         unsigned int freq;
92 };
93
94 static struct netconfig_default_connection
95                                 netconfig_default_connection_info = { NULL, };
96
97 gboolean netconfig_iface_network_state_ethernet_cable_state(gint32 *state);
98
99 static gboolean __netconfig_is_connected(GVariantIter *array)
100 {
101         gboolean is_connected = FALSE;
102         GVariant *variant = NULL;
103         gchar *key = NULL;
104         const gchar *value = NULL;
105
106         while (g_variant_iter_loop(array, "{sv}", &key, &variant)) {
107                 if (g_strcmp0(key, "State") != 0) {
108                         continue;
109                 }
110
111                 if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
112                         value = g_variant_get_string(variant, NULL);
113                         if (g_strcmp0(value, "ready") == 0 || g_strcmp0(value, "online") == 0)
114                                 is_connected = TRUE;
115                 }
116
117                 g_free(key);
118                 g_variant_unref(variant);
119                 break;
120         }
121
122         return is_connected;
123 }
124
125 static char *__netconfig_get_default_profile(void)
126 {
127         GVariant *message = NULL;
128         GVariantIter *iter;
129         GVariantIter *next;
130         gchar *default_profile = NULL;
131         gchar *object_path;
132
133         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
134                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
135                         "GetServices", NULL);
136         if (message == NULL) {
137                 ERR("Failed to get profiles");
138                 return NULL;
139         }
140
141         g_variant_get(message, "(a(oa{sv}))", &iter);
142         while (g_variant_iter_loop(iter, "(oa{sv})", &object_path, &next)) {
143                 if (object_path == NULL) {
144                         continue;
145                 }
146
147                 if(netconfig_is_cellular_profile(object_path) && !netconfig_is_cellular_internet_profile(object_path)){
148                         continue;
149                 }
150
151                 if (__netconfig_is_connected(next) == TRUE) {
152                         default_profile = g_strdup(object_path);
153                         g_free(object_path);
154                         g_variant_iter_free(next);
155                         break;
156                 }
157         }
158         g_variant_iter_free(iter);
159         g_variant_unref(message);
160
161         return default_profile;
162 }
163
164 static void __netconfig_get_default_connection_info(const char *profile)
165 {
166         GVariant *message = NULL, *variant = NULL, *variant2 = NULL;
167         GVariantIter *iter = NULL, *iter1 = NULL;
168         GVariant *next = NULL;
169         gchar *key = NULL;
170         gchar *key1 = NULL;
171         gchar *key2 = NULL;
172
173         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile,
174                         CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
175         if (message == NULL) {
176                 ERR("Failed to get service properties");
177                 goto done;
178         }
179
180         g_variant_get(message, "(a{sv})", &iter);
181         while (g_variant_iter_loop(iter, "{sv}", &key, &next)) {
182                 const gchar *value = NULL;
183                 guint16 freq = 0;
184                 if (g_strcmp0(key, "Name") == 0 &&
185                                 netconfig_is_wifi_profile(profile) == TRUE) {
186                         if (g_variant_is_of_type(next, G_VARIANT_TYPE_STRING)) {
187                                 value = g_variant_get_string(next, NULL);
188
189                                 netconfig_default_connection_info.essid = g_strdup(value);
190                         }
191                 } else if (g_strcmp0(key, "Ethernet") == 0) {
192                         g_variant_get(next, "a{sv}", &iter1);
193                         while (g_variant_iter_loop(iter1, "{sv}", &key1, &variant)) {
194                                 if (g_strcmp0(key1, "Interface") == 0) {
195                                         value = g_variant_get_string(variant, NULL);
196                                         netconfig_default_connection_info.ifname = g_strdup(value);
197                                 }
198                         }
199                 } else if (g_strcmp0(key, "IPv4") == 0) {
200                         g_variant_get(next, "a{sv}", &iter1);
201                         while (g_variant_iter_loop(iter1, "{sv}", &key1, &variant)) {
202                                 if (g_strcmp0(key1, "Address") == 0) {
203                                         value = g_variant_get_string(variant, NULL);
204                                         netconfig_default_connection_info.ipaddress = g_strdup(value);
205                                 }
206                         }
207                 } else if (g_strcmp0(key, "IPv6") == 0) {
208                         g_variant_get(next, "a{sv}", &iter1);
209                         while (g_variant_iter_loop(iter1, "{sv}", &key1, &variant)) {
210                                 if (g_strcmp0(key1, "Address") == 0) {
211                                         value = g_variant_get_string(variant, NULL);
212                                         netconfig_default_connection_info.ipaddress6 = g_strdup(value);
213                                 }
214                         }
215                 } else if (g_strcmp0(key, "Proxy") == 0) {
216                         g_variant_get(next, "a{sv}", &iter1);
217                         while (g_variant_iter_loop(iter1, "{sv}", &key2, &variant2)) {
218                                 GVariantIter *iter_sub = NULL;
219
220                                 if (g_strcmp0(key2, "Servers") == 0) {
221                                         if (!g_variant_is_of_type(variant2, G_VARIANT_TYPE_STRING_ARRAY)) {
222                                                 g_free(key2);
223                                                 g_variant_unref(variant2);
224                                                 break;
225                                         }
226
227                                         g_variant_get(variant2, "as", &iter_sub);
228                                         g_variant_iter_loop(iter_sub, "s", &value);
229                                         g_variant_iter_free(iter_sub);
230                                         if (value != NULL && (strlen(value) > 0))
231                                                 netconfig_default_connection_info.proxy = g_strdup(value);
232                                 } else if (g_strcmp0(key2, "Method") == 0) {
233                                         if (g_variant_is_of_type(variant2, G_VARIANT_TYPE_STRING)) {
234                                                 g_free(key2);
235                                                 g_variant_unref(variant2);
236                                                 break;
237                                         }
238
239                                         value = g_variant_get_string(variant2, NULL);
240                                         if (g_strcmp0(value, "direct") == 0) {
241                                                 g_free(netconfig_default_connection_info.proxy);
242                                                 netconfig_default_connection_info.proxy = NULL;
243
244                                                 g_free(key2);
245                                                 g_variant_unref(variant2);
246                                                 break;
247                                         }
248                                 }
249                         }
250                 } else if (g_strcmp0(key, "Frequency") == 0) {
251                         if (g_variant_is_of_type(next, G_VARIANT_TYPE_UINT16)) {
252                                 freq = g_variant_get_uint16(next);
253                                 netconfig_default_connection_info.freq = freq;
254                         }
255                 }
256         }
257
258 done:
259         if (message)
260                 g_variant_unref(message);
261
262         if (iter)
263                 g_variant_iter_free (iter);
264
265         if (iter1)
266                 g_variant_iter_free (iter1);
267
268         return;
269 }
270
271 static void __netconfig_adjust_tcp_buffer_size(void)
272 {
273         int fdr = 0, fdw = 0;
274         int fdrmax = 0, fdwmax = 0;
275         const char *rbuf_size = NULL;
276         const char *wbuf_size = NULL;
277         const char *rmax_size = NULL;
278         const char *wmax_size = NULL;
279         const char *profile = netconfig_get_default_profile();
280
281         if (profile == NULL) {
282                 DBG("There is no default connection");
283
284                 rbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_READ;
285                 wbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_WRITE;
286         } else if (netconfig_is_wifi_profile(profile) == TRUE) {
287                 DBG("Default connection: Wi-Fi");
288
289                 rbuf_size = NET_TCP_BUFFERSIZE_WIFI_READ;
290                 wbuf_size = NET_TCP_BUFFERSIZE_WIFI_WRITE;
291                 rmax_size = NET_TCP_BUFFERSIZE_WIFI_RMEM_MAX;
292                 wmax_size = NET_TCP_BUFFERSIZE_WIFI_WMEM_MAX;
293         } else if (netconfig_is_cellular_profile(profile) == TRUE) {
294                 TapiHandle *tapi_handle = NULL;
295                 int telephony_svctype = 0, telephony_pstype = 0;
296
297                 tapi_handle = (TapiHandle *)netconfig_tel_init();
298                 if (NULL != tapi_handle) {
299                         tel_get_property_int(tapi_handle,
300                                         TAPI_PROP_NETWORK_SERVICE_TYPE,
301                                         &telephony_svctype);
302                         tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_PS_TYPE,
303                                         &telephony_pstype);
304                         netconfig_tel_deinit();
305                 }
306
307                 DBG("Default cellular %d, %d", telephony_svctype, telephony_pstype);
308
309                 switch (telephony_pstype) {
310                 case VCONFKEY_TELEPHONY_PSTYPE_HSPA:
311                         rbuf_size = NET_TCP_BUFFERSIZE_HSPA_READ;
312                         wbuf_size = NET_TCP_BUFFERSIZE_HSPA_WRITE;
313                         break;
314                 case VCONFKEY_TELEPHONY_PSTYPE_HSUPA:
315                         rbuf_size = NET_TCP_BUFFERSIZE_HSUPA_READ;
316                         wbuf_size = NET_TCP_BUFFERSIZE_HSDPA_WRITE;
317                         break;
318                 case VCONFKEY_TELEPHONY_PSTYPE_HSDPA:
319                         rbuf_size = NET_TCP_BUFFERSIZE_HSDPA_READ;
320                         wbuf_size = NET_TCP_BUFFERSIZE_HSDPA_WRITE;
321                         break;
322 #if !defined TIZEN_WEARABLE
323                 case VCONFKEY_TELEPHONY_PSTYPE_HSPAP:
324                         rbuf_size = NET_TCP_BUFFERSIZE_HSPAP_READ;
325                         wbuf_size = NET_TCP_BUFFERSIZE_HSPAP_WRITE;
326                         break;
327 #endif
328                 default:
329                         switch (telephony_svctype) {
330                         case VCONFKEY_TELEPHONY_SVCTYPE_LTE:
331                                 rbuf_size = NET_TCP_BUFFERSIZE_LTE_READ;
332                                 wbuf_size = NET_TCP_BUFFERSIZE_LTE_WRITE;
333                                 rmax_size = NET_TCP_BUFFERSIZE_LTE_RMEM_MAX;
334                                 break;
335                         case VCONFKEY_TELEPHONY_SVCTYPE_3G:
336                                 rbuf_size = NET_TCP_BUFFERSIZE_UMTS_READ;
337                                 wbuf_size = NET_TCP_BUFFERSIZE_UMTS_WRITE;
338                                 break;
339                         case VCONFKEY_TELEPHONY_SVCTYPE_2_5G_EDGE:
340                                 rbuf_size = NET_TCP_BUFFERSIZE_EDGE_READ;
341                                 wbuf_size = NET_TCP_BUFFERSIZE_EDGE_WRITE;
342                                 break;
343                         case VCONFKEY_TELEPHONY_SVCTYPE_2_5G:
344                                 rbuf_size = NET_TCP_BUFFERSIZE_GPRS_READ;
345                                 wbuf_size = NET_TCP_BUFFERSIZE_GPRS_WRITE;
346                                 break;
347                         default:
348                                 /* TODO: Check LTE support */
349                                 rbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_READ;
350                                 wbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_WRITE;
351                                 break;
352                         }
353                         break;
354                 }
355         } else {
356                 DBG("Default TCP buffer configured");
357
358                 rbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_READ;
359                 wbuf_size = NET_TCP_BUFFERSIZE_DEFAULT_WRITE;
360         }
361
362         if (rbuf_size != NULL) {
363                 fdr = open(NET_PROC_SYS_NET_IPV4_TCP_RMEM, O_RDWR | O_CLOEXEC);
364
365                 if (fdr < 0 || write(fdr, rbuf_size, strlen(rbuf_size)) < 0)
366                         ERR("Failed to set TCP read buffer size");
367
368                 if (fdr >= 0)
369                         close(fdr);
370         }
371
372         if (wbuf_size != NULL) {
373                 fdw = open(NET_PROC_SYS_NET_IPv4_TCP_WMEM, O_RDWR | O_CLOEXEC);
374
375                 if (fdw < 0 || write(fdw, wbuf_size, strlen(wbuf_size)) < 0)
376                         ERR("Failed to set TCP write buffer size");
377
378                 if (fdw >= 0)
379                         close(fdw);
380         }
381
382         /* As default */
383         if (rmax_size == NULL)
384                 rmax_size = NET_TCP_BUFFERSIZE_WIFI_RMEM_MAX;
385         if (wmax_size == NULL)
386                 wmax_size = NET_TCP_BUFFERSIZE_WIFI_WMEM_MAX;
387
388         if (rmax_size != NULL) {
389                 fdrmax = open(NET_PROC_SYS_NET_CORE_RMEM_MAX, O_RDWR | O_CLOEXEC);
390
391                 if (fdrmax < 0 || write(fdrmax, rmax_size, strlen(rmax_size)) < 0)
392                         ERR("Failed to set TCP rmem_max size");
393
394                 if (fdrmax >= 0)
395                         close(fdrmax);
396         }
397
398         if (wmax_size != NULL) {
399                 fdwmax = open(NET_PROC_SYS_NET_CORE_WMEM_MAX, O_RDWR | O_CLOEXEC);
400
401                 if (fdwmax < 0 || write(fdwmax, wmax_size, strlen(wmax_size)) < 0)
402                         ERR("Failed to set TCP wmem_max size");
403
404                 if (fdwmax >= 0)
405                         close(fdwmax);
406         }
407 }
408
409 static void __netconfig_update_default_connection_info(void)
410 {
411         int old_network_status = 0;
412         const char *profile = netconfig_get_default_profile();
413         const char *ip_addr = netconfig_get_default_ipaddress();
414         const char *ip_addr6 = netconfig_get_default_ipaddress6();
415         const char *proxy_addr = netconfig_get_default_proxy();
416         unsigned int freq = netconfig_get_default_frequency();
417
418         if (emulator_is_emulated() == TRUE)
419                 return;
420
421         if (profile == NULL)
422                 DBG("Reset network state configuration");
423         else
424                 DBG("%s: ip(%s) proxy(%s)", profile, ip_addr, proxy_addr);
425
426         vconf_get_int(VCONFKEY_NETWORK_STATUS, &old_network_status);
427
428         if (profile == NULL && old_network_status != VCONFKEY_NETWORK_OFF) {
429                 netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF);
430
431                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, "");
432                 netconfig_set_vconf_str(VCONFKEY_NETWORK_PROXY, "");
433
434                 netconfig_set_vconf_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 0);
435                 netconfig_set_vconf_int("memory/private/wifi/frequency", 0);
436
437                 DBG("Successfully clear IP and PROXY up");
438
439                 /* Disable clatd if it is in running state */
440                 netconfig_clatd_disable();
441         }
442         else if (profile != NULL) {
443                 char *old_ip = vconf_get_str(VCONFKEY_NETWORK_IP);
444                 char *old_proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
445
446                 if (netconfig_is_wifi_profile(profile) == TRUE) {
447                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_WIFI);
448                         netconfig_set_vconf_int("memory/private/wifi/frequency", freq);
449                 }
450                 else if (netconfig_is_cellular_profile(profile) ){
451
452                         if( !netconfig_is_cellular_internet_profile(profile)){
453                                 DBG("connection is not a internet profile - stop to update the cellular state");
454                                 return;
455                         }
456
457                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_CELLULAR);
458
459                         /* Enable clatd if IPv6 is set and no IPv4 address */
460                         if (!ip_addr && ip_addr6 )
461                                 netconfig_clatd_enable();
462                 }
463                 else if (netconfig_is_ethernet_profile(profile) == TRUE){
464                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_ETHERNET);
465                 }
466                 else if (netconfig_is_bluetooth_profile(profile) == TRUE){
467                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_BLUETOOTH);
468                 }
469                 else{
470                         netconfig_set_vconf_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF);
471                 }
472
473                 if (g_strcmp0(old_ip, ip_addr) != 0 || old_ip == NULL) {
474                         if (ip_addr != NULL)
475                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, ip_addr);
476                         else if (ip_addr6 != NULL)
477                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, ip_addr6);
478                         else
479                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_IP, "");
480                 }
481                 g_free(old_ip);
482
483                 if (g_strcmp0(old_proxy, proxy_addr) != 0) {
484                         if (proxy_addr == NULL)
485                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_PROXY, "");
486                         else
487                                 netconfig_set_vconf_str(VCONFKEY_NETWORK_PROXY, proxy_addr);
488                 }
489                 g_free(old_proxy);
490
491                 netconfig_set_vconf_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 1);
492
493                 DBG("Successfully update default network configuration");
494
495                 /* Disable clatd if it is in running state */
496                 if (netconfig_is_cellular_profile(profile) != TRUE)
497                         netconfig_clatd_disable();
498         }
499
500         __netconfig_adjust_tcp_buffer_size();
501 }
502
503 static gboolean __netconfig_is_tech_state_connected(void)
504 {
505         gboolean ret = FALSE;
506         GVariant *message = NULL, *variant;
507         GVariantIter *iter, *next;
508         gchar *path;
509         gchar *key;
510
511         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
512                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
513                         "GetTechnologies", NULL);
514
515         if (message == NULL) {
516                 DBG("Fail to get technology state");
517                 return FALSE;
518         }
519
520         g_variant_get(message, "(a(oa{sv}))", &iter);
521         while (g_variant_iter_loop(iter, "(oa{sv})", &path, &next)) {
522                 if (path == NULL) {
523                         continue;
524                 }
525
526                 while (g_variant_iter_loop(next, "{sv}", &key, &variant)) {
527                         gboolean data;
528                         if (g_strcmp0(key, "Connected") == 0) {
529                                 data = g_variant_get_boolean(variant);
530                                 DBG("%s [%s: %s]", path, key, data ? "True" : "False");
531                                 if (TRUE == data) {
532                                         ret = TRUE;
533                                         g_free(path);
534                                         g_free(key);
535                                         g_variant_unref(variant);
536                                         g_variant_iter_free(next);
537                                         goto done;
538                                 }
539                         }
540                 }
541         }
542
543 done:
544         g_variant_iter_free(iter);
545         g_variant_unref(message);
546
547         return ret;
548 }
549
550 static void __netconfig_update_if_service_connected(void)
551 {
552         GVariant *message = NULL, *var;
553         GVariantIter *iter, *next;
554         gchar *path;
555         gchar *key;
556
557         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
558                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
559                         "GetServices", NULL);
560
561         if (message == NULL) {
562                 ERR("Failed to get services");
563                 return;
564         }
565
566         g_variant_get(message, "(a(oa{sv}))", &iter);
567         while (g_variant_iter_loop(iter, "(oa{sv})", &path, &next)) {
568                 if (path == NULL) {
569                         continue;
570                 }
571
572                 if (g_str_has_prefix(path,
573                                                 CONNMAN_WIFI_SERVICE_PROFILE_PREFIX) == TRUE) {
574                         if (g_strrstr(path + strlen(CONNMAN_WIFI_SERVICE_PROFILE_PREFIX),
575                                                         "hidden") != NULL) {
576                                 /* skip hidden profiles */
577                                 continue;
578                         }
579                         /* Process this */
580                 } else if (g_str_has_prefix(path,
581                                                 CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX) == TRUE) {
582                         /* Process this */
583                 } else {
584                         continue;
585                 }
586
587                 while (g_variant_iter_loop(next, "{sv}", &key, &var)) {
588                         if (g_strcmp0(key, "State") == 0) {
589                                 const gchar *sdata = NULL;
590                                 sdata = g_variant_get_string(var, NULL);
591                                 DBG("%s [%s: %s]", path, key, sdata);
592
593                                 if (g_strcmp0(sdata, "online") == 0 || g_strcmp0(sdata, "ready") == 0) {
594
595                                         /* Found a connected WiFi / 3G service.
596                                          * Lets update the default profile info.
597                                          */
598                                         netconfig_update_default_profile((const gchar*)path);
599                                         g_free(key);
600                                         g_free(path);
601                                         g_variant_unref(var);
602                                         g_variant_iter_free(next);
603                                         goto done;
604                                 }
605                         }
606                 }
607         }
608 done:
609         g_variant_iter_free(iter);
610         g_variant_unref(message);
611
612         return;
613 }
614
615 static void __netconfig_network_notify_result(const char *sig_name, const char *key)
616 {
617         gboolean reply;
618         GVariant *params;
619         GVariantBuilder *builder = NULL;
620         GDBusConnection *connection = NULL;
621         GError *error = NULL;
622         const char *prop_key = "key";
623
624         INFO("[Signal] %s %s", sig_name, key);
625
626         connection = netdbus_get_connection();
627         if (connection == NULL) {
628                 ERR("Failed to get GDBus Connection");
629                 return;
630         }
631
632         builder = g_variant_builder_new(G_VARIANT_TYPE ("a{sv}"));
633         g_variant_builder_add(builder, "{sv}", prop_key, g_variant_new_string(key));
634         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
635
636         g_variant_builder_unref(builder);
637
638         reply = g_dbus_connection_emit_signal(connection,
639                         NULL,
640                         NETCONFIG_NETWORK_PATH,
641                         NETCONFIG_NETWORK_INTERFACE,
642                         sig_name,
643                         params,
644                         &error);
645
646         if (reply != TRUE) {
647                 if (error != NULL) {
648                         ERR("Failed to send signal [%s]", error->message);
649                         g_error_free(error);
650                 }
651                 return;
652         }
653
654         INFO("Sent signal (%s), key (%s)", sig_name, key);
655         return;
656 }
657
658 const char *netconfig_get_default_profile(void)
659 {
660         return netconfig_default_connection_info.profile;
661 }
662
663 const char *netconfig_get_default_ifname(void)
664 {
665         return netconfig_default_connection_info.ifname;
666 }
667
668 const char *netconfig_get_default_ipaddress(void)
669 {
670         return netconfig_default_connection_info.ipaddress;
671 }
672
673 const char *netconfig_get_default_ipaddress6(void)
674 {
675         return netconfig_default_connection_info.ipaddress6;
676 }
677
678 const char *netconfig_get_default_proxy(void)
679 {
680         return netconfig_default_connection_info.proxy;
681 }
682
683 unsigned int netconfig_get_default_frequency(void)
684 {
685         return netconfig_default_connection_info.freq;
686 }
687
688 const char *netconfig_wifi_get_connected_essid(const char *default_profile)
689 {
690         if (default_profile == NULL)
691                 return NULL;
692
693         if (netconfig_is_wifi_profile(default_profile) != TRUE)
694                 return NULL;
695
696         if (g_strcmp0(default_profile, netconfig_default_connection_info.profile) != 0)
697                 return NULL;
698
699         return netconfig_default_connection_info.essid;
700 }
701
702 static int __netconfig_reset_ipv4_socket(void)
703 {
704         int ret;
705         int fd;
706         struct ifreq ifr;
707         struct sockaddr_in sai;
708         const char *ipaddr = netconfig_get_default_ipaddress();
709         DBG("ipaddr-[%s]", ipaddr);
710
711         if (!ipaddr)
712                 return -1;
713
714         fd = socket(AF_INET, SOCK_DGRAM, 0);
715         if (fd < 0)
716                 return -1;
717
718         memset(&sai, 0, sizeof(struct sockaddr_in));
719         sai.sin_family = AF_INET;
720         sai.sin_port = 0;
721         if (!inet_aton(ipaddr, &sai.sin_addr)) {
722                 DBG("fail to inet_aton()");
723                 close(fd);
724                 return -1;
725         }
726
727         memset(&ifr, 0, sizeof(struct ifreq));
728         memcpy(&ifr.ifr_addr, &sai, sizeof(sai));
729         g_strlcpy((char *)ifr.ifr_name, WIFI_IFNAME, IFNAMSIZ);
730
731 #ifndef SIOCKILLADDR
732 #define SIOCKILLADDR    0x8939
733 #endif
734
735         ret = ioctl(fd, SIOCKILLADDR, &ifr);
736         if (ret < 0) {
737                 DBG("fail to ioctl[SIOCKILLADDR]");
738                 close(fd);
739                 return -1;
740         }
741
742         close(fd);
743         return 0;
744 }
745
746 void netconfig_update_default_profile(const char *profile)
747 {
748         static char *old_profile = NULL;
749
750         /* It's automatically updated by signal-handler
751          * DO NOT update manually
752          *
753          * It is going to update default connection information
754          */
755
756         if (netconfig_default_connection_info.profile != NULL) {
757
758                 if (netconfig_is_wifi_profile(netconfig_default_connection_info.profile))
759                         __netconfig_reset_ipv4_socket();
760
761                 g_free(old_profile);
762                 old_profile = strdup(netconfig_default_connection_info.profile);
763
764                 g_free(netconfig_default_connection_info.profile);
765                 netconfig_default_connection_info.profile = NULL;
766
767                 g_free(netconfig_default_connection_info.ifname);
768                 netconfig_default_connection_info.ifname = NULL;
769
770                 g_free(netconfig_default_connection_info.ipaddress);
771                 netconfig_default_connection_info.ipaddress = NULL;
772
773                 g_free(netconfig_default_connection_info.ipaddress6);
774                 netconfig_default_connection_info.ipaddress6 = NULL;
775
776                 g_free(netconfig_default_connection_info.proxy);
777                 netconfig_default_connection_info.proxy = NULL;
778
779                 netconfig_default_connection_info.freq = 0;
780
781                 if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) {
782                         g_free(netconfig_default_connection_info.essid);
783                         netconfig_default_connection_info.essid = NULL;
784                 }
785         }
786
787         //default profile is NULL and new connected profile is NULL
788         if( !profile ){
789                 profile = __netconfig_get_default_profile();
790
791                 if (profile && netconfig_is_cellular_profile(profile) &&
792                         !netconfig_is_cellular_internet_profile(profile)){
793                         DBG("not a default cellular profile");
794                         profile = NULL;
795                 }
796
797                 if(!profile){
798                         __netconfig_update_default_connection_info();
799                         return;
800                 }
801         }
802
803         netconfig_default_connection_info.profile = g_strdup(profile);
804         __netconfig_get_default_connection_info(profile);
805         __netconfig_update_default_connection_info();
806
807 }
808
809 void netconfig_update_default(void)
810 {
811         if (__netconfig_is_tech_state_connected() == TRUE)
812                 __netconfig_update_if_service_connected();
813         else
814                 __netconfig_adjust_tcp_buffer_size();
815 }
816
817 char *netconfig_get_ifname(const char *profile)
818 {
819         GVariant *message = NULL, *variant;
820         GVariantIter *iter, *next;
821         gchar *key;
822         gchar *key1;
823         const gchar *value = NULL;
824         gchar *ifname = NULL;
825
826         if (profile == NULL)
827                 return NULL;
828
829         message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile,
830                         CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
831         if (message == NULL) {
832                 ERR("Failed to get service properties");
833                 return NULL;
834         }
835
836         g_variant_get(message, "(a{sv})", &iter);
837         while (g_variant_iter_loop(iter, "{sv}", &key, &next)) {
838                 if (g_strcmp0(key, "Ethernet") == 0) {
839                         while (g_variant_iter_loop(next, "{sv}", &key1, &variant)) {
840                                 if (g_strcmp0(key1, "Interface") == 0) {
841                                         value = g_variant_get_string(variant, NULL);
842                                         ifname = g_strdup(value);
843                                 }
844                         }
845                 }
846         }
847
848         g_variant_unref(message);
849
850         g_variant_iter_free(iter);
851
852         return ifname;
853 }
854
855 /* Check Ethernet Cable Plug-in /Plug-out Status */
856 void netconfig_network_notify_ethernet_cable_state(const char *key)
857 {
858        __netconfig_network_notify_result("EthernetCableState", key);
859 }
860
861 static gboolean handle_add_route(
862                 Network *object,
863                 GDBusMethodInvocation *context,
864                 gchar *ip_addr,
865                 gchar *netmask,
866                 gchar *interface,  gchar *gateway, gint address_family)
867 {
868         const gchar *path = ROUTE_EXEC_PATH;
869         gchar *const args[] = { "/sbin/route", "add", "-net", ip_addr,
870                 "netmask", netmask, "dev", interface, NULL };
871         gchar *const envs[] = { NULL };
872         const gchar* buf = NULL;
873         gchar* ch = NULL;
874         int prefix_len = 0;
875         int pos = 0;
876
877         DBG("ip_addr(%s), netmask(%s), interface(%s), gateway(%s)", ip_addr, netmask, interface, gateway);
878
879         switch(address_family) {
880                 case AF_INET:
881                         if (ip_addr == NULL || netmask == NULL || interface == NULL) {
882                                 ERR("Invalid parameter");
883                                 netconfig_error_invalid_parameter(context);
884                                 return FALSE;
885                         }
886
887                         if (netconfig_execute_file(path, args, envs) < 0) {
888                                 DBG("Failed to add a new route");
889                                 netconfig_error_permission_denied(context);
890                                 return FALSE;
891                         }
892
893                         break;
894                 case AF_INET6:
895                         if (ip_addr == NULL || interface == NULL || gateway == NULL) {
896                                 ERR("Invalid parameter");
897                                 netconfig_error_invalid_parameter(context);
898                                 return FALSE;
899                         }
900
901                         buf = ip_addr;
902                         ch = strchr(buf, '/');
903                         pos = ch - buf + 1;
904                         if (ch) {
905                                 prefix_len = atoi(ch + 1);
906                                 ip_addr[pos-1] = '\0';
907                         } else {
908                                 prefix_len = 128;
909                         }
910
911                         if (netconfig_add_route_ipv6(ip_addr, interface, gateway, prefix_len) < 0) {
912                                 DBG("Failed to add a new route");
913                                 netconfig_error_permission_denied(context);
914                                 return FALSE;
915                         }
916                         break;
917                 default:
918                         DBG("Unknown Address Family");
919                         netconfig_error_invalid_parameter(context);
920                         return FALSE;
921         }
922
923         DBG("Successfully added a new route");
924         network_complete_add_route(object, context, TRUE);
925         return TRUE;
926 }
927
928 static gboolean handle_remove_route(
929                 Network *object,
930                 GDBusMethodInvocation *context,
931                 gchar *ip_addr,
932                 gchar *netmask,
933                 gchar *interface, gchar *gateway, gint address_family)
934 {
935         const char *path = ROUTE_EXEC_PATH;
936         gchar *const args[] = { "/sbin/route", "del", "-net", ip_addr,
937                 "netmask", netmask, "dev", interface, NULL };
938         char *const envs[] = { NULL };
939         const char* buf = NULL;
940         char* ch = NULL;
941         int prefix_len = 0;
942         int pos = 0;
943
944         DBG("ip_addr(%s), netmask(%s), interface(%s), gateway(%s)", ip_addr, netmask, interface, gateway);
945
946         switch(address_family) {
947                 case AF_INET:
948                         if (ip_addr == NULL || netmask == NULL || interface == NULL) {
949                                 DBG("Invalid parameter!");
950                                 netconfig_error_invalid_parameter(context);
951                                 return FALSE;
952                         }
953                         if (netconfig_execute_file(path, args, envs) < 0) {
954                                 DBG("Failed to remove the route");
955                                 netconfig_error_permission_denied(context);
956                                 return FALSE;
957                         }
958                         break;
959                 case AF_INET6:
960                         if (ip_addr == NULL || interface == NULL || gateway == NULL) {
961                                 DBG("Invalid parameter!");
962                                 netconfig_error_invalid_parameter(context);
963                                 return FALSE;
964                         }
965
966                         buf = ip_addr;
967                         ch = strchr(buf, '/');
968                         pos = ch - buf + 1;
969                         if (ch) {
970                                 prefix_len = atoi(ch + 1);
971                                 ip_addr[pos-1] = '\0';
972                         } else {
973                                 prefix_len = 128;
974                         }
975
976                         if (netconfig_del_route_ipv6(ip_addr, interface, gateway, prefix_len) < 0) {
977                                 DBG("Failed to remove the route");
978                                 netconfig_error_permission_denied(context);
979                                 return FALSE;
980                         }
981                         break;
982                 default:
983                         DBG("Unknown Address Family");
984                         netconfig_error_invalid_parameter(context);
985                         return FALSE;
986         }
987
988         DBG("Successfully removed the route");
989         network_complete_remove_route(object, context, TRUE);
990         return TRUE;
991 }
992
993 static gboolean handle_check_get_privilege(Network *object,
994                 GDBusMethodInvocation *context)
995 {
996         network_complete_check_get_privilege(object, context);
997         return TRUE;
998 }
999
1000
1001 static gboolean handle_check_profile_privilege(Network *object,
1002                 GDBusMethodInvocation *context)
1003 {
1004         network_complete_check_profile_privilege(object, context);
1005         return TRUE;
1006 }
1007
1008 gboolean handle_ethernet_cable_state(Network *object,
1009         GDBusMethodInvocation *context)
1010 {
1011         int ret = 0;
1012         int state = 0;
1013
1014         ret = netconfig_get_ethernet_cable_state(&state);
1015         if(ret != 0) {
1016                 DBG("Failed to get ethernet cable state");
1017                 netconfig_error_fail_ethernet_cable_state(context);
1018                 return FALSE;
1019         }
1020
1021         DBG("Successfully get ethernet cable state[%d]", state);
1022         network_complete_ethernet_cable_state(object, context, state);
1023         return TRUE;
1024 }
1025
1026 void state_object_create_and_init(void)
1027 {
1028         DBG("Creating network state object");
1029         GDBusInterfaceSkeleton *interface_network = NULL;
1030         GDBusConnection *connection = NULL;
1031         GDBusObjectManagerServer *server = netdbus_get_state_manager();
1032         if (server == NULL)
1033                 return;
1034
1035         connection = netdbus_get_connection();
1036         g_dbus_object_manager_server_set_connection(server, connection);
1037
1038         /*Interface netconfig.network*/
1039         netconfigstate = network_skeleton_new();
1040
1041         interface_network = G_DBUS_INTERFACE_SKELETON(netconfigstate);
1042         g_signal_connect(netconfigstate, "handle-add-route",
1043                                 G_CALLBACK(handle_add_route), NULL);
1044         g_signal_connect(netconfigstate, "handle-check-get-privilege",
1045                                 G_CALLBACK(handle_check_get_privilege), NULL);
1046         g_signal_connect(netconfigstate, "handle-check-profile-privilege",
1047                                 G_CALLBACK(handle_check_profile_privilege), NULL);
1048         g_signal_connect(netconfigstate, "handle-remove-route",
1049                                 G_CALLBACK(handle_remove_route), NULL);
1050
1051         if (!g_dbus_interface_skeleton_export(interface_network, connection,
1052                         NETCONFIG_NETWORK_STATE_PATH, NULL)) {
1053                 ERR("Export with path failed");
1054         }
1055 }
1056
1057 void state_object_deinit(void)
1058 {
1059         g_object_unref(netconfigstate);
1060 }