diff options
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--] | src/6to4.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/agent-connman.c | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | src/agent.c | 0 | ||||
-rw-r--r-- | src/backtrace.c | 138 | ||||
-rwxr-xr-x[-rw-r--r--] | src/bridge.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/clock.c | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | src/config.c | 52 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connection.c | 70 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman-dbus.conf | 13 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman-polkit.conf | 6 | ||||
-rw-r--r-- | src/connman-wait-online.service.in | 15 | ||||
-rw-r--r-- | src/connman.conf | 30 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman.h | 97 | ||||
-rwxr-xr-x[-rw-r--r--] | src/connman.service.in | 18 | ||||
-rw-r--r-- | src/connman.socket | 13 | ||||
-rw-r--r-- | src/connman_tv.service.in | 19 | ||||
-rwxr-xr-x[-rw-r--r--] | src/counter.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dbus.c | 29 | ||||
-rwxr-xr-x[-rw-r--r--] | src/detect.c | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | src/device.c | 86 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dhcp.c | 73 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dhcpv6.c | 89 | ||||
-rwxr-xr-x[-rw-r--r--] | src/dnsproxy.c | 352 | ||||
-rwxr-xr-x[-rw-r--r--] | src/eduroam.config | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/error.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/inet.c | 95 | ||||
-rwxr-xr-x[-rw-r--r--] | src/inotify.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ipaddress.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ipconfig.c | 79 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ippool.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/iptables.c | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ipv6pd.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/log.c | 233 | ||||
-rwxr-xr-x[-rw-r--r--] | src/machine.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/main.c | 75 | ||||
-rwxr-xr-x[-rw-r--r--] | src/main.conf | 7 | ||||
-rwxr-xr-x | src/main_disable_eth.conf | 110 | ||||
-rwxr-xr-x | src/main_ivi.conf | 110 | ||||
-rwxr-xr-x | src/main_tv.conf | 116 | ||||
-rwxr-xr-x[-rw-r--r--] | src/manager.c | 39 | ||||
-rwxr-xr-x[-rw-r--r--] | src/nat.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/net.connman.service.in | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | src/network.c | 478 | ||||
-rwxr-xr-x[-rw-r--r--] | src/notifier.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/ntp.c | 66 | ||||
-rwxr-xr-x[-rw-r--r--] | src/peer.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/peer_service.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/plugin.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/provider.c | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | src/proxy.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/resolver.c | 34 | ||||
-rwxr-xr-x[-rw-r--r--] | src/rfkill.c | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | src/rtnl.c | 139 | ||||
-rwxr-xr-x[-rw-r--r--] | src/service.c | 1976 | ||||
-rwxr-xr-x[-rw-r--r--] | src/session.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/netlink.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/netlink.h | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/util.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/shared/util.h | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/stats.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/storage.c | 14 | ||||
-rwxr-xr-x[-rw-r--r--] | src/task.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/technology.c | 284 | ||||
-rwxr-xr-x[-rw-r--r--] | src/tethering.c | 170 | ||||
-rwxr-xr-x[-rw-r--r--] | src/timeserver.c | 14 | ||||
-rwxr-xr-x[-rw-r--r--] | src/timezone.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/util.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/utsname.c | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | src/wispr.c | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | src/wpad.c | 2 |
70 files changed, 4948 insertions, 246 deletions
diff --git a/src/6to4.c b/src/6to4.c index 71a28827..71a28827 100644..100755 --- a/src/6to4.c +++ b/src/6to4.c diff --git a/src/agent-connman.c b/src/agent-connman.c index fca7cc1f..e4850a8f 100644..100755 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -253,6 +253,9 @@ static void request_input_append_passphrase(DBusMessageIter *iter, value = "wep"; break; case CONNMAN_SERVICE_SECURITY_PSK: +#if defined TIZEN_EXT + case CONNMAN_SERVICE_SECURITY_RSN: +#endif value = "psk"; break; case CONNMAN_SERVICE_SECURITY_8021X: @@ -386,6 +389,9 @@ static void previous_passphrase_handler(DBusMessageIter *iter, data.type = "wep"; break; case CONNMAN_SERVICE_SECURITY_PSK: +#if defined TIZEN_EXT + case CONNMAN_SERVICE_SECURITY_RSN: +#endif data.type = "psk"; break; /* diff --git a/src/agent.c b/src/agent.c index 8f7b19ba..8f7b19ba 100644..100755 --- a/src/agent.c +++ b/src/agent.c diff --git a/src/backtrace.c b/src/backtrace.c deleted file mode 100644 index 6a66c0ac..00000000 --- a/src/backtrace.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * - * Connection Manager - * - * Copyright (C) 2007-2013 Intel Corporation. All rights reserved. - * Copyright (C) 2016 Yann E. MORIN <yann.morin.1998@free.fr>. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <execinfo.h> -#include <dlfcn.h> - -#include "connman.h" - -void print_backtrace(const char* program_path, const char* program_exec, - unsigned int offset) -{ - void *frames[99]; - size_t n_ptrs; - unsigned int i; - int outfd[2], infd[2]; - int pathlen; - pid_t pid; - - if (!program_exec) - return; - - pathlen = strlen(program_path); - - n_ptrs = backtrace(frames, G_N_ELEMENTS(frames)); - if (n_ptrs < offset) - return; - - if (pipe(outfd) < 0) - return; - - if (pipe(infd) < 0) { - close(outfd[0]); - close(outfd[1]); - return; - } - - pid = fork(); - if (pid < 0) { - close(outfd[0]); - close(outfd[1]); - close(infd[0]); - close(infd[1]); - return; - } - - if (pid == 0) { - close(outfd[1]); - close(infd[0]); - - dup2(outfd[0], STDIN_FILENO); - dup2(infd[1], STDOUT_FILENO); - - execlp("addr2line", "-C", "-f", "-e", program_exec, NULL); - - exit(EXIT_FAILURE); - } - - close(outfd[0]); - close(infd[1]); - - connman_error("++++++++ backtrace ++++++++"); - - for (i = offset; i < n_ptrs - 1; i++) { - Dl_info info; - char addr[20], buf[PATH_MAX * 2]; - int len, written; - char *ptr, *pos; - - dladdr(frames[i], &info); - - len = snprintf(addr, sizeof(addr), "%p\n", frames[i]); - if (len < 0) - break; - - written = write(outfd[1], addr, len); - if (written < 0) - break; - - len = read(infd[0], buf, sizeof(buf) - 1); - if (len < 0) - break; - - buf[len] = '\0'; - - pos = strchr(buf, '\n'); - *pos++ = '\0'; - - if (strcmp(buf, "??") == 0) { - connman_error("#%-2u %p in %s", i - offset, - frames[i], info.dli_fname); - continue; - } - - ptr = strchr(pos, '\n'); - *ptr++ = '\0'; - - if (strncmp(pos, program_path, pathlen) == 0) - pos += pathlen + 1; - - connman_error("#%-2u %p in %s() at %s", i - offset, - frames[i], buf, pos); - } - - connman_error("+++++++++++++++++++++++++++"); - - kill(pid, SIGTERM); - - close(outfd[1]); - close(infd[0]); -} diff --git a/src/bridge.c b/src/bridge.c index cd2d9cee..cd2d9cee 100644..100755 --- a/src/bridge.c +++ b/src/bridge.c diff --git a/src/clock.c b/src/clock.c index 0fde2c34..f04cf175 100644..100755 --- a/src/clock.c +++ b/src/clock.c @@ -241,6 +241,11 @@ static DBusMessage *set_property(DBusConnection *conn, type = dbus_message_iter_get_arg_type(&value); if (g_str_equal(name, "Time")) { +#if defined TIZEN_EXT + /* Tizen updates time (ntp) by system service */ + + return __connman_error_permission_denied(msg); +#else struct timeval tv; dbus_uint64_t newval; @@ -261,6 +266,7 @@ static DBusMessage *set_property(DBusConnection *conn, connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH, CONNMAN_CLOCK_INTERFACE, "Time", DBUS_TYPE_UINT64, &newval); +#endif } else if (g_str_equal(name, "TimeUpdates")) { const char *strval; enum time_updates newval; diff --git a/src/config.c b/src/config.c index a8c3da89..75cd717f 100644..100755 --- a/src/config.c +++ b/src/config.c @@ -740,6 +740,9 @@ static bool load_service(GKeyFile *keyfile, const char *group, if (str) { if (security == CONNMAN_SERVICE_SECURITY_PSK || +#if defined TIZEN_EXT + security == CONNMAN_SERVICE_SECURITY_RSN || +#endif security == CONNMAN_SERVICE_SECURITY_WEP) { service->security = security; } else { @@ -755,14 +758,14 @@ static bool load_service(GKeyFile *keyfile, const char *group, service->security = CONNMAN_SERVICE_SECURITY_PSK; } else if (str) { - if (security != CONNMAN_SERVICE_SECURITY_NONE) + if (security != CONNMAN_SERVICE_SECURITY_NONE) { connman_info("Mismatch no security and " "setting %s = %s", SERVICE_KEY_SECURITY, str); - - service->security = CONNMAN_SERVICE_SECURITY_NONE; + } + service->security = CONNMAN_SERVICE_SECURITY_NONE; } else - service->security = CONNMAN_SERVICE_SECURITY_NONE; + service->security = CONNMAN_SERVICE_SECURITY_NONE; g_free(str); @@ -1154,6 +1157,10 @@ static void provision_service_wifi(struct connman_config_service *config, if (config->phase2) __connman_service_set_string(service, "Phase2", config->phase2); +#if defined TIZEN_EXT + else + __connman_service_set_string(service, "Phase2", NULL); +#endif if (config->passphrase) __connman_service_set_string(service, "Passphrase", @@ -1181,6 +1188,20 @@ static gboolean remove_virtual_config(gpointer user_data) return FALSE; } +#if defined TIZEN_EXT +static bool __check_address_type(int address_family, const char *address) +{ + unsigned char buf[sizeof(struct in6_addr)] = {0, }; + int err = 0; + + err = inet_pton(address_family, address, buf); + if(err > 0) + return TRUE; + + return FALSE; +} +#endif + static int try_provision_service(struct connman_config_service *config, struct connman_service *service) { @@ -1189,7 +1210,6 @@ static int try_provision_service(struct connman_config_service *config, enum connman_service_type type; const void *ssid; unsigned int ssid_len; - const char *str; network = __connman_service_get_network(service); if (!network) { @@ -1220,10 +1240,6 @@ static int try_provision_service(struct connman_config_service *config, if (memcmp(config->ssid, ssid, ssid_len)) return -ENOENT; - str = connman_network_get_string(network, "WiFi.Security"); - if (config->security != __connman_service_string2security(str)) - return -ENOENT; - break; case CONNMAN_SERVICE_TYPE_ETHERNET: @@ -1368,8 +1384,19 @@ static int try_provision_service(struct connman_config_service *config, __connman_service_nameserver_clear(service); for (i = 0; config->nameservers[i]; i++) { +#if defined TIZEN_EXT + if (__check_address_type(AF_INET, config->nameservers[i])) + __connman_service_nameserver_append(service, + config->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV4); + else if (__check_address_type(AF_INET6, config->nameservers[i])) + __connman_service_nameserver_append(service, + config->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV6); +#else __connman_service_nameserver_append(service, config->nameservers[i], false); +#endif } } @@ -1465,6 +1492,13 @@ int __connman_config_provision_service(struct connman_service *service) type != CONNMAN_SERVICE_TYPE_GADGET) return -ENOSYS; +#if defined TIZEN_EXT + if(type == CONNMAN_SERVICE_TYPE_WIFI && + __connman_service_get_security(service) == + CONNMAN_SERVICE_SECURITY_NONE) + return -ENOSYS; +#endif + return find_and_provision_service(service); } diff --git a/src/connection.c b/src/connection.c index 6b005e7f..64d48b7d 100644..100755 --- a/src/connection.c +++ b/src/connection.c @@ -657,8 +657,15 @@ static void connection_newgateway(int index, const char *gateway) } if (!found) { +#if defined TIZEN_EXT + if (data->ipv4_gateway != NULL){ + set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4); + connman_check_proxy_setup_and_wispr_start(data->service); + } +#else if (data->ipv4_gateway) set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4); +#endif if (data->ipv6_gateway) set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6); @@ -786,6 +793,32 @@ static void add_host_route(int family, int index, const char *gateway, } } +#if defined TIZEN_EXT +static bool __connman_service_is_not_cellular_internet_profile( + struct connman_service *cellular) +{ + char *suffix; + const char *path; + const char internet_suffix[] = "_1"; + const char prepaid_internet_suffix[] = "_3"; + + if (connman_service_get_type(cellular) != CONNMAN_SERVICE_TYPE_CELLULAR) + return FALSE; + + path = __connman_service_get_path(cellular); + + suffix = strrchr(path, '_'); + + if (g_strcmp0(suffix, internet_suffix) != 0 && + g_strcmp0(suffix, prepaid_internet_suffix) != 0) { + DBG("not internet service profile: %s", path); + return TRUE; + } + + return FALSE; +} +#endif + int __connman_connection_gateway_add(struct connman_service *service, const char *gateway, enum connman_ipconfig_type type, @@ -812,6 +845,28 @@ int __connman_connection_gateway_add(struct connman_service *service, if (!gateway && type == CONNMAN_IPCONFIG_TYPE_IPV6) gateway = "::"; +#if defined TIZEN_EXT + if (__connman_service_is_not_cellular_internet_profile(service) == TRUE) { + /* not internet service should not be default gateway */ + + DBG("no internet service %p index %d gateway %s vpn ip %s type %d", + service, index, gateway, peer, type); + + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) { + add_host_route(AF_INET, index, gateway, service_type); + __connman_service_nameserver_add_routes(service, gateway); + type4 = CONNMAN_IPCONFIG_TYPE_IPV4; + } + + if (type == CONNMAN_IPCONFIG_TYPE_IPV6) { + add_host_route(AF_INET6, index, gateway, service_type); + __connman_service_nameserver_add_routes(service, gateway); + type6 = CONNMAN_IPCONFIG_TYPE_IPV6; + } + + goto done; + } +#endif DBG("service %p index %d gateway %s vpn ip %s type %d", service, index, gateway, peer, type); @@ -856,6 +911,12 @@ int __connman_connection_gateway_add(struct connman_service *service, } if (!active_gateway) { +#if defined TIZEN_EXT + if(new_gateway->ipv4_gateway) + DBG("ConnMan, Set default gateway[%s], active[%d]", + new_gateway->ipv4_gateway->gateway, + new_gateway->ipv4_gateway->active); +#endif set_default_gateway(new_gateway, type); goto done; } @@ -971,6 +1032,9 @@ bool __connman_connection_update_gateway(void) bool updated = false; GHashTableIter iter; gpointer value, key; +#if defined TIZEN_EXT + static struct gateway_data *old_default = NULL; +#endif if (!gateway_hash) return updated; @@ -1008,6 +1072,12 @@ bool __connman_connection_update_gateway(void) } } +#if defined TIZEN_EXT + if (updated == false && old_default != default_gateway) { + updated = true; + old_default = default_gateway; + } +#endif if (updated && default_gateway) { if (default_gateway->ipv4_gateway) set_default_gateway(default_gateway, diff --git a/src/connman-dbus.conf b/src/connman-dbus.conf index 98a773ea..29106dc7 100644..100755 --- a/src/connman-dbus.conf +++ b/src/connman-dbus.conf @@ -6,6 +6,19 @@ <allow send_destination="net.connman"/> <allow send_interface="net.connman.Agent"/> <allow send_interface="net.connman.Counter"/> + <allow send_interface="net.connman.Manager"/> + <allow send_interface="net.connman.Service"/> + <allow send_interface="net.connman.Technology"/> + <allow send_interface="net.connman.Notification"/> + </policy> + <policy user="network_fw"> + <allow own="net.connman"/> + <allow send_destination="net.connman"/> + <allow send_interface="net.connman.Agent"/> + <allow send_interface="net.connman.Counter"/> + <allow send_interface="net.connman.Manager"/> + <allow send_interface="net.connman.Service"/> + <allow send_interface="net.connman.Technology"/> <allow send_interface="net.connman.Notification"/> </policy> <policy at_console="true"> diff --git a/src/connman-polkit.conf b/src/connman-polkit.conf index b13d339b..03154faf 100644..100755 --- a/src/connman-polkit.conf +++ b/src/connman-polkit.conf @@ -7,6 +7,12 @@ <allow send_interface="net.connman.Counter"/> <allow send_interface="net.connman.Notification"/> </policy> + <policy user="network_fw"> + <allow own="net.connman"/> + <allow send_interface="net.connman.Agent"/> + <allow send_interface="net.connman.Counter"/> + <allow send_interface="net.connman.Notification"/> + </policy> <policy context="default"> <allow send_destination="net.connman"/> </policy> diff --git a/src/connman-wait-online.service.in b/src/connman-wait-online.service.in deleted file mode 100644 index c2ad5cc9..00000000 --- a/src/connman-wait-online.service.in +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Wait for network to be configured by ConnMan -Requisite=connman.service -After=connman.service -Before=network-online.target -DefaultDependencies=no -Conflicts=shutdown.target - -[Service] -Type=oneshot -ExecStart=@sbindir@/connmand-wait-online -RemainAfterExit=yes - -[Install] -WantedBy=network-online.target diff --git a/src/connman.conf b/src/connman.conf new file mode 100644 index 00000000..6c6d23b6 --- /dev/null +++ b/src/connman.conf @@ -0,0 +1,30 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <policy user="root"> + <allow own="net.connman"/> + <allow send_destination="net.connman"/> + </policy> + <policy user="network_fw"> + <allow own="net.connman"/> + <allow send_destination="net.connman"/> + </policy> + <policy context="default"> + <deny own="net.connman"/> + <deny send_destination="net.connman"/> + <allow send_destination="net.connman" send_type="signal"/> + <allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="GetScanState" /> + + <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetTechnologies" privilege="http://tizen.org/privilege/network.get" /> + <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" /> + <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetServices" privilege="http://tizen.org/privilege/network.get" /> + <check send_destination="net.connman" send_interface="net.connman.Service" send_member="Connect" privilege="http://tizen.org/privilege/network.set" /> + <check send_destination="net.connman" send_interface="net.connman.Service" send_member="Disconnect" privilege="http://tizen.org/privilege/network.set" /> + <check send_destination="net.connman" send_interface="net.connman.Service" send_member="SetProperty" privilege="http://tizen.org/privilege/network.profile" /> + <check send_destination="net.connman" send_interface="net.connman.Service" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" /> + <check send_destination="net.connman" send_interface="net.connman.Service" send_member="Remove" privilege="http://tizen.org/privilege/network.profile" /> + <check send_destination="net.connman" send_interface="net.connman.Service" send_member="PropertyChanged" privilege="http://tizen.org/privilege/network.get" /> + <check send_destination="net.connman" send_interface="net.connman.Technology" send_member="Scan" privilege="http://tizen.org/privilege/network.set" /> + <check send_destination="net.connman" send_interface="net.connman.Technology" send_member="SpecificScan" privilege="http://tizen.org/privilege/network.set" /> + </policy> +</busconfig> diff --git a/src/connman.h b/src/connman.h index 21b70802..4125463b 100644..100755 --- a/src/connman.h +++ b/src/connman.h @@ -125,7 +125,6 @@ int __connman_agent_request_peer_authorization(struct connman_peer *peer, bool wps_requested, const char *dbus_sender, void *user_data); - #include <connman/log.h> int __connman_log_init(const char *program, const char *debug, @@ -135,8 +134,6 @@ void __connman_log_cleanup(gboolean backtrace); void __connman_log_enable(struct connman_debug_desc *start, struct connman_debug_desc *stop); -#include <connman/backtrace.h> - #include <connman/option.h> #include <connman/setting.h> @@ -172,6 +169,9 @@ int __connman_inet_ipv6_send_rs(int index, int timeout, __connman_inet_rs_cb_t callback, void *user_data); int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr, GSList *prefixes, int router_lifetime); +#if defined TIZEN_EXT +void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data); +#endif typedef void (*__connman_inet_ns_cb_t) (struct nd_neighbor_advert *reply, unsigned int length, @@ -371,6 +371,11 @@ const char *__connman_ipconfig_get_broadcast(struct connman_ipconfig *ipconfig); void __connman_ipconfig_set_broadcast(struct connman_ipconfig *ipconfig, const char *broadcast); const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig); void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, const char *gateway); + +#if defined TIZEN_EXT +void __connman_ipconfig_set_dhcp_lease_duration(struct connman_ipconfig *ipconfig, int dhcp_lease_duration); +#endif + unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig); void __connman_ipconfig_set_prefixlen(struct connman_ipconfig *ipconfig, unsigned char prefixlen); @@ -401,7 +406,15 @@ enum connman_ipconfig_method __connman_ipconfig_get_method( int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig); int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig); int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig); +#if defined TIZEN_EXT +/* + * Description: __connman_service_lookup_from_index cannot find correct service + * e.g. same interface or same APN of cellular profile + */ +int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service); +#else int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig); +#endif void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig); int __connman_ipconfig_set_proxy_autoconfig(struct connman_ipconfig *ipconfig, @@ -451,6 +464,11 @@ enum __connman_dhcpv6_status { CONNMAN_DHCPV6_STATUS_RESTART = 2, }; +#if defined TIZEN_EXT +void set_dhcp_discover_timeout(int timeout_value); +void set_dhcp_discover_retry_count(int retry_count); +#endif + typedef void (* dhcpv6_cb) (struct connman_network *network, enum __connman_dhcpv6_status status, gpointer data); @@ -560,6 +578,10 @@ int __connman_device_request_hidden_scan(struct connman_device *device, const char *ssid, unsigned int ssid_len, const char *identity, const char *passphrase, const char *security, void *user_data); +#if defined TIZEN_EXT +int __connman_device_request_specific_scan(enum connman_service_type type, + int scan_type, GSList *specific_scan_list); +#endif bool __connman_device_isfiltered(const char *devname); @@ -579,6 +601,11 @@ int __connman_rfkill_init(void); void __connman_rfkill_cleanup(void); int __connman_rfkill_block(enum connman_service_type type, bool block); +#if defined TIZEN_EXT +char *index2ident(int index, const char *prefix); +char *index2addr(int index); +#endif + #include <connman/network.h> int __connman_network_init(void); @@ -660,6 +687,15 @@ int __connman_service_load_modifiable(struct connman_service *service); void __connman_service_list_struct(DBusMessageIter *iter); +#if defined TIZEN_EXT +int connman_service_get_ipv6_dns_method(struct connman_service *service); +enum connman_dnsconfig_method { + CONNMAN_DNSCONFIG_METHOD_UNKNOWN = 0, + CONNMAN_DNSCONFIG_METHOD_MANUAL = 1, + CONNMAN_DNSCONFIG_METHOD_DHCP = 2, +}; +#endif + int __connman_service_compare(const struct connman_service *a, const struct connman_service *b); @@ -693,6 +729,10 @@ struct connman_network *__connman_service_get_network(struct connman_service *se enum connman_service_security __connman_service_get_security(struct connman_service *service); const char *__connman_service_get_phase2(struct connman_service *service); bool __connman_service_wps_enabled(struct connman_service *service); +#if defined TIZEN_EXT +void __connman_service_set_storage_reload(struct connman_service *service, + bool storage_reload); +#endif int __connman_service_set_favorite(struct connman_service *service, bool favorite); int __connman_service_set_favorite_delayed(struct connman_service *service, @@ -716,6 +756,10 @@ enum connman_service_state __connman_service_ipconfig_get_state( struct connman_service *service, enum connman_ipconfig_type type); +#if defined TIZEN_EXT +void connman_check_proxy_setup_and_wispr_start(struct connman_service *service); +#endif + int __connman_service_indicate_error(struct connman_service *service, enum connman_service_error error); int __connman_service_clear_error(struct connman_service *service); @@ -727,6 +771,12 @@ int __connman_service_disconnect(struct connman_service *service); int __connman_service_disconnect_all(void); void __connman_service_set_active_session(bool enable, GSList *list); void __connman_service_auto_connect(enum connman_service_connect_reason reason); + +#if defined TIZEN_EXT +bool __connman_service_get_auto_connect_mode(void); +void __connman_service_set_auto_connect_mode(bool enable); +#endif + bool __connman_service_remove(struct connman_service *service); bool __connman_service_is_provider_pending(struct connman_service *service); void __connman_service_set_provider_pending(struct connman_service *service, @@ -744,10 +794,19 @@ const char *__connman_service_type2string(enum connman_service_type type); enum connman_service_type __connman_service_string2type(const char *str); enum connman_service_security __connman_service_string2security(const char *str); +#if defined TIZEN_EXT +int __connman_service_nameserver_append(struct connman_service *service, + const char *nameserver, bool is_auto, + enum connman_ipconfig_type type); +int __connman_service_nameserver_remove(struct connman_service *service, + const char *nameserver, bool is_auto, + enum connman_ipconfig_type type); +#else int __connman_service_nameserver_append(struct connman_service *service, const char *nameserver, bool is_auto); int __connman_service_nameserver_remove(struct connman_service *service, const char *nameserver, bool is_auto); +#endif void __connman_service_nameserver_clear(struct connman_service *service); void __connman_service_nameserver_add_routes(struct connman_service *service, const char *gw); @@ -763,6 +822,17 @@ void __connman_service_timeserver_changed(struct connman_service *service, GSList *ts_list); void __connman_service_set_pac(struct connman_service *service, const char *pac); +#if defined TIZEN_EXT +/* + * Returns profile count if there is any connected profiles + * that use same interface + */ +int __connman_service_get_connected_count_of_iface(struct connman_service *service); +void __connman_service_set_proxy(struct connman_service *service, + const char *proxies); +int check_passphrase_ext(struct connman_network *network, + const char *passphrase); +#endif bool __connman_service_is_hidden(struct connman_service *service); bool __connman_service_is_split_routing(struct connman_service *service); bool __connman_service_index_is_split_routing(int index); @@ -806,6 +876,9 @@ void __connman_service_notify(struct connman_service *service, unsigned int rx_error, unsigned int tx_error, unsigned int rx_dropped, unsigned int tx_dropped); +bool __connman_service_is_user_allowed(enum connman_service_type type, + uid_t uid); + int __connman_service_counter_register(const char *counter); void __connman_service_counter_unregister(const char *counter); @@ -875,12 +948,21 @@ int __connman_rtnl_init(void); void __connman_rtnl_start(void); void __connman_rtnl_cleanup(void); +#if defined TIZEN_EXT +void __connman_wifi_vsie_list_struct(DBusMessageIter *iter); +#endif + enum connman_device_type __connman_rtnl_get_device_type(int index); unsigned int __connman_rtnl_update_interval_add(unsigned int interval); unsigned int __connman_rtnl_update_interval_remove(unsigned int interval); int __connman_rtnl_request_update(void); int __connman_rtnl_send(const void *buf, size_t len); +#if defined TIZEN_EXT +void rtnl_nameserver_add_all(struct connman_service *service, + enum connman_ipconfig_type type); +#endif + bool __connman_session_policy_autoconnect(enum connman_service_connect_reason reason); int __connman_session_create(DBusMessage *msg); @@ -1062,3 +1144,12 @@ void __connman_machine_cleanup(void); int __connman_util_get_random(uint64_t *val); int __connman_util_init(void); void __connman_util_cleanup(void); + +#ifdef TIZEN_EXT +__attribute__ ((unused)) static int __tizentvextension = -1; +#define TIZEN_TV_EXT (__builtin_expect(__tizentvextension != -1, 1) ? \ + __tizentvextension : \ + (__tizentvextension = connman_setting_get_bool("TizenTVExtension"))) +#else /* TIZEN_EXT */ +#define TIZEN_TV_EXT (0) /* Always False */ +#endif /* TIZEN_EXT */ diff --git a/src/connman.service.in b/src/connman.service.in index 9f5c10fe..9eb75b24 100644..100755 --- a/src/connman.service.in +++ b/src/connman.service.in @@ -1,21 +1,19 @@ [Unit] Description=Connection service -DefaultDependencies=false -Conflicts=shutdown.target -RequiresMountsFor=@localstatedir@/lib/connman -After=dbus.service network-pre.target systemd-sysusers.service -Before=network.target multi-user.target shutdown.target -Wants=network.target +After=net-config.service +DefaultDependencies=no [Service] Type=dbus +User=network_fw +Group=network_fw BusName=net.connman Restart=on-failure -ExecStart=@sbindir@/connmand -n +SmackProcessLabel=System +ExecStart=@bindir@/connmand -n --noplugin vpn StandardOutput=null -CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SYS_TIME CAP_SYS_MODULE -ProtectHome=true -ProtectSystem=full +Capabilities=cap_setgid,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i +SecureBits=keep-caps [Install] WantedBy=multi-user.target diff --git a/src/connman.socket b/src/connman.socket new file mode 100644 index 00000000..5d0a280f --- /dev/null +++ b/src/connman.socket @@ -0,0 +1,13 @@ +[Unit] +Description=DNS Proxy Socket +Before=connman.service + +[Socket] +ListenStream=127.0.0.1:53 +ListenDatagram=0.0.0.0:53 +FreeBind=true +SmackLabelIPIn=* +SmackLabelIPOut=@ + +[Install] +WantedBy=sockets.target
\ No newline at end of file diff --git a/src/connman_tv.service.in b/src/connman_tv.service.in new file mode 100644 index 00000000..9eb75b24 --- /dev/null +++ b/src/connman_tv.service.in @@ -0,0 +1,19 @@ +[Unit] +Description=Connection service +After=net-config.service +DefaultDependencies=no + +[Service] +Type=dbus +User=network_fw +Group=network_fw +BusName=net.connman +Restart=on-failure +SmackProcessLabel=System +ExecStart=@bindir@/connmand -n --noplugin vpn +StandardOutput=null +Capabilities=cap_setgid,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i +SecureBits=keep-caps + +[Install] +WantedBy=multi-user.target diff --git a/src/counter.c b/src/counter.c index 8ea6205b..8ea6205b 100644..100755 --- a/src/counter.c +++ b/src/counter.c diff --git a/src/dbus.c b/src/dbus.c index d80a46ce..71728300 100644..100755 --- a/src/dbus.c +++ b/src/dbus.c @@ -524,6 +524,35 @@ err: return err; } +int connman_dbus_get_connection_unix_user_sync(DBusConnection *connection, + const char *bus_name, + unsigned int *user_id) +{ +#if defined TIZEN_EXT + *user_id = 0; +#else + unsigned long uid; + DBusError err; + + dbus_error_init(&err); + + uid = dbus_bus_get_unix_user(connection, bus_name, &err); + + if (uid == (unsigned long)-1) { + DBG("Can not get unix user ID!"); + if (dbus_error_is_set(&err)) { + DBG("%s", err.message); + dbus_error_free(&err); + } + return -1; + } + + *user_id = (unsigned int)uid; +#endif + + return 0; +} + static unsigned char *parse_context(DBusMessage *msg) { DBusMessageIter iter, array; diff --git a/src/detect.c b/src/detect.c index 6c039206..7f20870c 100644..100755 --- a/src/detect.c +++ b/src/detect.c @@ -67,8 +67,15 @@ static void detect_newlink(unsigned short type, int index, } device = find_device(index); +#if defined TIZEN_EXT + if (device) { + connman_inet_update_device_ident(device); + return; + } +#else if (device) return; +#endif device = connman_device_create_from_index(index); if (!device) diff --git a/src/device.c b/src/device.c index a563f464..3ec8f715 100644..100755 --- a/src/device.c +++ b/src/device.c @@ -1042,6 +1042,73 @@ void connman_device_regdom_notify(struct connman_device *device, __connman_technology_notify_regdom_by_device(device, result, alpha2); } +#if defined TIZEN_EXT +static int device_specific_scan(enum connman_service_type type, + struct connman_device *device, + int scan_type, GSList *specific_scan_list) +{ + if (!device->driver || !device->driver->specific_scan) + return -EOPNOTSUPP; + + if (!device->powered) + return -ENOLINK; + + return device->driver->specific_scan(type, device, scan_type, + specific_scan_list, NULL); +} + +int __connman_device_request_specific_scan(enum connman_service_type type, + int scan_type, GSList *specific_scan_list) +{ + bool success = false; + int last_err = -ENOSYS; + GSList *list; + int err; + + switch (type) { + case CONNMAN_SERVICE_TYPE_UNKNOWN: + case CONNMAN_SERVICE_TYPE_SYSTEM: + case CONNMAN_SERVICE_TYPE_ETHERNET: + case CONNMAN_SERVICE_TYPE_BLUETOOTH: + case CONNMAN_SERVICE_TYPE_CELLULAR: + case CONNMAN_SERVICE_TYPE_GPS: + case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: + return -EOPNOTSUPP; + case CONNMAN_SERVICE_TYPE_WIFI: + case CONNMAN_SERVICE_TYPE_P2P: + break; + } + + for (list = device_list; list; list = list->next) { + struct connman_device *device = list->data; + enum connman_service_type service_type = + __connman_device_get_service_type(device); + + if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) { + if (type == CONNMAN_SERVICE_TYPE_P2P) { + if (service_type != CONNMAN_SERVICE_TYPE_WIFI) + continue; + } else if (service_type != type) + continue; + } + + err = device_specific_scan(type, device, scan_type, specific_scan_list); + if (err == 0 || err == -EINPROGRESS) { + success = true; + } else { + last_err = err; + DBG("device %p err %d", device, err); + } + } + + if (success) + return 0; + + return last_err; +} +#endif + int __connman_device_request_scan(enum connman_service_type type) { bool success = false; @@ -1078,7 +1145,15 @@ int __connman_device_request_scan(enum connman_service_type type) } err = device_scan(type, device); +#if defined TIZEN_EXT + /* When Scan is already in progress then return Error so that + * wifi-manager can block the scan-done signal to be sent to + * application and start requested scan after scan already in progress + * is completed then notify to application about the scan event */ + if (err == 0 || err == -EINPROGRESS) { +#else if (err == 0 || err == -EALREADY || err == -EINPROGRESS) { +#endif success = true; } else { last_err = err; @@ -1108,7 +1183,11 @@ int __connman_device_request_hidden_scan(struct connman_device *device, passphrase, security, user_data); } +#if defined TIZEN_EXT +char *index2ident(int index, const char *prefix) +#else static char *index2ident(int index, const char *prefix) +#endif { struct ifreq ifr; struct ether_addr eth; @@ -1154,7 +1233,11 @@ static char *index2ident(int index, const char *prefix) return str; } +#if defined TIZEN_EXT +char *index2addr(int index) +#else static char *index2addr(int index) +#endif { struct ifreq ifr; struct ether_addr eth; @@ -1394,6 +1477,9 @@ static void cleanup_devices(void) DBG("cleaning up %s index %d", interfaces[i], index); +#if defined TIZEN_EXT + if (strcmp(interfaces[i], "wlan0") != 0) +#endif connman_inet_ifdown(index); /* diff --git a/src/dhcp.c b/src/dhcp.c index 1af1eb52..c428c1d4 100644..100755 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -67,6 +67,9 @@ static GHashTable *ipconfig_table; static void dhcp_free(struct connman_dhcp *dhcp) { +#if defined TIZEN_EXT + DBG("dhcp_free [%p]", dhcp); +#endif g_strfreev(dhcp->nameservers); g_strfreev(dhcp->timeservers); g_free(dhcp->pac); @@ -76,10 +79,16 @@ static void dhcp_free(struct connman_dhcp *dhcp) dhcp->pac = NULL; g_free(dhcp); +#if defined TIZEN_EXT + dhcp = NULL; +#endif } static void ipv4ll_stop_client(struct connman_dhcp *dhcp) { +#if defined TIZEN_EXT + DBG("dhcp [%p] ipv4ll_client [%p]", dhcp, dhcp->ipv4ll_client); +#endif if (!dhcp->ipv4ll_client) return; @@ -119,8 +128,14 @@ static bool apply_dhcp_invalidate_on_network(struct connman_dhcp *dhcp) } if (dhcp->nameservers) { for (i = 0; dhcp->nameservers[i]; i++) { +#if defined TIZEN_EXT __connman_service_nameserver_remove(service, - dhcp->nameservers[i], false); + dhcp->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV4); +#else + __connman_service_nameserver_remove(service, + dhcp->nameservers[i], false); +#endif } g_strfreev(dhcp->nameservers); dhcp->nameservers = NULL; @@ -193,6 +208,10 @@ static int ipv4ll_start_client(struct connman_dhcp *dhcp) int index; int err; +#if defined TIZEN_EXT + DBG("dhcp %p", dhcp); +#endif + if (dhcp->ipv4ll_client) return -EALREADY; @@ -202,12 +221,16 @@ static int ipv4ll_start_client(struct connman_dhcp *dhcp) if (error != G_DHCP_CLIENT_ERROR_NONE) return -EINVAL; +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCP_DEBUG")) { +#endif dhcp->ipv4ll_debug_prefix = g_strdup_printf("IPv4LL index %d", index); g_dhcp_client_set_debug(ipv4ll_client, dhcp_debug, dhcp->ipv4ll_debug_prefix); +#if !defined TIZEN_EXT } +#endif g_dhcp_client_set_id(ipv4ll_client); @@ -242,7 +265,10 @@ static gboolean dhcp_retry_cb(gpointer user_data) struct connman_dhcp *dhcp = user_data; dhcp->timeout = 0; - +#if defined TIZEN_EXT + DBG("dhcp %p", dhcp); + DBG("dhcp->timeout %d", dhcp->timeout); +#endif g_dhcp_client_start(dhcp->dhcp_client, __connman_ipconfig_get_dhcp_address(dhcp->ipconfig)); @@ -382,18 +408,32 @@ static bool apply_lease_available_on_network(GDHCPClient *dhcp_client, if (!compare_string_arrays(nameservers, dhcp->nameservers)) { if (dhcp->nameservers) { +#if defined TIZEN_EXT + for (i = 0; dhcp->nameservers[i] != NULL; i++) { + __connman_service_nameserver_remove(service, + dhcp->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV4); + } +#else for (i = 0; dhcp->nameservers[i]; i++) { __connman_service_nameserver_remove(service, dhcp->nameservers[i], false); } +#endif g_strfreev(dhcp->nameservers); } dhcp->nameservers = nameservers; for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) { +#if defined TIZEN_EXT + __connman_service_nameserver_append(service, + dhcp->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV4); +#else __connman_service_nameserver_append(service, dhcp->nameservers[i], false); +#endif } } else { g_strfreev(nameservers); @@ -458,6 +498,10 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data) __connman_ipconfig_set_dhcp_address(dhcp->ipconfig, address); DBG("last address %s", address); +#if defined TIZEN_EXT + int dhcp_lease_duration = g_dhcp_client_get_dhcp_lease_duration(dhcp_client); +#endif + option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET); if (option) netmask = g_strdup(option->data); @@ -492,6 +536,10 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data) __connman_ipconfig_set_method(dhcp->ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP); +#if defined TIZEN_EXT + __connman_ipconfig_set_dhcp_lease_duration(dhcp->ipconfig, dhcp_lease_duration); +#endif + /* * Notify IPv4.Configuration's method moved back to DHCP. * @@ -580,14 +628,25 @@ static int dhcp_initialize(struct connman_dhcp *dhcp) dhcp_client = g_dhcp_client_new(G_DHCP_IPV4, index, &error); if (error != G_DHCP_CLIENT_ERROR_NONE) +#if defined TIZEN_EXT + { + DBG("failed g_dhcp_client_new(%d), index(%d)", error, index); +#endif return -EINVAL; +#if defined TIZEN_EXT + } +#endif +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCP_DEBUG")) { +#endif dhcp->dhcp_debug_prefix = g_strdup_printf("DHCP index %d", index); g_dhcp_client_set_debug(dhcp_client, dhcp_debug, dhcp->dhcp_debug_prefix); +#if !defined TIZEN_EXT } +#endif g_dhcp_client_set_id(dhcp_client); @@ -675,7 +734,9 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, struct connman_network *network, dhcp_cb callback, gpointer user_data) { +#if !defined TIZEN_EXT const char *last_addr = NULL; +#endif struct connman_dhcp *dhcp; int err; @@ -689,7 +750,9 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, return -EINVAL; } +#if !defined TIZEN_EXT last_addr = __connman_ipconfig_get_dhcp_address(ipconfig); +#endif dhcp = g_hash_table_lookup(ipconfig_table, ipconfig); if (!dhcp) { @@ -721,7 +784,13 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, dhcp->callback = callback; dhcp->user_data = user_data; +#if defined TIZEN_EXT + DBG("Start DHCP with DHCPDISCOVER request"); + + return g_dhcp_client_start(dhcp->dhcp_client, NULL); +#else return g_dhcp_client_start(dhcp->dhcp_client, last_addr); +#endif } void __connman_dhcp_stop(struct connman_ipconfig *ipconfig) diff --git a/src/dhcpv6.c b/src/dhcpv6.c index cbf7974f..c624cb00 100644..100755 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -197,10 +197,23 @@ static int set_duid(struct connman_service *service, int duid_len; ident = __connman_service_get_ident(service); +#if defined TIZEN_EXT + if(ident != NULL) + DBG("ident : %s", ident); +#endif keyfile = connman_storage_load_service(ident); + +#if defined TIZEN_EXT + if (!keyfile) { + keyfile = g_key_file_new(); + if (!keyfile) + return -EIO; + } +#else if (!keyfile) return -EINVAL; +#endif hex_duid = g_key_file_get_string(keyfile, ident, "IPv6.DHCP.DUID", NULL); @@ -322,9 +335,19 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data) if (!compare_string_arrays(nameservers, dhcp->nameservers)) { if (dhcp->nameservers) { for (i = 0; dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { __connman_service_nameserver_remove(service, - dhcp->nameservers[i], - false); + dhcp->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV6); +#else + __connman_service_nameserver_remove(service, + dhcp->nameservers[i], + false); +#endif +#if defined TIZEN_EXT + } +#endif g_strfreev(dhcp->nameservers); } @@ -332,9 +355,19 @@ static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data) for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { + __connman_service_nameserver_append(service, + dhcp->nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_IPV6); +#else __connman_service_nameserver_append(service, dhcp->nameservers[i], false); +#endif +#if defined TIZEN_EXT + } +#endif } else g_strfreev(nameservers); @@ -392,7 +425,9 @@ static int dhcpv6_info_request(struct connman_dhcpv6 *dhcp) return -EINVAL; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCPV6_DEBUG")) +#endif g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6"); service = connman_service_lookup_from_network(dhcp->network); @@ -517,9 +552,19 @@ static int set_other_addresses(GDHCPClient *dhcp_client, if (!compare_string_arrays(nameservers, dhcp->nameservers)) { if (dhcp->nameservers) { for (i = 0; dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { + __connman_service_nameserver_remove(service, + dhcp->nameservers[i], + false, CONNMAN_IPCONFIG_TYPE_IPV6); +#else __connman_service_nameserver_remove(service, dhcp->nameservers[i], false); +#endif +#if defined TIZEN_EXT + } +#endif g_strfreev(dhcp->nameservers); } @@ -527,9 +572,19 @@ static int set_other_addresses(GDHCPClient *dhcp_client, for (i = 0; dhcp->nameservers && dhcp->nameservers[i]; i++) +#if defined TIZEN_EXT + { __connman_service_nameserver_append(service, - dhcp->nameservers[i], - false); + dhcp->nameservers[i], + false, CONNMAN_IPCONFIG_TYPE_IPV6); +#else + __connman_service_nameserver_append(service, + dhcp->nameservers[i], + false); +#endif +#if defined TIZEN_EXT + } +#endif } else g_strfreev(nameservers); @@ -638,6 +693,9 @@ static void set_address(int ifindex, struct connman_ipconfig *ipconfig, /* Is this prefix part of the subnet we are suppose to use? */ prefix_len = check_ipv6_addr_prefix(prefixes, address); +#if defined TIZEN_EXT + char *gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig)); +#endif __connman_ipconfig_address_remove(ipconfig); __connman_ipconfig_set_local(ipconfig, address); __connman_ipconfig_set_prefixlen(ipconfig, prefix_len); @@ -645,6 +703,11 @@ static void set_address(int ifindex, struct connman_ipconfig *ipconfig, DBG("new address %s/%d", address, prefix_len); __connman_ipconfig_set_dhcp_address(ipconfig, address); +#if defined TIZEN_EXT + DBG("Set gateway %s", gateway); + __connman_ipconfig_set_gateway(ipconfig, gateway); + g_free(gateway); +#endif __connman_service_save( __connman_service_lookup_from_index(ifindex)); } @@ -1713,7 +1776,9 @@ static gboolean timeout_solicitation(gpointer user_data) static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp) { struct connman_service *service; +#if !defined TIZEN_EXT struct connman_ipconfig *ipconfig_ipv6; +#endif GDHCPClient *dhcp_client; GDHCPClientError error; int index, ret; @@ -1728,7 +1793,9 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp) return -EINVAL; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCPV6_DEBUG")) +#endif g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6"); service = connman_service_lookup_from_network(dhcp->network); @@ -1754,8 +1821,20 @@ static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp) g_dhcpv6_client_set_oro(dhcp_client, 3, G_DHCPV6_DNS_SERVERS, G_DHCPV6_DOMAIN_LIST, G_DHCPV6_SNTP_SERVERS); +#if defined TIZEN_EXT + /** + When privacy extension is enabled then connman requests + OPTION_IA_TA (4) from DHCPv6 server. This option is used to request + temporary IPv6 address from DHCPv6 server but we found that DHCPv6 + server never provided temporary IPv6 address and connman resend dhcpv6 + requests. So always set OPTION_IA_NA in dhcpv6 request to get IPv6 + address from DHCPv6 server. + */ + dhcp->use_ta = FALSE; +#else ipconfig_ipv6 = __connman_service_get_ip6config(service); dhcp->use_ta = __connman_ipconfig_ipv6_privacy_enabled(ipconfig_ipv6); +#endif g_dhcpv6_client_set_ia(dhcp_client, index, dhcp->use_ta ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA, @@ -2045,7 +2124,9 @@ static GDHCPClient *create_pd_client(struct connman_dhcpv6 *dhcp, int *err) return NULL; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_DHCPV6_DEBUG")) +#endif g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6:PD"); service = connman_service_lookup_from_network(dhcp->network); diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 40b4f159..3fa7bf46 100644..100755 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -41,6 +41,11 @@ #include "connman.h" +#if defined TIZEN_EXT +#include <sys/smack.h> +#include <systemd/sd-daemon.h> +#endif + #define debug(fmt...) do { } while (0) #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -194,7 +199,11 @@ struct domain_rr { * By default the TTL (time-to-live) of the DNS response is used * when setting the cache entry life time. The value is in seconds. */ +#if defined TIZEN_EXT +#define MAX_CACHE_TTL (60 * 60) +#else #define MAX_CACHE_TTL (60 * 30) +#endif /* * Also limit the other end, cache at least for 30 seconds. */ @@ -213,12 +222,22 @@ static int cache_size; static GHashTable *cache; static int cache_refcount; static GSList *server_list = NULL; +#if defined TIZEN_EXT +static GSList *server_list_sec = NULL; +#endif static GSList *request_list = NULL; static GHashTable *listener_table = NULL; static time_t next_refresh; static GHashTable *partial_tcp_req_table; static guint cache_timer = 0; +#if defined TIZEN_EXT +static void destroy_server_sec(struct server_data *server); +static struct server_data *create_server_sec(int index, + const char *domain, const char *server, + int protocol); +#endif + static guint16 get_id(void) { uint64_t rand; @@ -1642,6 +1661,31 @@ static int ns_resolv(struct server_data *server, struct request_data *req, } } +#if defined TIZEN_EXT + if (server->protocol == IPPROTO_UDP) { + GList *domains; + struct server_data *new_server = NULL; + + new_server = create_server_sec(server->index, NULL, + server->server, IPPROTO_UDP); + + if (new_server != NULL) { + for (domains = server->domains; domains; + domains = domains->next) { + char *dom = domains->data; + + DBG("Adding domain %s to %s", + dom, new_server->server); + + new_server->domains = g_list_append( + new_server->domains, + g_strdup(dom)); + } + + server = new_server; + } + } +#endif sk = g_io_channel_unix_get_fd(server->channel); err = sendto(sk, request, req->request_len, MSG_NOSIGNAL, @@ -2240,6 +2284,19 @@ static gboolean udp_server_event(GIOChannel *channel, GIOCondition condition, if (err < 0) return TRUE; +#if defined TIZEN_EXT + GSList *list; + + for (list = server_list_sec; list; list = list->next) { + struct server_data *new_data = list->data; + + if (new_data == data) { + destroy_server_sec(data); + return TRUE; + } + } +#endif + return TRUE; } @@ -2550,6 +2607,177 @@ static void enable_fallback(bool enable) } } +#if defined TIZEN_EXT + +static void destroy_server_sec(struct server_data *server) +{ + GList *list; + int fd; + + if (server->channel) + fd = g_io_channel_unix_get_fd(server->channel); + else + fd = -1; + + DBG("index %d server %s sock %d", server->index, server->server, fd); + + server_list_sec = g_slist_remove(server_list_sec, server); + + if (fd > 0) + close(fd); + + server_destroy_socket(server); + + if (server->protocol == IPPROTO_UDP && server->enabled) + DBG("Removing DNS server %s", server->server); + + g_free(server->server); + for (list = server->domains; list; list = list->next) { + char *domain = list->data; + + server->domains = g_list_remove(server->domains, domain); + g_free(domain); + } + g_free(server->server_addr); + + /* + * We do not remove cache right away but delay it few seconds. + * The idea is that when IPv6 DNS server is added via RDNSS, it has a + * lifetime. When the lifetime expires we decrease the refcount so it + * is possible that the cache is then removed. Because a new DNS server + * is usually created almost immediately we would then loose the cache + * without any good reason. The small delay allows the new RDNSS to + * create a new DNS server instance and the refcount does not go to 0. + */ + /* TODO: Need to check this */ + /* g_timeout_add_seconds(3, try_remove_cache, NULL); */ + + g_free(server); +} + +static void destroy_all_server_sec() +{ + GSList *list; + + DBG("remove all dns server"); + + for (list = server_list_sec; list; list = list->next) { + struct server_data *server = list->data; + destroy_server_sec(server); + } + server_list_sec = NULL; +} + +static gboolean sec_udp_idle_timeout(gpointer user_data) +{ + struct server_data *server = user_data; + + DBG(""); + + if (server == NULL) + return FALSE; + + destroy_server_sec(server); + + return FALSE; +} + +static struct server_data *create_server_sec(int index, + const char *domain, const char *server, + int protocol) +{ + struct server_data *data; + struct addrinfo hints, *rp; + int ret; + + DBG("index %d server %s", index, server); + + data = g_try_new0(struct server_data, 1); + if (data == NULL) { + connman_error("Failed to allocate server %s data", server); + return NULL; + } + + data->index = index; + if (domain) + data->domains = g_list_append(data->domains, g_strdup(domain)); + data->server = g_strdup(server); + data->protocol = protocol; + + memset(&hints, 0, sizeof(hints)); + + switch (protocol) { + case IPPROTO_UDP: + hints.ai_socktype = SOCK_DGRAM; + break; + + case IPPROTO_TCP: + hints.ai_socktype = SOCK_STREAM; + break; + + default: + destroy_server_sec(data); + return NULL; + } + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST; + + ret = getaddrinfo(data->server, "53", &hints, &rp); + if (ret) { + connman_error("Failed to parse server %s address: %s\n", + data->server, gai_strerror(ret)); + freeaddrinfo(rp); + destroy_server_sec(data); + return NULL; + } + + /* Do not blindly copy this code elsewhere; it doesn't loop over the + results using ->ai_next as it should. That's OK in *this* case + because it was a numeric lookup; we *know* there's only one. */ + + data->server_addr_len = rp->ai_addrlen; + + switch (rp->ai_family) { + case AF_INET: + data->server_addr = (struct sockaddr *) + g_try_new0(struct sockaddr_in, 1); + break; + case AF_INET6: + data->server_addr = (struct sockaddr *) + g_try_new0(struct sockaddr_in6, 1); + break; + default: + connman_error("Wrong address family %d", rp->ai_family); + break; + } + if (data->server_addr == NULL) { + freeaddrinfo(rp); + destroy_server_sec(data); + return NULL; + } + memcpy(data->server_addr, rp->ai_addr, rp->ai_addrlen); + freeaddrinfo(rp); + + if (server_create_socket(data) != 0) { + destroy_server_sec(data); + return NULL; + } + + if (protocol == IPPROTO_UDP) { + /* Enable new servers by default */ + data->enabled = TRUE; + DBG("Adding DNS server %s", data->server); + + data->timeout = g_timeout_add_seconds(30, sec_udp_idle_timeout, + data); + + server_list_sec = g_slist_append(server_list_sec, data); + } + + return data; +} +#endif + static struct server_data *create_server(int index, const char *domain, const char *server, int protocol) @@ -2840,6 +3068,10 @@ int __connman_dnsproxy_remove(int index, const char *domain, remove_server(index, domain, server, IPPROTO_UDP); remove_server(index, domain, server, IPPROTO_TCP); +#if defined TIZEN_EXT + destroy_all_server_sec(); +#endif + return 0; } @@ -3288,6 +3520,23 @@ static gboolean client_timeout(gpointer user_data) return FALSE; } +#if defined TIZEN_EXT +static void recover_listener(GIOChannel *channel, struct listener_data *ifdata) +{ + int sk, index; + + index = ifdata->index; + + sk = g_io_channel_unix_get_fd(channel); + close(sk); + + __connman_dnsproxy_remove_listener(index); + + if (__connman_dnsproxy_add_listener(index) == 0) + DBG("listener %d successfully recovered", index); +} +#endif + static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition, struct listener_data *ifdata, int family, guint *listener_watch) @@ -3308,11 +3557,17 @@ static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition, condition, channel, ifdata, family); if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { +#if defined TIZEN_EXT + connman_error("Error %d with TCP listener channel", condition); + + recover_listener(channel, ifdata); +#else if (*listener_watch > 0) g_source_remove(*listener_watch); *listener_watch = 0; connman_error("Error with TCP listener channel"); +#endif return false; } @@ -3426,7 +3681,11 @@ static bool tcp_listener_event(GIOChannel *channel, GIOCondition condition, * The packet length bytes do not contain the total message length, * that is the reason to -2 below. */ +#if defined TIZEN_EXT + if (msg_len > (unsigned int)(len - 2)) { +#else if (msg_len != (unsigned int)(len - 2)) { +#endif debug("client %d sent %d bytes but expecting %u pending %d", client_sk, len, msg_len + 2, msg_len + 2 - len); @@ -3471,8 +3730,14 @@ static bool udp_listener_event(GIOChannel *channel, GIOCondition condition, int sk, err, len; if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { +#if defined TIZEN_EXT + connman_error("Error %d with UDP listener channel", condition); + + recover_listener(channel, ifdata); +#else connman_error("Error with UDP listener channel"); *listener_watch = 0; +#endif return false; } @@ -3531,7 +3796,12 @@ static bool udp_listener_event(GIOChannel *channel, GIOCondition condition, req->name = g_strdup(query); req->request = g_malloc(len); memcpy(req->request, buf, len); +#if defined TIZEN_EXT + DBG("req %p dstid 0x%04x altid 0x%04x", req, req->dstid, req->altid); + req->timeout = g_timeout_add_seconds(30, request_timeout, req); +#else req->timeout = g_timeout_add_seconds(5, request_timeout, req); +#endif request_list = g_slist_append(request_list, req); return true; @@ -3559,14 +3829,24 @@ static GIOChannel *get_listener(int family, int protocol, int index) { GIOChannel *channel; const char *proto; +#if !defined TIZEN_EXT union { struct sockaddr sa; struct sockaddr_in6 sin6; struct sockaddr_in sin; } s; socklen_t slen; +#endif int sk, type; +#if !defined TIZEN_EXT char *interface; +#endif +#if defined TIZEN_EXT + int option; + int sd_num = 0; + int rv; + int is_socket_inet = 0; +#endif debug("family %d protocol %d index %d", family, protocol, index); @@ -3584,7 +3864,33 @@ static GIOChannel *get_listener(int family, int protocol, int index) default: return NULL; } +#if defined TIZEN_EXT + sd_num = sd_listen_fds(0); + DBG("socket type(%s) systemd number of fds(%d)", proto, sd_num); + if(sd_num < 1){ + DBG("fail to get the fd from systemd"); + return NULL; + } + if(protocol == IPPROTO_TCP) + type = SOCK_STREAM; + else + type = SOCK_DGRAM; + + for(sk = SD_LISTEN_FDS_START; sk < SD_LISTEN_FDS_START+sd_num; ++sk){ + rv = sd_is_socket_inet(sk, family, type, -1, 53); + if(rv > 0){ + DBG("socket fd (%d) is passed by systemd", sk); + is_socket_inet = 1; + break; + } + } + + if (!is_socket_inet) { + DBG("socket fd is not matched what connman requests"); + return NULL; + } +#else sk = socket(family, type, protocol); if (sk < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) { connman_error("No IPv6 support"); @@ -3596,6 +3902,9 @@ static GIOChannel *get_listener(int family, int protocol, int index) return NULL; } + /* ConnMan listens DNS from multiple interfaces + * E.g. various technology based and tethering interfaces + */ interface = connman_inet_ifname(index); if (!interface || setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, interface, @@ -3632,7 +3941,6 @@ static GIOChannel *get_listener(int family, int protocol, int index) s.sin.sin_family = AF_INET; s.sin.sin_port = htons(53); slen = sizeof(s.sin); - if (__connman_inet_get_interface_address(index, AF_INET, &s.sin.sin_addr) < 0) { @@ -3643,22 +3951,30 @@ static GIOChannel *get_listener(int family, int protocol, int index) close(sk); return NULL; } - +#endif +#if defined TIZEN_EXT + /* When ConnMan crashed, + * probably DNS listener cannot bind existing address */ + option = 1; + setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); +#endif +#if !defined TIZEN_EXT if (bind(sk, &s.sa, slen) < 0) { connman_error("Failed to bind %s listener socket", proto); close(sk); return NULL; } +#endif if (protocol == IPPROTO_TCP) { - +#if !defined TIZEN_EXT if (listen(sk, 10) < 0) { connman_error("Failed to listen on TCP socket %d/%s", -errno, strerror(errno)); close(sk); return NULL; } - +#endif fcntl(sk, F_SETFL, O_NONBLOCK); } @@ -3691,40 +4007,68 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata) ifdata->tcp4_listener_channel = get_listener(AF_INET, protocol, ifdata->index); if (ifdata->tcp4_listener_channel) +#if defined TIZEN_EXT + ifdata->tcp4_listener_watch = + g_io_add_watch(ifdata->tcp4_listener_channel, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + tcp4_listener_event, (gpointer)ifdata); +#else ifdata->tcp4_listener_watch = g_io_add_watch(ifdata->tcp4_listener_channel, G_IO_IN, tcp4_listener_event, (gpointer)ifdata); +#endif else ret |= TCP_IPv4_FAILED; ifdata->tcp6_listener_channel = get_listener(AF_INET6, protocol, ifdata->index); if (ifdata->tcp6_listener_channel) +#if defined TIZEN_EXT + ifdata->tcp6_listener_watch = + g_io_add_watch(ifdata->tcp6_listener_channel, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + tcp6_listener_event, (gpointer)ifdata); +#else ifdata->tcp6_listener_watch = g_io_add_watch(ifdata->tcp6_listener_channel, G_IO_IN, tcp6_listener_event, (gpointer)ifdata); +#endif else ret |= TCP_IPv6_FAILED; } else { ifdata->udp4_listener_channel = get_listener(AF_INET, protocol, ifdata->index); if (ifdata->udp4_listener_channel) +#if defined TIZEN_EXT + ifdata->udp4_listener_watch = + g_io_add_watch(ifdata->udp4_listener_channel, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + udp4_listener_event, (gpointer)ifdata); +#else ifdata->udp4_listener_watch = g_io_add_watch(ifdata->udp4_listener_channel, G_IO_IN, udp4_listener_event, (gpointer)ifdata); +#endif else ret |= UDP_IPv4_FAILED; ifdata->udp6_listener_channel = get_listener(AF_INET6, protocol, ifdata->index); if (ifdata->udp6_listener_channel) +#if defined TIZEN_EXT + ifdata->udp6_listener_watch = + g_io_add_watch(ifdata->udp6_listener_channel, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + udp6_listener_event, (gpointer)ifdata); +#else ifdata->udp6_listener_watch = g_io_add_watch(ifdata->udp6_listener_channel, G_IO_IN, udp6_listener_event, (gpointer)ifdata); +#endif else ret |= UDP_IPv6_FAILED; } diff --git a/src/eduroam.config b/src/eduroam.config index 768b7b40..768b7b40 100644..100755 --- a/src/eduroam.config +++ b/src/eduroam.config diff --git a/src/error.c b/src/error.c index 4f24ae25..4f24ae25 100644..100755 --- a/src/error.c +++ b/src/error.c diff --git a/src/inet.c b/src/inet.c index b887aa0b..008f3de7 100644..100755 --- a/src/inet.c +++ b/src/inet.c @@ -330,6 +330,61 @@ done: return err; } +#if defined TIZEN_EXT +void connman_inet_update_device_ident(struct connman_device *device) +{ + int index; + enum connman_device_type type; + char *ident = NULL, *addr = NULL; + + index = connman_device_get_index(device); + type = connman_device_get_type(device); + + switch (type) { + case CONNMAN_DEVICE_TYPE_UNKNOWN: + return; + case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_GADGET: + case CONNMAN_DEVICE_TYPE_WIFI: + addr = index2addr(index); + break; + case CONNMAN_DEVICE_TYPE_BLUETOOTH: + case CONNMAN_DEVICE_TYPE_CELLULAR: + case CONNMAN_DEVICE_TYPE_GPS: + case CONNMAN_DEVICE_TYPE_VENDOR: + break; + } + + switch (type) { + case CONNMAN_DEVICE_TYPE_VENDOR: + case CONNMAN_DEVICE_TYPE_GPS: + break; + case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_GADGET: + ident = index2ident(index, NULL); + break; + case CONNMAN_DEVICE_TYPE_WIFI: + ident = index2ident(index, NULL); + break; + case CONNMAN_DEVICE_TYPE_BLUETOOTH: + break; + case CONNMAN_DEVICE_TYPE_CELLULAR: + ident = index2ident(index, NULL); + break; + } + + if (ident != NULL) { + connman_device_set_ident(device, ident); + g_free(ident); + } + + if (addr != NULL) { + connman_device_set_string(device, "Address", addr); + g_free(addr); + } +} +#endif + struct in6_ifreq { struct in6_addr ifr6_addr; __u32 ifr6_prefixlen; @@ -1282,6 +1337,37 @@ static int icmpv6_recv(int fd, struct xs_cb_data *data) return -errno; } +#if defined TIZEN_EXT + /* Set Received Source Address from router as IPv6 Gateway Address */ + char src_addr[INET6_ADDRSTRLEN]; + if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN) + == NULL) { + xs_cleanup(data); + return -errno; + } + DBG("Received Source Address %s from router", src_addr); + + /* icmpv6_recv() function can be called in two scenarios : + * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6() + * 2. When __connman_inet_ipv6_send_rs() is called from + * __connman_6to4_probe() + * In the second case it is not required to set DHCPv6 Gateway Address + * as DHCPv6 was not started and network structure was not passed as + * user_data. If it is tried to add Source Address as Gateway Address + * then it will lead to crash because of user_data being ip_address + * instead of network structure. So Adding Gateway Address in case 1st + * case only. + */ + char *address = data->user_data; + int err = 0; + unsigned char buffer[sizeof(struct in6_addr)] = {0, }; + /* Checking if user_data is an ip_address */ + err = inet_pton(AF_INET, address, buffer); + /* Setting Received Source Address from + * router as Gateway Address */ + if(err <= 0) + __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data); +#endif hdr = (struct nd_router_advert *)buf; DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len, sizeof(struct nd_router_advert)); @@ -1381,6 +1467,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest, char cbuf[CMSG_SPACE(sizeof(*pinfo))]; struct iovec iov[2]; int fd, datalen, ret, iovlen = 1; +#if defined TIZEN_EXT + char ebuf[256]; +#endif DBG(""); @@ -1459,6 +1548,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest, msgh.msg_controllen = cmsg->cmsg_len; ret = sendmsg(fd, &msgh, 0); +#if defined TIZEN_EXT + DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf))); +#endif close(fd); return ret; @@ -2651,7 +2743,8 @@ char **__connman_inet_get_running_interfaces(void) g_free(ifr); - if (count < numif) { + if (count < numif) + { char **prev_result = result; result = g_try_realloc(result, (count + 1) * sizeof(char *)); if (!result) { diff --git a/src/inotify.c b/src/inotify.c index c251c6ff..c251c6ff 100644..100755 --- a/src/inotify.c +++ b/src/inotify.c diff --git a/src/ipaddress.c b/src/ipaddress.c index d63d95c3..d63d95c3 100644..100755 --- a/src/ipaddress.c +++ b/src/ipaddress.c diff --git a/src/ipconfig.c b/src/ipconfig.c index 25657733..d94b8734 100644..100755 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -52,6 +52,10 @@ struct connman_ipconfig { struct connman_ipaddress *address; struct connman_ipaddress *system; +#if defined TIZEN_EXT + int dhcp_lease_duration; +#endif + int ipv6_privacy_config; char *last_dhcp_address; char **last_dhcpv6_prefixes; @@ -488,6 +492,16 @@ void __connman_ipconfig_newlink(int index, unsigned short type, index, type, type2str(type)); update: +#if defined TIZEN_EXT + if (g_strcmp0(ipdevice->address, address) != 0) { + /* If an original address is built-in physical device, + * it's hardly get an address at a initial creation + */ + g_free(ipdevice->address); + ipdevice->address = g_strdup(address); + } +#endif + ipdevice->mtu = mtu; update_stats(ipdevice, ifname, stats); @@ -1047,16 +1061,32 @@ void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, ipconfig->address->gateway = g_strdup(gateway); } +#if defined TIZEN_EXT +void __connman_ipconfig_set_dhcp_lease_duration(struct connman_ipconfig *ipconfig, + int dhcp_lease_duration) +{ + ipconfig->dhcp_lease_duration = dhcp_lease_duration; +} +#endif + +#if defined TIZEN_EXT +int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service) +#else int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig) +#endif { +#if !defined TIZEN_EXT struct connman_service *service; +#endif DBG(""); if (!ipconfig->address) return -EINVAL; +#if !defined TIZEN_EXT service = __connman_service_lookup_from_index(ipconfig->index); +#endif if (!service) return -EINVAL; @@ -1122,8 +1152,11 @@ static struct connman_ipconfig *create_ipv6config(int index) ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index)); if (ipdevice) +#if !defined TIZEN_EXT ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy; - +#else + ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy = 2; +#endif ipv6config->address = connman_ipaddress_alloc(AF_INET6); if (!ipv6config->address) { g_free(ipv6config); @@ -1353,6 +1386,12 @@ int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig) if (!ipconfig) return 0; +#if defined TIZEN_EXT + DBG("ipconfig method %d type %d", ipconfig->method, ipconfig->type); +#else + DBG("method %d", ipconfig->method); +#endif + switch (ipconfig->method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: @@ -1639,6 +1678,11 @@ int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig) if (ipdevice->config_ipv6 == ipconfig) { ipconfig_list = g_list_remove(ipconfig_list, ipconfig); +#if defined TIZEN_EXT + if (ipdevice->config_ipv6->method == + CONNMAN_IPCONFIG_METHOD_AUTO) + disable_ipv6(ipdevice->config_ipv6); +#endif connman_ipaddress_clear(ipdevice->config_ipv6->system); __connman_ipconfig_unref(ipdevice->config_ipv6); ipdevice->config_ipv6 = NULL; @@ -1772,6 +1816,11 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig, case CONNMAN_IPCONFIG_METHOD_MANUAL: case CONNMAN_IPCONFIG_METHOD_DHCP: append_addr = ipconfig->system; +#if defined TIZEN_EXT + /* TIZEN enables get_properties before __connman_ipconfig_newaddr */ + if (append_addr && append_addr->local == NULL) + append_addr = ipconfig->address; +#endif break; } @@ -1796,6 +1845,20 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig, if (append_addr->gateway) connman_dbus_dict_append_basic(iter, "Gateway", DBUS_TYPE_STRING, &append_addr->gateway); + +#if defined TIZEN_EXT + if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_DHCP) { + char *server_ip; + server_ip = __connman_dhcp_get_server_address(ipconfig); + if (server_ip) { + connman_dbus_dict_append_basic(iter, "DHCPServerIP", + DBUS_TYPE_STRING, &server_ip); + g_free(server_ip); + } + connman_dbus_dict_append_basic(iter, "DHCPLeaseDuration", + DBUS_TYPE_INT32, &ipconfig->dhcp_lease_duration); + } +#endif } void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig, @@ -1833,6 +1896,11 @@ void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig, case CONNMAN_IPCONFIG_METHOD_DHCP: case CONNMAN_IPCONFIG_METHOD_AUTO: append_addr = ipconfig->system; +#if defined TIZEN_EXT + /* TIZEN enables get_properties before __connman_ipconfig_newaddr */ + if (append_addr && append_addr->local == NULL) + append_addr = ipconfig->address; +#endif break; } @@ -2032,7 +2100,10 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig, case CONNMAN_IPCONFIG_METHOD_OFF: ipconfig->method = method; - +#if defined TIZEN_EXT + if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) + disable_ipv6(ipconfig); +#endif break; case CONNMAN_IPCONFIG_METHOD_AUTO: @@ -2042,7 +2113,9 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig, ipconfig->method = method; if (privacy_string) ipconfig->ipv6_privacy_config = privacy; - +#if defined TIZEN_EXT + enable_ipv6(ipconfig); +#endif break; case CONNMAN_IPCONFIG_METHOD_MANUAL: diff --git a/src/ippool.c b/src/ippool.c index cea1dccd..cea1dccd 100644..100755 --- a/src/ippool.c +++ b/src/ippool.c diff --git a/src/iptables.c b/src/iptables.c index 5ef757a3..aaddf9d6 100644..100755 --- a/src/iptables.c +++ b/src/iptables.c @@ -2350,7 +2350,7 @@ int __connman_iptables_commit(const char *table_name) return -EINVAL; repl = iptables_blob(table); - if (!repl) + if(!repl) return -ENOMEM; if (debug_enabled) diff --git a/src/ipv6pd.c b/src/ipv6pd.c index 0d221f07..0d221f07 100644..100755 --- a/src/ipv6pd.c +++ b/src/ipv6pd.c diff --git a/src/log.c b/src/log.c index 9bae4a3d..fa8ac31f 100644..100755 --- a/src/log.c +++ b/src/log.c @@ -30,6 +30,7 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> +#include <execinfo.h> #include <dlfcn.h> #include "connman.h" @@ -37,6 +38,132 @@ static const char *program_exec; static const char *program_path; +#if defined TIZEN_EXT +#include <sys/stat.h> +#include <sys/time.h> + +#define LOG_FILE_PATH "/opt/usr/data/network/connman.log" +#define MAX_LOG_SIZE 1 * 1024 * 1024 +#define MAX_LOG_COUNT 1 + +#define openlog __connman_log_open +#define closelog __connman_log_close +#define vsyslog __connman_log +#define syslog __connman_log_s + +static FILE *log_file = NULL; + +void __connman_log_open(const char *ident, int option, int facility) +{ + if (!log_file) + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); +} + +void __connman_log_close(void) +{ + fclose(log_file); + log_file = NULL; +} + +static void __connman_log_update_file_revision(int rev) +{ + int next_log_rev = 0; + char *log_file = NULL; + char *next_log_file = NULL; + + next_log_rev = rev + 1; + + log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev); + next_log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, next_log_rev); + + if (next_log_rev >= MAX_LOG_COUNT) + remove(next_log_file); + + if (access(next_log_file, F_OK) == 0) + __connman_log_update_file_revision(next_log_rev); + + if (rename(log_file, next_log_file) != 0) + remove(log_file); + + g_free(log_file); + g_free(next_log_file); +} + +static void __connman_log_make_backup(void) +{ + const int rev = 0; + char *backup = NULL; + + backup = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev); + + if (access(backup, F_OK) == 0) + __connman_log_update_file_revision(rev); + + if (rename(LOG_FILE_PATH, backup) != 0) + remove(LOG_FILE_PATH); + + g_free(backup); +} + +static void __connman_log_get_local_time(char *strtime, const int size) +{ + struct timeval tv; + struct tm *local_ptm; + char buf[32]; + + gettimeofday(&tv, NULL); + local_ptm = localtime(&tv.tv_sec); + + strftime(buf, sizeof(buf), "%m/%d %H:%M:%S", local_ptm); + snprintf(strtime, size, "%s.%03ld", buf, tv.tv_usec / 1000); +} + +void __connman_log(const int log_priority, const char *format, va_list ap) +{ + int log_size = 0; + struct stat buf; + char str[256]; + char strtime[40]; + + if (!log_file) + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + + if (!log_file) + return; + + fstat(fileno(log_file), &buf); + log_size = buf.st_size; + + if (log_size >= MAX_LOG_SIZE) { + fclose(log_file); + log_file = NULL; + + __connman_log_make_backup(); + + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + + if (!log_file) + return; + } + + __connman_log_get_local_time(strtime, sizeof(strtime)); + + if (vsnprintf(str, sizeof(str), format, ap) > 0) + fprintf(log_file, "%s %s\n", strtime, str); +} + +void __connman_log_s(int log_priority, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + + vsyslog(LOG_DEBUG, format, ap); + + va_end(ap); +} +#endif + /** * connman_info: * @format: format string @@ -89,6 +216,7 @@ void connman_error(const char *format, ...) vsyslog(LOG_ERR, format, ap); va_end(ap); + fflush(log_file); } /** @@ -107,13 +235,116 @@ void connman_debug(const char *format, ...) vsyslog(LOG_DEBUG, format, ap); va_end(ap); + fflush(log_file); +} + +static void print_backtrace(unsigned int offset) +{ + void *frames[99]; + size_t n_ptrs; + unsigned int i; + int outfd[2], infd[2]; + int pathlen; + pid_t pid; + + if (!program_exec) + return; + + pathlen = strlen(program_path); + + n_ptrs = backtrace(frames, G_N_ELEMENTS(frames)); + if (n_ptrs < offset) + return; + + if (pipe(outfd) < 0) + return; + + if (pipe(infd) < 0) { + close(outfd[0]); + close(outfd[1]); + return; + } + + pid = fork(); + if (pid < 0) { + close(outfd[0]); + close(outfd[1]); + close(infd[0]); + close(infd[1]); + return; + } + + if (pid == 0) { + close(outfd[1]); + close(infd[0]); + + dup2(outfd[0], STDIN_FILENO); + dup2(infd[1], STDOUT_FILENO); + + execlp("addr2line", "-C", "-f", "-e", program_exec, NULL); + + exit(EXIT_FAILURE); + } + + close(outfd[0]); + close(infd[1]); + + connman_error("++++++++ backtrace ++++++++"); + + for (i = offset; i < n_ptrs - 1; i++) { + Dl_info info; + char addr[20], buf[PATH_MAX * 2]; + int len, written; + char *ptr, *pos; + + dladdr(frames[i], &info); + + len = snprintf(addr, sizeof(addr), "%p\n", frames[i]); + if (len < 0) + break; + + written = write(outfd[1], addr, len); + if (written < 0) + break; + + len = read(infd[0], buf, sizeof(buf) - 1); + if (len < 0) + break; + + buf[len] = '\0'; + + pos = strchr(buf, '\n'); + *pos++ = '\0'; + + if (strcmp(buf, "??") == 0) { + connman_error("#%-2u %p in %s", i - offset, + frames[i], info.dli_fname); + continue; + } + + ptr = strchr(pos, '\n'); + *ptr++ = '\0'; + + if (strncmp(pos, program_path, pathlen) == 0) + pos += pathlen + 1; + + connman_error("#%-2u %p in %s() at %s", i - offset, + frames[i], buf, pos); + } + + connman_error("+++++++++++++++++++++++++++"); + + kill(pid, SIGTERM); + + close(outfd[1]); + close(infd[0]); } static void signal_handler(int signo) { connman_error("Aborting (signal %d) [%s]", signo, program_exec); - print_backtrace(program_path, program_exec, 2); + print_backtrace(2); exit(EXIT_FAILURE); } diff --git a/src/machine.c b/src/machine.c index 14ea3667..14ea3667 100644..100755 --- a/src/machine.c +++ b/src/machine.c diff --git a/src/main.c b/src/main.c index b78a0461..4bc2266b 100644..100755 --- a/src/main.c +++ b/src/main.c @@ -30,6 +30,8 @@ #include <string.h> #include <signal.h> #include <sys/signalfd.h> +#include <sys/types.h> +#include <sys/resource.h> #include <getopt.h> #include <sys/stat.h> #include <net/if.h> @@ -79,6 +81,10 @@ static struct { bool enable_6to4; char *vendor_class_id; bool enable_online_check; +#if defined TIZEN_EXT + char **cellular_interfaces; + bool tizen_tv_extension; +#endif } connman_settings = { .bg_scan = true, .pref_timeservers = NULL, @@ -96,6 +102,10 @@ static struct { .enable_6to4 = false, .vendor_class_id = NULL, .enable_online_check = true, +#if defined TIZEN_EXT + .cellular_interfaces = NULL, + .tizen_tv_extension = false, +#endif }; #define CONF_BG_SCAN "BackgroundScanning" @@ -114,6 +124,10 @@ static struct { #define CONF_ENABLE_6TO4 "Enable6to4" #define CONF_VENDOR_CLASS_ID "VendorClassID" #define CONF_ENABLE_ONLINE_CHECK "EnableOnlineCheck" +#if defined TIZEN_EXT +#define CONF_CELLULAR_INTERFACE "NetworkCellularInterfaceList" +#define CONF_TIZEN_TV_EXT "TizenTVExtension" +#endif static const char *supported_options[] = { CONF_BG_SCAN, @@ -130,8 +144,11 @@ static const char *supported_options[] = { CONF_TETHERING_TECHNOLOGIES, CONF_PERSISTENT_TETHERING_MODE, CONF_ENABLE_6TO4, - CONF_VENDOR_CLASS_ID, CONF_ENABLE_ONLINE_CHECK, +#if defined TIZEN_EXT + CONF_CELLULAR_INTERFACE, + CONF_TIZEN_TV_EXT, +#endif NULL }; @@ -246,6 +263,46 @@ static void check_config(GKeyFile *config) g_strfreev(keys); } +#if defined TIZEN_EXT +static void check_Tizen_configuration(GKeyFile *config) +{ + GError *error = NULL; + char **cellular_interfaces; + bool boolean; + gsize len; + + cellular_interfaces = g_key_file_get_string_list(config, "General", + CONF_CELLULAR_INTERFACE, &len, &error); + + if (error == NULL) + connman_settings.cellular_interfaces = cellular_interfaces; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "General", + CONF_TIZEN_TV_EXT, &error); + if (!error) + connman_settings.tizen_tv_extension = boolean; + + g_clear_error(&error); +} + +static void set_nofile_inc(void) +{ + int err; + struct rlimit rlim; + + rlim.rlim_cur = 8192; + rlim.rlim_max = 8192; + + err = setrlimit(RLIMIT_NOFILE, &rlim); + if (err) + DBG("fail to increase FILENO err(%d)", err); + + return; +} +#endif + static void parse_config(GKeyFile *config) { GError *error = NULL; @@ -408,12 +465,19 @@ static void parse_config(GKeyFile *config) } g_clear_error(&error); + +#if defined TIZEN_EXT + check_Tizen_configuration(config); +#endif } static int config_init(const char *file) { GKeyFile *config; +#if defined TIZEN_EXT + set_nofile_inc(); +#endif config = load_config(file); check_config(config); parse_config(config); @@ -632,6 +696,11 @@ char **connman_setting_get_string_list(const char *key) if (g_str_equal(key, CONF_TETHERING_TECHNOLOGIES)) return connman_settings.tethering_technologies; +#if defined TIZEN_EXT + if (g_str_equal(key, CONF_CELLULAR_INTERFACE)) + return connman_settings.cellular_interfaces; +#endif + return NULL; } @@ -768,8 +837,10 @@ int main(int argc, char *argv[]) __connman_dhcpv6_init(); __connman_wpad_init(); __connman_wispr_init(); +#if !defined TIZEN_EXT __connman_rfkill_init(); __connman_machine_init(); +#endif g_free(option_config); g_free(option_device); @@ -781,8 +852,10 @@ int main(int argc, char *argv[]) g_source_remove(signal); +#if !defined TIZEN_EXT __connman_machine_cleanup(); __connman_rfkill_cleanup(); +#endif __connman_wispr_cleanup(); __connman_wpad_cleanup(); __connman_dhcpv6_cleanup(); diff --git a/src/main.conf b/src/main.conf index 68870b28..a2cc1e20 100644..100755 --- a/src/main.conf +++ b/src/main.conf @@ -19,6 +19,7 @@ # the scan list is empty. In that case, a simple backoff # mechanism starting from 10s up to 5 minutes will run. # BackgroundScanning = true +BackgroundScanning = false # List of Fallback timeservers separated by ",". # These timeservers are used for NTP sync when there are @@ -26,6 +27,7 @@ # These can contain mixed combination of fully qualified # domain names, IPv4 and IPv6 addresses. # FallbackTimeservers = +#FallbackTimeservers = pool.ntp.org # List of fallback nameservers separated by "," used if no # nameservers are otherwise provided by the service. The @@ -52,6 +54,7 @@ # the default route when compared to either a non-preferred # type or a preferred type further down in the list. # PreferredTechnologies = +PreferredTechnologies = wifi, ethernet # List of blacklisted network interfaces separated by ",". # Found interfaces will be compared to the list and will @@ -59,6 +62,7 @@ # match any of the list entries. Default value is # vmnet,vboxnet,virbr,ifb,ve-,vb-. # NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,ve-,vb- +NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w # Allow connman to change the system hostname. This can # happen for example if we receive DHCP hostname option. @@ -76,6 +80,7 @@ # setting enabled applications will notice more network breaks than # normal. Default value is false. # SingleConnectedTechnology = false +SingleConnectedTechnology = true # List of technologies for which tethering is allowed separated by ",". # The default value is wifi,bluetooth,gadget. Only those technologies @@ -117,3 +122,5 @@ # other which is already connected. # This setting has no effect if SingleConnectedTechnologies is enabled. # AlwaysConnectedTechnologies = + +NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w diff --git a/src/main_disable_eth.conf b/src/main_disable_eth.conf new file mode 100755 index 00000000..c4ec3e38 --- /dev/null +++ b/src/main_disable_eth.conf @@ -0,0 +1,110 @@ +[General] + +# Set input request timeout. Default is 120 seconds +# The request for inputs like passphrase will timeout +# after certain amount of time. Use this setting to +# increase the value in case of different user +# interface designs. +# InputRequestTimeout = 120 + +# Set browser launch timeout. Default is 300 seconds +# The request for launching a browser for portal pages +# will timeout after certain amount of time. Use this +# setting to increase the value in case of different +# user interface designs. +# BrowserLaunchTimeout = 300 + +# Enable background scanning. Default is true. +# Background scanning will start every 5 minutes unless +# the scan list is empty. In that case, a simple backoff +# mechanism starting from 10s up to 5 minutes will run. +# BackgroundScanning = true +BackgroundScanning = false + +# List of Fallback timeservers separated by ",". +# These timeservers are used for NTP sync when there are +# no timeserver set by the user or by the service. +# These can contain mixed combination of fully qualified +# domain names, IPv4 and IPv6 addresses. +# FallbackTimeservers = +#FallbackTimeservers = pool.ntp.org + +# List of fallback nameservers separated by "," used if no +# nameservers are otherwise provided by the service. The +# nameserver entries must be in numeric format, host +# names are ignored. +# FallbackNameservers = + +# List of technologies that are marked autoconnectable +# by default, separated by commas ",". The default value +# for this entry when empty is ethernet,wifi,cellular. +# Services that are automatically connected must have been +# set up and saved to storage beforehand. +# DefaultAutoConnectTechnologies = + +# List of preferred technologies from the most preferred +# one to the least preferred one separated by commas ",". +# Services of the listed technology type will be tried one +# by one in the order given, until one of them gets connected +# or they are all tried. A service of a preferred technology +# type in state 'ready' will get the default route when +# compared to another preferred type further down the list +# with state 'ready' or with a non-preferred type; a service +# of a preferred technology type in state 'online' will get +# the default route when compared to either a non-preferred +# type or a preferred type further down in the list. +# PreferredTechnologies = +PreferredTechnologies = wifi, ethernet + +# List of blacklisted network interfaces separated by ",". +# Found interfaces will be compared to the list and will +# not be handled by connman, if their first characters +# match any of the list entries. Default value is +# vmnet,vboxnet,virbr,ifb. +# NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb +NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w,eth + +# Allow connman to change the system hostname. This can +# happen for example if we receive DHCP hostname option. +# Default value is true. +# AllowHostnameUpdates = true + +# Keep only a single connected technology at any time. When a new +# service is connected by the user or a better one is found according +# to PreferredTechnologies, the new service is kept connected and all +# the other previously connected services are disconnected. With this +# setting it does not matter whether the previously connected services +# are in 'online' or 'ready' states, the newly connected service is +# the only one that will be kept connected. A service connected by the +# user will be used until going out of network coverage. With this +# setting enabled applications will notice more network breaks than +# normal. Default value is false. +# SingleConnectedTechnology = false +SingleConnectedTechnology = true + +# List of technologies for which tethering is allowed separated by ",". +# The default value is wifi,bluetooth,gadget. Only those technologies +# listed here are used for tethering. If ethernet tethering is desired, +# then ethernet should be added to the list. The technologies listed here +# have to support tethering, currently tethering is implemented for wifi, +# bluetooth, gadget and ethernet. +# NOTE that if ethernet tethering is enabled, then a DHCP server is +# started on all ethernet interfaces. Tethered ethernet should +# never be connected to corporate or home network as it will disrupt +# normal operation of these networks. Due to this ethernet is not +# tethered by default. Do not activate ethernet tethering unless you +# really know what you are doing. +# TetheringTechnologies = wifi,bluetooth,gadget + +# Restore earlier tethering status when returning from offline mode, +# re-enabling a technology, and after restarts and reboots. +# Default value is false. +# PersistentTetheringMode = false + +# Automatically enable Anycast 6to4 if possible. This is not recommended, as +# the use of 6to4 will generally lead to a severe degradation of connection +# quality. See RFC6343. Default value is false (as recommended by RFC6343 +# section 4.1). +# Enable6to4 = false + +NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w diff --git a/src/main_ivi.conf b/src/main_ivi.conf new file mode 100755 index 00000000..627bd061 --- /dev/null +++ b/src/main_ivi.conf @@ -0,0 +1,110 @@ +[General] + +# Set input request timeout. Default is 120 seconds +# The request for inputs like passphrase will timeout +# after certain amount of time. Use this setting to +# increase the value in case of different user +# interface designs. +# InputRequestTimeout = 120 + +# Set browser launch timeout. Default is 300 seconds +# The request for launching a browser for portal pages +# will timeout after certain amount of time. Use this +# setting to increase the value in case of different +# user interface designs. +# BrowserLaunchTimeout = 300 + +# Enable background scanning. Default is true. +# Background scanning will start every 5 minutes unless +# the scan list is empty. In that case, a simple backoff +# mechanism starting from 10s up to 5 minutes will run. +# BackgroundScanning = true +BackgroundScanning = false + +# List of Fallback timeservers separated by ",". +# These timeservers are used for NTP sync when there are +# no timeserver set by the user or by the service. +# These can contain mixed combination of fully qualified +# domain names, IPv4 and IPv6 addresses. +# FallbackTimeservers = +#FallbackTimeservers = pool.ntp.org + +# List of fallback nameservers separated by "," used if no +# nameservers are otherwise provided by the service. The +# nameserver entries must be in numeric format, host +# names are ignored. +# FallbackNameservers = + +# List of technologies that are marked autoconnectable +# by default, separated by commas ",". The default value +# for this entry when empty is ethernet,wifi,cellular. +# Services that are automatically connected must have been +# set up and saved to storage beforehand. +# DefaultAutoConnectTechnologies = + +# List of preferred technologies from the most preferred +# one to the least preferred one separated by commas ",". +# Services of the listed technology type will be tried one +# by one in the order given, until one of them gets connected +# or they are all tried. A service of a preferred technology +# type in state 'ready' will get the default route when +# compared to another preferred type further down the list +# with state 'ready' or with a non-preferred type; a service +# of a preferred technology type in state 'online' will get +# the default route when compared to either a non-preferred +# type or a preferred type further down in the list. +# PreferredTechnologies = +PreferredTechnologies = wifi, ethernet + +# List of blacklisted network interfaces separated by ",". +# Found interfaces will be compared to the list and will +# not be handled by connman, if their first characters +# match any of the list entries. Default value is +# vmnet,vboxnet,virbr,ifb. +# NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb +NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w,eth0 + +# Allow connman to change the system hostname. This can +# happen for example if we receive DHCP hostname option. +# Default value is true. +# AllowHostnameUpdates = true + +# Keep only a single connected technology at any time. When a new +# service is connected by the user or a better one is found according +# to PreferredTechnologies, the new service is kept connected and all +# the other previously connected services are disconnected. With this +# setting it does not matter whether the previously connected services +# are in 'online' or 'ready' states, the newly connected service is +# the only one that will be kept connected. A service connected by the +# user will be used until going out of network coverage. With this +# setting enabled applications will notice more network breaks than +# normal. Default value is false. +# SingleConnectedTechnology = false +SingleConnectedTechnology = true + +# List of technologies for which tethering is allowed separated by ",". +# The default value is wifi,bluetooth,gadget. Only those technologies +# listed here are used for tethering. If ethernet tethering is desired, +# then ethernet should be added to the list. The technologies listed here +# have to support tethering, currently tethering is implemented for wifi, +# bluetooth, gadget and ethernet. +# NOTE that if ethernet tethering is enabled, then a DHCP server is +# started on all ethernet interfaces. Tethered ethernet should +# never be connected to corporate or home network as it will disrupt +# normal operation of these networks. Due to this ethernet is not +# tethered by default. Do not activate ethernet tethering unless you +# really know what you are doing. +# TetheringTechnologies = wifi,bluetooth,gadget + +# Restore earlier tethering status when returning from offline mode, +# re-enabling a technology, and after restarts and reboots. +# Default value is false. +# PersistentTetheringMode = false + +# Automatically enable Anycast 6to4 if possible. This is not recommended, as +# the use of 6to4 will generally lead to a severe degradation of connection +# quality. See RFC6343. Default value is false (as recommended by RFC6343 +# section 4.1). +# Enable6to4 = false + +NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w diff --git a/src/main_tv.conf b/src/main_tv.conf new file mode 100755 index 00000000..fd3afc90 --- /dev/null +++ b/src/main_tv.conf @@ -0,0 +1,116 @@ +[General] + +# Set input request timeout. Default is 120 seconds +# The request for inputs like passphrase will timeout +# after certain amount of time. Use this setting to +# increase the value in case of different user +# interface designs. +# InputRequestTimeout = 120 + +# Set browser launch timeout. Default is 300 seconds +# The request for launching a browser for portal pages +# will timeout after certain amount of time. Use this +# setting to increase the value in case of different +# user interface designs. +# BrowserLaunchTimeout = 300 + +# Enable background scanning. Default is true. +# Background scanning will start every 5 minutes unless +# the scan list is empty. In that case, a simple backoff +# mechanism starting from 10s up to 5 minutes will run. +# BackgroundScanning = true +BackgroundScanning = false + +# List of Fallback timeservers separated by ",". +# These timeservers are used for NTP sync when there are +# no timeserver set by the user or by the service. +# These can contain mixed combination of fully qualified +# domain names, IPv4 and IPv6 addresses. +# FallbackTimeservers = +#FallbackTimeservers = pool.ntp.org + +# List of fallback nameservers separated by "," used if no +# nameservers are otherwise provided by the service. The +# nameserver entries must be in numeric format, host +# names are ignored. +# FallbackNameservers = + +# List of technologies that are marked autoconnectable +# by default, separated by commas ",". The default value +# for this entry when empty is ethernet,wifi,cellular. +# Services that are automatically connected must have been +# set up and saved to storage beforehand. +# DefaultAutoConnectTechnologies = + +# List of preferred technologies from the most preferred +# one to the least preferred one separated by commas ",". +# Services of the listed technology type will be tried one +# by one in the order given, until one of them gets connected +# or they are all tried. A service of a preferred technology +# type in state 'ready' will get the default route when +# compared to another preferred type further down the list +# with state 'ready' or with a non-preferred type; a service +# of a preferred technology type in state 'online' will get +# the default route when compared to either a non-preferred +# type or a preferred type further down in the list. +# PreferredTechnologies = +PreferredTechnologies = wifi, ethernet + +# List of blacklisted network interfaces separated by ",". +# Found interfaces will be compared to the list and will +# not be handled by connman, if their first characters +# match any of the list entries. Default value is +# vmnet,vboxnet,virbr,ifb. +# NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb +NetworkInterfaceBlacklist = veth, vmnet,vboxnet,virbr,usb,rndis,rmnet,rev_rmnet,dummy,seth_td,seth_w + +# Allow connman to change the system hostname. This can +# happen for example if we receive DHCP hostname option. +# Default value is true. +# AllowHostnameUpdates = true + +# Keep only a single connected technology at any time. When a new +# service is connected by the user or a better one is found according +# to PreferredTechnologies, the new service is kept connected and all +# the other previously connected services are disconnected. With this +# setting it does not matter whether the previously connected services +# are in 'online' or 'ready' states, the newly connected service is +# the only one that will be kept connected. A service connected by the +# user will be used until going out of network coverage. With this +# setting enabled applications will notice more network breaks than +# normal. Default value is false. +# SingleConnectedTechnology = false +SingleConnectedTechnology = true + +# List of technologies for which tethering is allowed separated by ",". +# The default value is wifi,bluetooth,gadget. Only those technologies +# listed here are used for tethering. If ethernet tethering is desired, +# then ethernet should be added to the list. The technologies listed here +# have to support tethering, currently tethering is implemented for wifi, +# bluetooth, gadget and ethernet. +# NOTE that if ethernet tethering is enabled, then a DHCP server is +# started on all ethernet interfaces. Tethered ethernet should +# never be connected to corporate or home network as it will disrupt +# normal operation of these networks. Due to this ethernet is not +# tethered by default. Do not activate ethernet tethering unless you +# really know what you are doing. +# TetheringTechnologies = wifi,bluetooth,gadget + +# Restore earlier tethering status when returning from offline mode, +# re-enabling a technology, and after restarts and reboots. +# Default value is false. +# PersistentTetheringMode = false + +# Automatically enable Anycast 6to4 if possible. This is not recommended, as +# the use of 6to4 will generally lead to a severe degradation of connection +# quality. See RFC6343. Default value is false (as recommended by RFC6343 +# section 4.1). +# Enable6to4 = false + +NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w + + + +# Enable Tizen TV Profile Features +TizenTVExtension = true + diff --git a/src/manager.c b/src/manager.c index d15ce203..2e1367ff 100644..100755 --- a/src/manager.c +++ b/src/manager.c @@ -41,6 +41,9 @@ static DBusMessage *get_properties(DBusConnection *conn, DBusMessageIter array, dict; dbus_bool_t offlinemode; const char *str; +#if defined TIZEN_EXT + dbus_bool_t autoconnectmode; +#endif DBG("conn %p", conn); @@ -63,6 +66,12 @@ static DBusMessage *get_properties(DBusConnection *conn, connman_dbus_dict_append_basic(&dict, "SessionMode", DBUS_TYPE_BOOLEAN, &sessionmode); +#if defined TIZEN_EXT + autoconnectmode = __connman_service_get_auto_connect_mode(); + connman_dbus_dict_append_basic(&dict, "AutoConnectMode", + DBUS_TYPE_BOOLEAN, + &autoconnectmode); +#endif connman_dbus_dict_close(&array, &dict); @@ -102,6 +111,20 @@ static DBusMessage *set_property(DBusConnection *conn, dbus_message_iter_get_basic(&value, &offlinemode); + if (offlinemode) { + uid_t uid; + if (connman_dbus_get_connection_unix_user_sync(conn, + dbus_message_get_sender(msg), + &uid) < 0) { + DBG("Can not get unix user id!"); + return __connman_error_permission_denied(msg); + } + + if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) { + DBG("Not allow this user to turn on offlinemode now!"); + return __connman_error_permission_denied(msg); + } + } __connman_technology_set_offlinemode(offlinemode); } else if (g_str_equal(name, "SessionMode")) { @@ -109,8 +132,20 @@ static DBusMessage *set_property(DBusConnection *conn, return __connman_error_invalid_arguments(msg); dbus_message_iter_get_basic(&value, &sessionmode); + } +#if defined TIZEN_EXT + else if (g_str_equal(name, "AutoConnectMode") == TRUE) { + bool automode; - } else + if (type != DBUS_TYPE_BOOLEAN) + return __connman_error_invalid_arguments(msg); + + dbus_message_iter_get_basic(&value, &automode); + + __connman_service_set_auto_connect_mode(automode); + } +#endif + else return __connman_error_invalid_property(msg); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); @@ -126,7 +161,9 @@ static DBusMessage *get_technologies(DBusConnection *conn, { DBusMessage *reply; +#if !defined TIZEN_EXT DBG(""); +#endif reply = dbus_message_new_method_return(msg); if (!reply) diff --git a/src/nat.c b/src/nat.c index fb557101..fb557101 100644..100755 --- a/src/nat.c +++ b/src/nat.c diff --git a/src/net.connman.service.in b/src/net.connman.service.in index f7f6a7c0..990eb66b 100644..100755 --- a/src/net.connman.service.in +++ b/src/net.connman.service.in @@ -1,5 +1,6 @@ [D-BUS Service] Name=net.connman -Exec=@sbindir@/connmand -n -User=root +Exec=/bin/false +User=network_fw +Group=network_fw SystemdService=connman.service diff --git a/src/network.c b/src/network.c index ed56210f..d38fc0af 100644..100755 --- a/src/network.c +++ b/src/network.c @@ -41,6 +41,18 @@ */ #define RS_REFRESH_TIMEOUT 3 +#if defined TIZEN_EXT +#define WIFI_ENCYPTION_MODE_LEN_MAX 6 +#define WIFI_BSSID_LEN_MAX 6 +#endif + +/* + * As per RFC 4861, a host should transmit up to MAX_RTR_SOLICITATIONS(3) + * Router Solicitation messages, each separated by at least + * RTR_SOLICITATION_INTERVAL(4) seconds to obtain RA for IPv6 auto-configuration. + */ +#define RTR_SOLICITATION_INTERVAL 4 + static GSList *network_list = NULL; static GSList *driver_list = NULL; @@ -92,8 +104,26 @@ struct connman_network { bool wps; bool use_wps; char *pin_wps; +#if defined TIZEN_EXT + char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX]; + unsigned char bssid[WIFI_BSSID_LEN_MAX]; + unsigned int maxrate; + bool isHS20AP; + unsigned int keymgmt; + char *keymgmt_type; + bool rsn_mode; + int disconnect_reason; + int assoc_status_code; + void *wifi_vsie; + unsigned int wifi_vsie_len; +#endif } wifi; +#if defined TIZEN_EXT + /* Multiple APN services and a default APN which a user selected */ + bool default_internet; +#endif + }; static const char *type2string(enum connman_network_type type) @@ -167,7 +197,11 @@ static void dhcp_success(struct connman_network *network) if (err < 0) goto err; +#if defined TIZEN_EXT + err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service); +#else err = __connman_ipconfig_gateway_add(ipconfig_ipv4); +#endif if (err < 0) goto err; @@ -233,7 +267,11 @@ static int set_connected_manual(struct connman_network *network) if (err < 0) goto err; +#if defined TIZEN_EXT + err = __connman_ipconfig_gateway_add(ipconfig, service); +#else err = __connman_ipconfig_gateway_add(ipconfig); +#endif if (err < 0) goto err; @@ -287,7 +325,11 @@ static int manual_ipv6_set(struct connman_network *network, return err; } +#if defined TIZEN_EXT + err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service); +#else err = __connman_ipconfig_gateway_add(ipconfig_ipv6); +#endif if (err < 0) return err; @@ -427,10 +469,13 @@ static void check_dhcpv6(struct nd_router_advert *reply, DBG("re-send router solicitation %d", network->router_solicit_count); network->router_solicit_count--; - __connman_inet_ipv6_send_rs(network->index, 1, + __connman_inet_ipv6_send_rs(network->index, RTR_SOLICITATION_INTERVAL, check_dhcpv6, network); return; } +#if defined TIZEN_EXT + DBG("RA message is not received from server in reply of RS."); +#endif connman_network_unref(network); return; } @@ -443,6 +488,9 @@ static void check_dhcpv6(struct nd_router_advert *reply, */ if (!network->connected) { connman_network_unref(network); +#if defined TIZEN_EXT + DBG("Network is not connected"); +#endif return; } @@ -471,11 +519,21 @@ static void check_dhcpv6(struct nd_router_advert *reply, * We do stateful/stateless DHCPv6 if router advertisement says so. */ if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) { +#if defined TIZEN_EXT + DBG("IPv6 ND_RA_FLAG_MANAGED"); +#endif __connman_dhcpv6_start(network, prefixes, dhcpv6_callback); } else { if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) +#if defined TIZEN_EXT + { + DBG("IPv6 ND_RA_FLAG_OTHER"); +#endif __connman_dhcpv6_start_info(network, dhcpv6_info_callback); +#if defined TIZEN_EXT + } +#endif g_slist_free_full(prefixes, g_free); network->connecting = false; @@ -557,6 +615,11 @@ static void autoconf_ipv6_set(struct connman_network *network) __connman_device_set_network(network->device, network); +#if defined TIZEN_EXT + if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) + return; +#endif + service = connman_service_lookup_from_network(network); if (!service) return; @@ -577,7 +640,8 @@ static void autoconf_ipv6_set(struct connman_network *network) /* Try to get stateless DHCPv6 information, RFC 3736 */ network->router_solicit_count = 3; - __connman_inet_ipv6_send_rs(index, 1, check_dhcpv6, network); + __connman_inet_ipv6_send_rs(index, RTR_SOLICITATION_INTERVAL, + check_dhcpv6, network); } static void set_connected(struct connman_network *network) @@ -690,12 +754,22 @@ static void set_disconnected(struct connman_network *network) CONNMAN_IPCONFIG_TYPE_IPV6); if (network->connected) { +#if defined TIZEN_EXT + /** + * Do not remove gateway and its address, + * if there are connected profiles that use same interface (multiple PDN) + */ + if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_CELLULAR || + __connman_service_get_connected_count_of_iface(service) <= 0) { +#endif __connman_connection_gateway_remove(service, CONNMAN_IPCONFIG_TYPE_ALL); __connman_ipconfig_address_unset(ipconfig_ipv4); __connman_ipconfig_address_unset(ipconfig_ipv6); - +#if defined TIZEN_EXT + } +#endif /* * Special handling for IPv6 autoconfigured address. * The simplest way to remove autoconfigured routes is to @@ -905,7 +979,9 @@ static void network_destruct(struct connman_network *network) g_free(network->wifi.private_key_passphrase); g_free(network->wifi.phase2_auth); g_free(network->wifi.pin_wps); - +#if defined TIZEN_EXT + g_free(network->wifi.wifi_vsie); +#endif g_free(network->path); g_free(network->group); g_free(network->node); @@ -1147,6 +1223,15 @@ bool __connman_network_get_weakness(struct connman_network *network) return false; } +#if defined TIZEN_EXT +void connman_network_set_connecting(struct connman_network *network) +{ + DBG("set network connecting true"); + network->connecting = TRUE; + return; +} +#endif + bool connman_network_get_connecting(struct connman_network *network) { return network->connecting; @@ -1162,7 +1247,9 @@ bool connman_network_get_connecting(struct connman_network *network) int connman_network_set_available(struct connman_network *network, bool available) { +#if !defined TIZEN_EXT DBG("network %p available %d", network, available); +#endif if (network->available == available) return -EALREADY; @@ -1183,6 +1270,113 @@ bool connman_network_get_available(struct connman_network *network) return network->available; } +#if defined TIZEN_EXT +void connman_network_clear_associating(struct connman_network *network) +{ + struct connman_service *service; + enum connman_service_state state; + + DBG("network %p", network); + + network->connecting = FALSE; + network->associating = FALSE; + + service = connman_service_lookup_from_network(network); + if (!service) + return; + + state = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV4); + if (state != CONNMAN_SERVICE_STATE_IDLE && + state != CONNMAN_SERVICE_STATE_FAILURE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_DISCONNECT, + CONNMAN_IPCONFIG_TYPE_IPV4); + + state = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV6); + if (state != CONNMAN_SERVICE_STATE_IDLE && + state != CONNMAN_SERVICE_STATE_FAILURE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_DISCONNECT, + CONNMAN_IPCONFIG_TYPE_IPV6); + + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); + + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV6); +} + +static gboolean __connman_network_clear_associating_delayed(gpointer user_data) +{ + GSList *list; + gboolean found = FALSE; + enum connman_service_state state_ipv4; + enum connman_service_state state_ipv6; + struct connman_service *service; + struct connman_network *network = (struct connman_network *)user_data; + + for (list = network_list; list != NULL; list = list->next) { + struct connman_network *item = list->data; + + if (item == network) { + found = TRUE; + break; + } + } + + if (found != TRUE) + return FALSE; + + DBG("network %p name %s", network, network->name); + service = connman_service_lookup_from_network(network); + + state_ipv4 = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV4); + state_ipv6 = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV6); + + DBG("service %p state %d/%d", service, state_ipv4, state_ipv6); + + if (network->associating == FALSE && + state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION && + state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION) { + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV6); + } else { + if (network->associating == FALSE) { + struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6; + enum connman_ipconfig_method ipv4_method, ipv6_method; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4); + ipconfig_ipv6 = __connman_service_get_ip4config(service); + ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6); + + if((ipv4_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) && + (state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION)) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV6); + if((ipv6_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) && + (state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION)) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); + } + } + + return FALSE; +} +#endif + /** * connman_network_set_associating: * @network: network structure @@ -1212,6 +1406,14 @@ int connman_network_set_associating(struct connman_network *network, CONNMAN_IPCONFIG_TYPE_IPV6); } +#if defined TIZEN_EXT + if (associating == FALSE && + connman_network_get_bool(network, "WiFi.UseWPS") == FALSE) + g_timeout_add_seconds(1, + __connman_network_clear_associating_delayed, + network); +#endif + return 0; } @@ -1221,8 +1423,13 @@ static void set_associate_error(struct connman_network *network) service = connman_service_lookup_from_network(network); +#if defined TIZEN_EXT + __connman_service_indicate_error(service, + CONNMAN_SERVICE_ERROR_AUTH_FAILED); +#else __connman_service_indicate_error(service, CONNMAN_SERVICE_ERROR_CONNECT_FAILED); +#endif } static void set_configure_error(struct connman_network *network) @@ -1241,6 +1448,10 @@ static void set_invalid_key_error(struct connman_network *network) service = connman_service_lookup_from_network(network); +#if defined TIZEN_EXT + if (service) + __connman_service_set_favorite(service, false); +#endif __connman_service_indicate_error(service, CONNMAN_SERVICE_ERROR_INVALID_KEY); } @@ -1265,6 +1476,22 @@ static void set_blocked_error(struct connman_network *network) CONNMAN_SERVICE_ERROR_BLOCKED); } + +#if defined TIZEN_EXT +static void set_dhcp_error(struct connman_network *network) +{ + struct connman_service *service; + + if (network->associating != FALSE) + network->associating = FALSE; + + service = connman_service_lookup_from_network(network); + + __connman_service_indicate_error(service, + CONNMAN_SERVICE_ERROR_DHCP_FAILED); +} +#endif + void connman_network_set_ipv4_method(struct connman_network *network, enum connman_ipconfig_method method) { @@ -1319,9 +1546,16 @@ void connman_network_set_error(struct connman_network *network, case CONNMAN_NETWORK_ERROR_CONNECT_FAIL: set_connect_error(network); break; +#if defined TIZEN_EXT + case CONNMAN_NETWORK_ERROR_DHCP_FAIL: + set_dhcp_error(network); + break; +#endif + case CONNMAN_NETWORK_ERROR_BLOCKED: set_blocked_error(network); break; + } __connman_network_disconnect(network); @@ -1461,13 +1695,21 @@ int __connman_network_connect(struct connman_network *network) network->connecting = true; +#if defined TIZEN_EXT + if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR) +#endif __connman_device_disconnect(network->device); - +#if defined TIZEN_EXT + DBG("ConnMan, Connect Request [%s]", network->name); +#endif err = network->driver->connect(network); if (err < 0) { - if (err == -EINPROGRESS) + if (err == -EINPROGRESS) { +#if defined TIZEN_EXT + if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR) +#endif connman_network_set_associating(network, true); - else + } else network->connecting = false; return err; @@ -1498,7 +1740,9 @@ int __connman_network_disconnect(struct connman_network *network) return -EUNATCH; network->connecting = false; - +#if defined TIZEN_EXT + DBG("ConnMan, Disconnect request"); +#endif if (network->driver->disconnect) err = network->driver->disconnect(network); @@ -1552,12 +1796,38 @@ int __connman_network_clear_ipconfig(struct connman_network *network, return 0; } +#if defined TIZEN_EXT +void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data) +{ + DBG(""); + + struct connman_network *network = user_data; + struct connman_service *service; + struct connman_ipconfig *ipconfig = NULL; + + service = connman_service_lookup_from_network(network); + if (service == NULL) + return; + + ipconfig = __connman_service_get_ipconfig(service, AF_INET6); + if (ipconfig == NULL) + return; + + __connman_ipconfig_set_gateway(ipconfig, gateway); + + return; +} +#endif + int __connman_network_enable_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig) { int r = 0; enum connman_ipconfig_type type; enum connman_ipconfig_method method; +#if defined TIZEN_EXT + struct connman_service *service; +#endif if (!network || !ipconfig) return -EINVAL; @@ -1585,6 +1855,14 @@ int __connman_network_enable_ipconfig(struct connman_network *network, break; case CONNMAN_IPCONFIG_METHOD_AUTO: +#if defined TIZEN_EXT + service = connman_service_lookup_from_network(network); + + if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_CONFIGURATION, + CONNMAN_IPCONFIG_TYPE_IPV6); +#endif autoconf_ipv6_set(network); break; @@ -1661,6 +1939,142 @@ int connman_network_set_ipaddress(struct connman_network *network, return 0; } +#if defined TIZEN_EXT +/* + * Description: Network client requires additional wifi specific info + */ +int connman_network_set_bssid(struct connman_network *network, + const unsigned char *bssid) +{ + int i = 0; + + if (bssid == NULL) + return -EINVAL; + + DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network, + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5]); + + for (;i < WIFI_BSSID_LEN_MAX;i++) + network->wifi.bssid[i] = bssid[i]; + + return 0; +} + +unsigned char *connman_network_get_bssid(struct connman_network *network) +{ + return (unsigned char *)network->wifi.bssid; +} + +int connman_network_set_maxrate(struct connman_network *network, + unsigned int maxrate) +{ +#if !defined TIZEN_EXT + DBG("network %p maxrate %d", network, maxrate); +#endif + + network->wifi.maxrate = maxrate; + + return 0; +} + +unsigned int connman_network_get_maxrate(struct connman_network *network) +{ + return network->wifi.maxrate; +} + +int connman_network_set_enc_mode(struct connman_network *network, + const char *encryption_mode) +{ + if (encryption_mode == NULL) + return -EINVAL; + + DBG("network %p encryption mode %s", network, encryption_mode); + + g_strlcpy(network->wifi.encryption_mode, encryption_mode, + WIFI_ENCYPTION_MODE_LEN_MAX); + + return 0; +} + +const char *connman_network_get_enc_mode(struct connman_network *network) +{ + return (const char *)network->wifi.encryption_mode; +} + +int connman_network_set_rsn_mode(struct connman_network *network, + bool rsn_mode) +{ + network->wifi.rsn_mode = rsn_mode; + + return 0; +} + +int connman_network_set_proxy(struct connman_network *network, + const char *proxies) +{ + struct connman_service *service; + + DBG("network %p proxies %s", network, proxies); + + service = connman_service_lookup_from_network(network); + if (service == NULL) + return -EINVAL; + + __connman_service_set_proxy(service, proxies); + + connman_service_set_proxy_method(service, + CONNMAN_SERVICE_PROXY_METHOD_MANUAL); + + return 0; +} + +int connman_network_set_keymgmt(struct connman_network *network, + unsigned int keymgmt) +{ + if (network == NULL) + return 0; + + network->wifi.keymgmt = keymgmt; + + return 0; +} + +unsigned int connman_network_get_keymgmt(struct connman_network *network) +{ + if (network == NULL) + return 0; + + return network->wifi.keymgmt; +} + +int connman_network_set_disconnect_reason(struct connman_network *network, + int reason_code) +{ + if (network == NULL) + return 0; + + network->wifi.disconnect_reason = reason_code; + + return 0; +} + +int connman_network_get_disconnect_reason(struct connman_network *network) +{ + if (network == NULL) + return 0; + + return network->wifi.disconnect_reason; +} +int connman_network_get_assoc_status_code(struct connman_network *network) +{ + if (network == NULL) + return 0; + + return network->wifi.assoc_status_code; +} +#endif + int connman_network_set_nameservers(struct connman_network *network, const char *nameservers) { @@ -1682,8 +2096,14 @@ int connman_network_set_nameservers(struct connman_network *network, nameservers_array = g_strsplit(nameservers, " ", 0); for (i = 0; nameservers_array[i]; i++) { +#if defined TIZEN_EXT + __connman_service_nameserver_append(service, + nameservers_array[i], false, + CONNMAN_IPCONFIG_TYPE_ALL); +#else __connman_service_nameserver_append(service, nameservers_array[i], false); +#endif } g_strfreev(nameservers_array); @@ -1799,6 +2219,9 @@ int connman_network_set_string(struct connman_network *network, g_free(network->wifi.security); network->wifi.security = g_strdup(value); } else if (g_str_equal(key, "WiFi.Passphrase")) { +#if defined TIZEN_EXT + DBG("ConnMan, %p key %s", network, key); +#endif g_free(network->wifi.passphrase); network->wifi.passphrase = g_strdup(value); } else if (g_str_equal(key, "WiFi.EAP")) { @@ -1869,7 +2292,15 @@ const char *connman_network_get_string(struct connman_network *network, else if (g_str_equal(key, "WiFi.Mode")) return network->wifi.mode; else if (g_str_equal(key, "WiFi.Security")) +#if defined TIZEN_EXT + if (network->wifi.rsn_mode != true || + g_str_equal(network->wifi.security, "ieee8021x")) + return network->wifi.security; + else + return "rsn"; +#else return network->wifi.security; +#endif else if (g_str_equal(key, "WiFi.Passphrase")) return network->wifi.passphrase; else if (g_str_equal(key, "WiFi.EAP")) @@ -1921,6 +2352,12 @@ int connman_network_set_bool(struct connman_network *network, network->wifi.wps = value; else if (g_strcmp0(key, "WiFi.UseWPS") == 0) network->wifi.use_wps = value; +#if defined TIZEN_EXT + else if (g_strcmp0(key, "DefaultInternet") == 0) + network->default_internet = value; + else if (g_strcmp0(key, "WiFi.HS20AP") == 0) + network->wifi.isHS20AP = value; +#endif return -EINVAL; } @@ -1941,6 +2378,12 @@ bool connman_network_get_bool(struct connman_network *network, return network->wifi.wps; else if (g_str_equal(key, "WiFi.UseWPS")) return network->wifi.use_wps; +#if defined TIZEN_EXT + else if (g_str_equal(key, "DefaultInternet")) + return network->default_internet; + else if (g_str_equal(key, "WiFi.HS20AP")) + return network->wifi.isHS20AP; +#endif return false; } @@ -1965,6 +2408,16 @@ int connman_network_set_blob(struct connman_network *network, network->wifi.ssid_len = size; } else network->wifi.ssid_len = 0; +#if defined TIZEN_EXT + } else if (g_str_equal(key, "WiFi.Vsie")){ + g_free(network->wifi.wifi_vsie); + network->wifi.wifi_vsie = g_try_malloc(size); + if (network->wifi.wifi_vsie) { + memcpy(network->wifi.wifi_vsie, data, size); + network->wifi.wifi_vsie_len = size; + } else + network->wifi.wifi_vsie_len = 0; +#endif } else { return -EINVAL; } @@ -1989,6 +2442,15 @@ const void *connman_network_get_blob(struct connman_network *network, return network->wifi.ssid; } +#if defined TIZEN_EXT + if (g_str_equal(key, "WiFi.Vsie")) { + if (size) + *size = network->wifi.wifi_vsie_len; + + return network->wifi.wifi_vsie; + } +#endif + return NULL; } diff --git a/src/notifier.c b/src/notifier.c index 5ba53242..5ba53242 100644..100755 --- a/src/notifier.c +++ b/src/notifier.c diff --git a/src/ntp.c b/src/ntp.c index 0e80c3e5..11512a02 100644..100755 --- a/src/ntp.c +++ b/src/ntp.c @@ -251,8 +251,9 @@ static void decode_msg(void *base, size_t len, struct timeval *tv, double m_delta, org, rec, xmt, dst; double delay, offset; static guint transmit_delay; +#if !defined TIZEN_EXT struct timex tmx = {}; - +#endif if (len < sizeof(*msg)) { connman_error("Invalid response from time server"); return; @@ -341,6 +342,66 @@ static void decode_msg(void *base, size_t len, struct timeval *tv, poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL); +#if defined TIZEN_EXT + //send the dbus message to alram-manager + { +#define TIME_BUS_NAME "org.tizen.alarm.manager" +#define TIME_INTERFACE "org.tizen.alarm.manager" +#define TIME_PATH "/org/tizen/alarm/manager" +#define TIME_METHOD "alarm_set_time_with_propagation_delay" + + struct timespec cur = {0}; + struct timespec req = {0}; + double dtime; + + DBusConnection *connection = NULL; + DBusMessage *msg = NULL, *reply = NULL; + DBusError error; + + dbus_error_init(&error); + + connection = connman_dbus_get_connection(); + if(!connection){ + DBG("dbus connection does not exist"); + return; + } + + clock_gettime(CLOCK_REALTIME, &cur); + dtime = offset + cur.tv_sec + 1.0e-9 * cur.tv_nsec; + cur.tv_sec = (long) dtime; + cur.tv_nsec = (dtime - cur.tv_sec) * 1000000000; + + clock_gettime(CLOCK_REALTIME, &req); + msg = dbus_message_new_method_call(TIME_BUS_NAME, TIME_PATH, + TIME_INTERFACE, TIME_METHOD); + dbus_message_append_args(msg, DBUS_TYPE_UINT32, &(cur.tv_sec), + DBUS_TYPE_UINT32, &(cur.tv_nsec), + DBUS_TYPE_UINT32, &(req.tv_sec), + DBUS_TYPE_UINT32, &(req.tv_nsec), DBUS_TYPE_INVALID); + reply = dbus_connection_send_with_reply_and_block(connection, msg, + DBUS_TIMEOUT_USE_DEFAULT, &error); + if(reply == NULL){ + if(dbus_error_is_set(&error)){ + DBG("%s", error.message); + dbus_error_free(&error); + } + else{ + DBG("Failed to request set time"); + } + dbus_connection_unref(connection); + dbus_message_unref(msg); + return; + } + + dbus_message_unref(msg); + dbus_message_unref(reply); + dbus_connection_unref(connection); + + DBG("%lu cur seconds, %lu cur nsecs, %lu req seconds, %lu req nsecs", + cur.tv_sec, cur.tv_nsec, req.tv_sec, req.tv_nsec); + DBG("setting time"); + } +#else if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) { tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR; tmx.status = STA_PLL; @@ -379,7 +440,8 @@ static void decode_msg(void *base, size_t len, struct timeval *tv, } DBG("interval/delta/delay/drift %fs/%+.3fs/%.3fs/%+ldppm", - LOGTOD(msg->poll), offset, delay, tmx.freq / 65536); + LOGTOD(msg->poll), offset, delay, tmx.freq / 65536); +#endif } static gboolean received_data(GIOChannel *channel, GIOCondition condition, diff --git a/src/peer.c b/src/peer.c index 340cbcc2..340cbcc2 100644..100755 --- a/src/peer.c +++ b/src/peer.c diff --git a/src/peer_service.c b/src/peer_service.c index a457bff7..a457bff7 100644..100755 --- a/src/peer_service.c +++ b/src/peer_service.c diff --git a/src/plugin.c b/src/plugin.c index 7d730582..7d730582 100644..100755 --- a/src/plugin.c +++ b/src/plugin.c diff --git a/src/provider.c b/src/provider.c index 9c71a200..c0d69e49 100644..100755 --- a/src/provider.c +++ b/src/provider.c @@ -243,7 +243,11 @@ static int set_connected(struct connman_provider *provider, } __connman_ipconfig_address_add(ipconfig); +#if defined TIZEN_EXT + __connman_ipconfig_gateway_add(ipconfig, service); +#else __connman_ipconfig_gateway_add(ipconfig); +#endif provider_indicate_state(provider, CONNMAN_SERVICE_STATE_READY); @@ -573,8 +577,14 @@ int connman_provider_set_nameservers(struct connman_provider *provider, return 0; for (i = 0; nameservers[i]; i++) +#if defined TIZEN_EXT + __connman_service_nameserver_append(provider->vpn_service, + nameservers[i], false, + CONNMAN_IPCONFIG_TYPE_ALL); +#else __connman_service_nameserver_append(provider->vpn_service, nameservers[i], false); +#endif return 0; } diff --git a/src/proxy.c b/src/proxy.c index e1bc420a..e1bc420a 100644..100755 --- a/src/proxy.c +++ b/src/proxy.c diff --git a/src/resolver.c b/src/resolver.c index 75ea5ba6..d6c20cdd 100644..100755 --- a/src/resolver.c +++ b/src/resolver.c @@ -35,9 +35,6 @@ #include "connman.h" -#define RESOLV_CONF_STATEDIR STATEDIR"/resolv.conf" -#define RESOLV_CONF_ETC "/etc/resolv.conf" - #define RESOLVER_FLAG_PUBLIC (1 << 0) /* @@ -133,19 +130,11 @@ static int resolvfile_export(void) old_umask = umask(022); - fd = open(RESOLV_CONF_STATEDIR, O_RDWR | O_CREAT | O_CLOEXEC, + fd = open("/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { - connman_warn_once("Cannot create "RESOLV_CONF_STATEDIR" " - "falling back to "RESOLV_CONF_ETC); - - fd = open(RESOLV_CONF_ETC, O_RDWR | O_CREAT | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - - if (fd < 0) { - err = -errno; - goto done; - } + err = -errno; + goto done; } if (ftruncate(fd, 0) < 0) { @@ -312,8 +301,14 @@ static gboolean resolver_expire_cb(gpointer user_data) struct connman_service *service; service = __connman_service_lookup_from_index(entry->index); if (service) +#if defined TIZEN_EXT + __connman_service_nameserver_remove(service, + entry->server, true, + CONNMAN_IPCONFIG_TYPE_ALL); +#else __connman_service_nameserver_remove(service, entry->server, true); +#endif } remove_entries(list); @@ -367,6 +362,11 @@ static int append_resolver(int index, const char *domain, if (!server && !domain) return -EINVAL; +#ifdef TIZEN_EXT + if (g_strcmp0(server, "0.0.0.0") == 0) + return -EINVAL; +#endif + entry = g_try_new0(struct entry_data, 1); if (!entry) return -ENOMEM; @@ -409,8 +409,14 @@ static int append_resolver(int index, const char *domain, struct connman_service *service; service = __connman_service_lookup_from_index(entry->index); if (service) +#if defined TIZEN_EXT + __connman_service_nameserver_append(service, + server, true, + CONNMAN_IPCONFIG_TYPE_ALL); +#else __connman_service_nameserver_append(service, server, true); +#endif } return 0; diff --git a/src/rfkill.c b/src/rfkill.c index d9bed4d2..fce9d720 100644..100755 --- a/src/rfkill.c +++ b/src/rfkill.c @@ -73,6 +73,7 @@ static enum connman_service_type convert_type(uint8_t type) return CONNMAN_SERVICE_TYPE_UNKNOWN; } +#if !defined TIZEN_EXT static enum rfkill_type convert_service_type(enum connman_service_type type) { switch (type) { @@ -95,6 +96,7 @@ static enum rfkill_type convert_service_type(enum connman_service_type type) return NUM_RFKILL_TYPES; } +#endif static GIOStatus rfkill_process(GIOChannel *chan) { @@ -157,13 +159,20 @@ static guint watch = 0; int __connman_rfkill_block(enum connman_service_type type, bool block) { +#if !defined TIZEN_EXT uint8_t rfkill_type; struct rfkill_event event; ssize_t len; int fd, err = 0; +#endif DBG("type %d block %d", type, block); +#if defined TIZEN_EXT + DBG("try to set rfkill block %d, but it's not permitted", block); + + return 0; +#else rfkill_type = convert_service_type(type); if (rfkill_type == NUM_RFKILL_TYPES) return -EINVAL; @@ -186,6 +195,7 @@ int __connman_rfkill_block(enum connman_service_type type, bool block) close(fd); return err; +#endif } int __connman_rfkill_init(void) diff --git a/src/rtnl.c b/src/rtnl.c index a094e257..35ae0a96 100644..100755 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -46,6 +46,12 @@ #define ARPHDR_PHONET_PIPE (821) #endif +#if defined TIZEN_EXT +#ifndef ARPHDR_RMNET +#define ARPHDR_RMNET (530) +#endif +#endif + #define print(arg...) do { if (0) connman_info(arg); } while (0) //#define print(arg...) connman_info(arg) @@ -94,6 +100,7 @@ static bool ether_blacklisted(const char *name) return false; } +#if !defined TIZEN_EXT static bool wext_interface(char *ifname) { struct iwreq wrq; @@ -115,6 +122,30 @@ static bool wext_interface(char *ifname) return true; } +#endif + +#if defined TIZEN_EXT +static bool __connman_rtnl_is_cellular_device(const char *name) +{ + char **pattern; + char **cellular_interfaces; + + cellular_interfaces = + connman_setting_get_string_list( + "NetworkCellularInterfaceList"); + if (!cellular_interfaces) + return false; + + for (pattern = cellular_interfaces; *pattern; pattern++) { + if (g_str_has_prefix(name, *pattern)) { + DBG("Cellular interface: %s", name); + return true; + } + } + + return false; +} +#endif static void read_uevent(struct interface_data *interface) { @@ -124,6 +155,14 @@ static void read_uevent(struct interface_data *interface) name = connman_inet_ifname(interface->index); +#if defined TIZEN_EXT + if (__connman_rtnl_is_cellular_device(name)) { + interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR; + interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR; + return; + } +#endif + if (ether_blacklisted(name)) { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN; @@ -187,6 +226,8 @@ static void read_uevent(struct interface_data *interface) if (found_devtype) goto out; +#if !defined TIZEN_EXT + /* TIZEN does not use old wext interface */ /* We haven't got a DEVTYPE, let's check if it's a wireless device */ if (wext_interface(name)) { interface->service_type = CONNMAN_SERVICE_TYPE_WIFI; @@ -194,6 +235,7 @@ static void read_uevent(struct interface_data *interface) connman_error("%s runs an unsupported 802.11 driver", name); } +#endif out: g_free(name); @@ -419,6 +461,14 @@ static void process_newlink(unsigned short type, int index, unsigned flags, if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats)) return; +#if defined TIZEN_EXT + /* Do not accept Wi-Fi P2P interface */ + if (g_strrstr(ifname, "p2p") != NULL) { + DBG("Newlink event for Wi-Fi P2P interface ignored"); + return; + } +#endif + snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x", address.ether_addr_octet[0], address.ether_addr_octet[1], @@ -441,12 +491,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags, return; } +#ifdef TIZEN_EXT + if (TIZEN_TV_EXT && g_strcmp0(ident, "eeeeeeeeeeee") == 0) { + DBG("Newlink event with Dummy MAC. Ignored!"); + return; + } +#endif + switch (type) { case ARPHRD_ETHER: case ARPHRD_LOOPBACK: case ARPHDR_PHONET_PIPE: case ARPHRD_PPP: case ARPHRD_NONE: +#if defined TIZEN_EXT +/* + * Description: ARPHDR_RMNET for QC modem using QMI + */ + case ARPHDR_RMNET: +#endif __connman_ipconfig_newlink(index, type, flags, str, mtu, &stats); break; @@ -471,6 +534,25 @@ static void process_newlink(unsigned short type, int index, unsigned flags, if (type == ARPHRD_ETHER) read_uevent(interface); +#if defined TIZEN_EXT + if (type == ARPHRD_PPP || type == ARPHDR_RMNET) + read_uevent(interface); + + } else if (g_strcmp0(interface->ident, ident) != 0) { + /* If an original address is built-in physical device, + * it's hardly get an address at a initial creation + */ + __connman_technology_remove_interface(interface->service_type, + interface->index, interface->ident); + + g_free(interface->ident); + interface->ident = g_strdup(ident); + + __connman_technology_add_interface(interface->service_type, + interface->index, interface->ident); + + interface = NULL; +#endif } else if (type == ARPHRD_ETHER && interface->device_type == CONNMAN_DEVICE_TYPE_UNKNOWN) read_uevent(interface); else @@ -534,6 +616,13 @@ static void process_dellink(unsigned short type, int index, unsigned flags, case ARPHDR_PHONET_PIPE: case ARPHRD_PPP: case ARPHRD_NONE: +#if defined TIZEN_EXT + /* + * Description: SLP requires ARPHRD_PPP for PPP type device + * ARPHDR_RMNET for QC modem using QMI + */ + case ARPHDR_RMNET: +#endif __connman_ipconfig_dellink(index, &stats); break; } @@ -1229,6 +1318,37 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) if (index < 0) return; +#if defined TIZEN_EXT + struct connman_service *service; + enum connman_service_state state; + enum connman_dnsconfig_method ipv6_dns_method; + + service = __connman_service_lookup_from_index(index); + if (!service) { + DBG("Invalid service"); + return; + } + + DBG("service: %p index: %d\n", service, index); + + if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) { + state = __connman_service_ipconfig_get_state(service, CONNMAN_IPCONFIG_TYPE_IPV6); + if (state != CONNMAN_SERVICE_STATE_ASSOCIATION && + state != CONNMAN_SERVICE_STATE_CONFIGURATION && + state != CONNMAN_SERVICE_STATE_READY && + state != CONNMAN_SERVICE_STATE_ONLINE) { + DBG("Service state[%d] is not connecting/connected", state); + return; + } + } + + ipv6_dns_method = connman_service_get_ipv6_dns_method(service); + if (ipv6_dns_method != CONNMAN_DNSCONFIG_METHOD_DHCP) { + DBG("IPv6 DNS method is not Auto ignore RA!!! [DNS method: %d]", ipv6_dns_method); + return; + } +#endif + for (opt = (void *)&msg[1]; msglen > 0; msglen -= opt->nd_opt_len * 8, @@ -1239,16 +1359,29 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */ char buf[40]; +#if defined TIZEN_EXT + struct connman_service *service; + service = __connman_service_lookup_from_index(index); + DBG("service: %p\n",service); +#endif servers = rtnl_nd_opt_rdnss(opt, &lifetime, - &nr_servers); + &nr_servers); for (i = 0; i < nr_servers; i++) { if (!inet_ntop(AF_INET6, servers + i, buf, - sizeof(buf))) + sizeof(buf))) continue; +#if defined TIZEN_EXT + __connman_service_nameserver_remove(service, + buf, false, + CONNMAN_IPCONFIG_TYPE_IPV6); + __connman_service_nameserver_append(service, + buf, false, + CONNMAN_IPCONFIG_TYPE_IPV6); +#endif connman_resolver_append_lifetime(index, - NULL, buf, lifetime); + NULL, buf, lifetime); } } else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */ diff --git a/src/service.c b/src/service.c index 02cd51f2..d0543ae5 100644..100755 --- a/src/service.c +++ b/src/service.c @@ -30,6 +30,8 @@ #include <gdbus.h> #include <ctype.h> #include <stdint.h> +#include <pwd.h> +#include <utmpx.h> #include <connman/storage.h> #include <connman/setting.h> @@ -39,6 +41,13 @@ #define CONNECT_TIMEOUT 120 +#define USER_ROOT 0 +#define USER_NONE (uid_t)-1 + +#if defined TIZEN_EXT +#define WIFI_BSSID_STR_LEN 18 +#endif + static DBusConnection *connection = NULL; static GList *service_list = NULL; @@ -49,6 +58,10 @@ static unsigned int vpn_autoconnect_timeout = 0; static struct connman_service *current_default = NULL; static bool services_dirty = false; +#if defined TIZEN_EXT +static bool auto_connect_mode = TRUE; +#endif + struct connman_stats { bool valid; bool enabled; @@ -63,6 +76,11 @@ struct connman_stats_counter { struct connman_stats stats_roaming; }; +struct connman_service_user { + uid_t favorite_user; + uid_t current_user; +}; + struct connman_service { int refcount; char *identifier; @@ -85,6 +103,8 @@ struct connman_service { char *name; char *passphrase; bool roaming; + bool request_passphrase_input; + struct connman_service_user user; struct connman_ipconfig *ipconfig_ipv4; struct connman_ipconfig *ipconfig_ipv6; struct connman_network *network; @@ -130,6 +150,28 @@ struct connman_service { bool hidden_service; char *config_file; char *config_entry; +#if defined TIZEN_EXT + /* + * Description: TIZEN implements system global connection management. + * It's only for PDP (cellular) bearer. Wi-Fi is managed + * by ConnMan automatically. Reference count can help to + * manage open/close connection requests by each application. + */ + int user_pdn_connection_refcount; + bool storage_reload; + /* + * Description: In case of EAP security type, + * user can select the keymgmt type for roaming(802.11r). + * - FT, CCKM, OKC, ... + */ + char *keymgmt_type; + int disconnect_reason; + int assoc_status_code; +#endif +#ifdef TIZEN_EXT + enum connman_dnsconfig_method dns_config_method_ipv4; + enum connman_dnsconfig_method dns_config_method_ipv6; +#endif }; static bool allow_property_changed(struct connman_service *service); @@ -145,6 +187,50 @@ struct find_data { struct connman_service *service; }; +#if defined TIZEN_EXT +/* + * Public APIs to use user_pdn_connection_refcount + */ +void connman_service_user_pdn_connection_ref(struct connman_service *service) +{ + __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1); + + DBG("User made PDN connection referenced: %d", + service->user_pdn_connection_refcount); +} + +gboolean connman_service_user_pdn_connection_unref_and_test( + struct connman_service *service) +{ + __sync_synchronize(); + + DBG("User made PDN connection referenced: %d, which will be decreased", + service->user_pdn_connection_refcount); + + if (service->user_pdn_connection_refcount < 1) + return TRUE; + + if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1) == 0) + return TRUE; + + return FALSE; +} + +gboolean connman_service_is_no_ref_user_pdn_connection( + struct connman_service *cellular) +{ + if (cellular == NULL) + return TRUE; + + __sync_synchronize(); + if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR && + cellular->user_pdn_connection_refcount == 0) + return TRUE; + + return FALSE; +} +#endif + static void compare_path(gpointer value, gpointer user_data) { struct connman_service *service = value; @@ -253,6 +339,10 @@ enum connman_service_security __connman_service_string2security(const char *str) return CONNMAN_SERVICE_SECURITY_NONE; if (!strcmp(str, "wep")) return CONNMAN_SERVICE_SECURITY_WEP; +#if defined TIZEN_EXT + if (!strcmp(str, "rsn")) + return CONNMAN_SERVICE_SECURITY_RSN; +#endif return CONNMAN_SERVICE_SECURITY_UNKNOWN; } @@ -268,8 +358,14 @@ static const char *security2string(enum connman_service_security security) return "wep"; case CONNMAN_SERVICE_SECURITY_PSK: case CONNMAN_SERVICE_SECURITY_WPA: +#if defined TIZEN_EXT + return "psk"; + case CONNMAN_SERVICE_SECURITY_RSN: + return "rsn"; +#else case CONNMAN_SERVICE_SECURITY_RSN: return "psk"; +#endif case CONNMAN_SERVICE_SECURITY_8021X: return "ieee8021x"; } @@ -355,6 +451,116 @@ static enum connman_service_proxy_method string2proxymethod(const char *method) return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN; } +#ifdef TIZEN_EXT +static const char *__connman_dnsconfig_method2string(enum connman_dnsconfig_method method) +{ + switch (method) { + case CONNMAN_DNSCONFIG_METHOD_UNKNOWN: + return "unknown"; + case CONNMAN_DNSCONFIG_METHOD_MANUAL: + return "manual"; + case CONNMAN_DNSCONFIG_METHOD_DHCP: + return "dhcp"; + } + + return NULL; +} + +static enum connman_dnsconfig_method __connman_dnsconfig_string2method( + const char *method) +{ + if (g_strcmp0(method, "manual") == 0) + return CONNMAN_DNSCONFIG_METHOD_MANUAL; + else if (g_strcmp0(method, "dhcp") == 0) + return CONNMAN_DNSCONFIG_METHOD_DHCP; + else + return CONNMAN_DNSCONFIG_METHOD_UNKNOWN; +} +#endif + +static bool +connman_service_is_user_allowed(struct connman_service *service, uid_t uid) +{ + uid_t favorite_user = service->user.favorite_user; + uid_t current_user = uid; + + DBG("Service favorite UID: %d, current UID: %d", favorite_user, current_user); + if (favorite_user == USER_NONE || current_user == USER_ROOT) + return true; + + if (favorite_user != current_user || current_user == USER_NONE) { + DBG("Current user is not a favorite user to this service!"); + return false; + } + + return true; +} + +#if !defined TIZEN_EXT +static GList *connman_service_get_login_users() +{ + struct utmpx *utmp; + struct passwd *pwd; + GList *user_list = NULL; + + setutxent(); + + while ((utmp = getutxent()) != NULL) { + DBG("User Name: %s", utmp->ut_user); + + pwd = getpwnam(utmp->ut_user); + if (pwd) { + if (!g_list_find(user_list, GUINT_TO_POINTER(pwd->pw_uid))) + user_list = g_list_append(user_list, + GUINT_TO_POINTER(pwd->pw_uid)); + + DBG("User Name: %s, UID: %d", utmp->ut_user, pwd->pw_uid); + } + } + + endutxent(); + + return user_list; +} +#endif + +static bool is_service_owner_user_login(struct connman_service *service) +{ +#if defined TIZEN_EXT + return true; +#else + GList *list, *user_list; + bool ret = false; + + /* Here we only care about wifi service */ + if (service->type != CONNMAN_SERVICE_TYPE_WIFI) + return true; + + DBG("service favorite user id is: %d", service->user.favorite_user); + + user_list = connman_service_get_login_users(); + if (user_list == NULL) { + DBG("Can not get any logged in user info."); + return true; + } + + for (list = user_list; list; list = list->next) { + uid_t uid = GPOINTER_TO_UINT(list->data); + + DBG("login user id is %d", uid); + + if (service->user.favorite_user == uid) { + ret = true; + break; + } + } + + g_list_free(user_list); + + return ret; +#endif +} + static void set_split_routing(struct connman_service *service, bool value) { if (service->type != CONNMAN_SERVICE_TYPE_VPN) @@ -418,6 +624,25 @@ int __connman_service_load_modifiable(struct connman_service *service) return 0; } +static int service_load_passphrase(struct connman_service *service) +{ + GKeyFile *keyfile; + gchar *str; + + keyfile = connman_storage_load_service(service->identifier); + if (!keyfile) + return -EIO; + + str = g_key_file_get_string(keyfile, + service->identifier, "Passphrase", NULL); + if (str) + service->passphrase = str; + + g_key_file_free(keyfile); + + return 0; +} + static int service_load(struct connman_service *service) { GKeyFile *keyfile; @@ -552,6 +777,18 @@ static int service_load(struct connman_service *service) service->nameservers_config = NULL; } +#ifdef TIZEN_EXT + char *dns_method; + + dns_method = g_key_file_get_string(keyfile, service->identifier, + "Nameservers.IPv4method", NULL); + service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method); + + dns_method = g_key_file_get_string(keyfile, service->identifier, + "Nameservers.IPv6method", NULL); + service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method); +#endif + service->timeservers_config = g_key_file_get_string_list(keyfile, service->identifier, "Timeservers", &length, NULL); if (service->timeservers_config && length == 0) { @@ -597,6 +834,63 @@ static int service_load(struct connman_service *service) service->hidden_service = g_key_file_get_boolean(keyfile, service->identifier, "Hidden", NULL); +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && + service->security == CONNMAN_SERVICE_SECURITY_8021X) { + str = g_key_file_get_string(keyfile, + service->identifier, "EAP", NULL); + if (str != NULL) { + g_free(service->eap); + service->eap = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "Phase2", NULL); + if (str != NULL) { + g_free(service->phase2); + service->phase2 = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "Identity", NULL); + if (str != NULL) { + g_free(service->identity); + service->identity = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "CACertFile", NULL); + if (str != NULL) { + g_free(service->ca_cert_file); + service->ca_cert_file = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "ClientCertFile", NULL); + if (str != NULL) { + g_free(service->client_cert_file); + service->client_cert_file = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "PrivateKeyFile", NULL); + if (str != NULL) { + g_free(service->private_key_file); + service->private_key_file = str; + } + + str = g_key_file_get_string(keyfile, + service->identifier, "PrivateKeyPassphrase", NULL); + if (str != NULL) { + g_free(service->private_key_passphrase); + service->private_key_passphrase = str; + } + } +#endif + + if (g_key_file_has_key(keyfile, service->identifier, "UID", NULL)) + service->user.favorite_user = g_key_file_get_integer(keyfile, + service->identifier, "UID", NULL); done: g_key_file_free(keyfile); @@ -642,6 +936,13 @@ static int service_save(struct connman_service *service) const unsigned char *ssid; unsigned int ssid_len = 0; + if (service->user.favorite_user == USER_NONE) + g_key_file_remove_key(keyfile, service->identifier, + "UID", NULL); + else + g_key_file_set_integer(keyfile, service->identifier, + "UID", service->user.favorite_user); + ssid = connman_network_get_blob(service->network, "WiFi.SSID", &ssid_len); @@ -697,12 +998,14 @@ static int service_save(struct connman_service *service) g_free(str); } - if (service->passphrase && strlen(service->passphrase) > 0) - g_key_file_set_string(keyfile, service->identifier, + if (service->user.current_user == service->user.favorite_user) { + if (service->passphrase && strlen(service->passphrase) > 0) + g_key_file_set_string(keyfile, service->identifier, "Passphrase", service->passphrase); - else - g_key_file_remove_key(keyfile, service->identifier, - "Passphrase", NULL); + else + g_key_file_remove_key(keyfile, service->identifier, + "Passphrase", NULL); + } if (service->ipconfig_ipv4) __connman_ipconfig_save(service->ipconfig_ipv4, keyfile, @@ -722,6 +1025,28 @@ static int service_save(struct connman_service *service) g_key_file_remove_key(keyfile, service->identifier, "Nameservers", NULL); +#if defined TIZEN_EXT + if(service->dns_config_method_ipv4 != 0) { + const char *method; + method = __connman_dnsconfig_method2string( + service->dns_config_method_ipv4); + g_key_file_set_string(keyfile, service->identifier, + "Nameservers.IPv4method", method); + } else + g_key_file_remove_key(keyfile, service->identifier, + "Nameservers.IPv4method", NULL); + + if(service->dns_config_method_ipv6 != 0) { + const char *method; + method = __connman_dnsconfig_method2string( + service->dns_config_method_ipv6); + g_key_file_set_string(keyfile, service->identifier, + "Nameservers.IPv6method", method); + } else + g_key_file_remove_key(keyfile, service->identifier, + "Nameservers.IPv6method", NULL); +#endif + if (service->timeservers_config) { guint len = g_strv_length(service->timeservers_config); @@ -787,6 +1112,60 @@ static int service_save(struct connman_service *service) g_key_file_set_string(keyfile, service->identifier, "Config.ident", service->config_entry); +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && + service->security == CONNMAN_SERVICE_SECURITY_8021X) { + if (service->eap != NULL && strlen(service->eap) > 0) + g_key_file_set_string(keyfile, service->identifier, + "EAP", service->eap); + else + g_key_file_remove_key(keyfile, service->identifier, + "EAP", NULL); + + if (service->phase2 != NULL && strlen(service->phase2) > 0) + g_key_file_set_string(keyfile, service->identifier, + "Phase2", service->phase2); + else + g_key_file_remove_key(keyfile, service->identifier, + "Phase2", NULL); + + if (service->identity != NULL && strlen(service->identity) > 0) + g_key_file_set_string(keyfile, service->identifier, + "Identity", service->identity); + else + g_key_file_remove_key(keyfile, service->identifier, + "Identity", NULL); + + if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0) + g_key_file_set_string(keyfile, service->identifier, + "CACertFile", service->ca_cert_file); + else + g_key_file_remove_key(keyfile, service->identifier, + "CACertFile", NULL); + + if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0) + g_key_file_set_string(keyfile, service->identifier, + "ClientCertFile", service->client_cert_file); + else + g_key_file_remove_key(keyfile, service->identifier, + "ClientCertFile", NULL); + + if (service->private_key_file != NULL && strlen(service->private_key_file) > 0) + g_key_file_set_string(keyfile, service->identifier, + "PrivateKeyFile", service->private_key_file); + else + g_key_file_remove_key(keyfile, service->identifier, + "PrivateKeyFile", NULL); + + if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0) + g_key_file_set_string(keyfile, service->identifier, + "PrivateKeyPassphrase", service->private_key_passphrase); + else + g_key_file_remove_key(keyfile, service->identifier, + "PrivateKeyPassphrase", NULL); + } +#endif + done: __connman_storage_save_service(keyfile, service->identifier); @@ -1053,6 +1432,9 @@ static int nameserver_add(struct connman_service *service, if (index < 0) return -ENXIO; +#if defined TIZEN_EXT + DBG("Resolver append nameserver: %s", nameserver); +#endif ret = connman_resolver_append(index, NULL, nameserver); if (ret >= 0) nameservers_changed(service); @@ -1067,14 +1449,115 @@ static int nameserver_add_all(struct connman_service *service, if (service->nameservers_config) { while (service->nameservers_config[i]) { +#if defined TIZEN_EXT + DBG("type %d add service->nameservers_config[%d]:%s",type, + i, service->nameservers_config[i]); + if(strncmp(service->nameservers_config[i], "::", 2) == 0) { + DBG("Invalid nameserver"); + i++; + continue; + } + + switch(type) { + case CONNMAN_IPCONFIG_TYPE_IPV4: + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET && + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_MANUAL) { + nameserver_add(service, type, + service->nameservers_config[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_IPV6: + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET6 && + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_MANUAL) { + nameserver_add(service, type, + service->nameservers_config[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_ALL: + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET && + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_MANUAL) { + nameserver_add(service, type, + service->nameservers_config[i]); + } + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET6 && + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_MANUAL) { + nameserver_add(service, type, + service->nameservers_config[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing"); + break; + default: + DBG("default case do nothing"); + break; + } +#else nameserver_add(service, type, service->nameservers_config[i]); +#endif i++; } } else if (service->nameservers) { while (service->nameservers[i]) { +#if defined TIZEN_EXT + DBG("type %d service->nameservers[%d]: %s",type, + i, service->nameservers[i]); + + switch(type) { + case CONNMAN_IPCONFIG_TYPE_IPV4: + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET && + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + nameserver_add(service, type, + service->nameservers[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_IPV6: + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET6 && + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + nameserver_add(service, type, + service->nameservers[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_ALL: + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET && + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + nameserver_add(service, type, + service->nameservers[i]); + } + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET6 && + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + nameserver_add(service, type, + service->nameservers[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing"); + break; + default: + DBG("default case do nothing"); + break; + } +#else nameserver_add(service, type, service->nameservers[i]); +#endif i++; } } @@ -1100,6 +1583,9 @@ static int nameserver_remove(struct connman_service *service, if (index < 0) return -ENXIO; +#if defined TIZEN_EXT + DBG("Resolver remove nameserver: %s", nameserver); +#endif ret = connman_resolver_remove(index, NULL, nameserver); if (ret >= 0) nameservers_changed(service); @@ -1110,6 +1596,15 @@ static int nameserver_remove(struct connman_service *service, static int nameserver_remove_all(struct connman_service *service, enum connman_ipconfig_type type) { +#if defined TIZEN_EXT + /** + * Skip this function if there is any connected profiles + * that use same interface + */ + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR && + __connman_service_get_connected_count_of_iface(service) > 0) + return 0; +#endif int index, i = 0; index = __connman_service_get_index(service); @@ -1117,15 +1612,124 @@ static int nameserver_remove_all(struct connman_service *service, return -ENXIO; while (service->nameservers_config && service->nameservers_config[i]) { - +#if defined TIZEN_EXT + DBG("type %d Remove service->nameservers_config[%d]: %s", + type, i, service->nameservers_config[i]); + switch(type) { + case CONNMAN_IPCONFIG_TYPE_IPV4: + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET && + (service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP || + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_MANUAL)) { + nameserver_remove(service, type, + service->nameservers_config[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_IPV6: + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET6 && + (service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP || + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_MANUAL)) { + nameserver_remove(service, type, + service->nameservers_config[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_ALL: + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET && + (service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP || + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_MANUAL)) { + nameserver_remove(service, type, + service->nameservers_config[i]); + } + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET6 && + (service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP || + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_MANUAL)) { + nameserver_remove(service, type, + service->nameservers_config[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing"); + break; + default: + DBG("default case do nothing"); + break; + } +#else nameserver_remove(service, type, service->nameservers_config[i]); +#endif i++; } i = 0; while (service->nameservers && service->nameservers[i]) { +#if defined TIZEN_EXT + DBG("type %d Remove service->nameservers[%d]: %s",type, i, + service->nameservers[i]); + switch(type) { + case CONNMAN_IPCONFIG_TYPE_IPV4: + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET && + (service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_MANUAL || + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP)) { + nameserver_remove(service, type, + service->nameservers[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_IPV6: + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET6 && + (service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_MANUAL || + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP)) { + nameserver_remove(service, type, + service->nameservers[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_ALL: + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET && + (service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_MANUAL || + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP)) { + nameserver_remove(service, type, + service->nameservers[i]); + } + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET6 && + (service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_MANUAL || + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP)) { + nameserver_remove(service, type, + service->nameservers[i]); + } + break; + case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing"); + break; + default: + DBG("default case do nothing"); + break; + } +#else nameserver_remove(service, type, service->nameservers[i]); +#endif i++; } @@ -1139,13 +1743,19 @@ static int nameserver_remove_all(struct connman_service *service, * inserted to resolver via netlink message (see rtnl.c:rtnl_newnduseropt() * for details) and not through service.c */ +#if defined TIZEN_EXT +int __connman_service_nameserver_append(struct connman_service *service, + const char *nameserver, bool is_auto, + enum connman_ipconfig_type type) +#else int __connman_service_nameserver_append(struct connman_service *service, const char *nameserver, bool is_auto) +#endif { char **nameservers; int len, i; - DBG("service %p nameserver %s auto %d", service, nameserver, is_auto); + DBG("service %p nameserver %s auto %d", service, nameserver, is_auto); if (!nameserver) return -EINVAL; @@ -1156,8 +1766,15 @@ int __connman_service_nameserver_append(struct connman_service *service, nameservers = service->nameservers; for (i = 0; nameservers && nameservers[i]; i++) +#if defined TIZEN_EXT + { + DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver); +#endif if (g_strcmp0(nameservers[i], nameserver) == 0) return -EEXIST; +#if defined TIZEN_EXT + } +#endif if (nameservers) { len = g_strv_length(nameservers); @@ -1173,6 +1790,16 @@ int __connman_service_nameserver_append(struct connman_service *service, nameservers[len] = g_strdup(nameserver); nameservers[len + 1] = NULL; +#ifdef TIZEN_EXT + if(type == CONNMAN_IPCONFIG_TYPE_IPV4 && + service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN) + service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP; + + if(type == CONNMAN_IPCONFIG_TYPE_IPV6 && + service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN) + service->dns_config_method_ipv6 = CONNMAN_DNSCONFIG_METHOD_DHCP; +#endif + if (is_auto) { service->nameservers_auto = nameservers; } else { @@ -1187,8 +1814,14 @@ int __connman_service_nameserver_append(struct connman_service *service, return 0; } +#if defined TIZEN_EXT +int __connman_service_nameserver_remove(struct connman_service *service, + const char *nameserver, bool is_auto, + enum connman_ipconfig_type type) +#else int __connman_service_nameserver_remove(struct connman_service *service, const char *nameserver, bool is_auto) +#endif { char **servers, **nameservers; bool found = false; @@ -1246,8 +1879,14 @@ set_servers: service->nameservers_auto = nameservers; } else { service->nameservers = nameservers; +#if defined TIZEN_EXT + DBG("nameserver remove ip_type: %d", type); + nameserver_remove(service, type, + nameserver); +#else nameserver_remove(service, CONNMAN_IPCONFIG_TYPE_ALL, nameserver); +#endif } return 0; @@ -1473,6 +2112,71 @@ static void reset_stats(struct connman_service *service) g_timer_reset(service->stats_roaming.timer); } +#if defined TIZEN_EXT +static gboolean __connman_service_is_internet_profile( + struct connman_service *cellular) +{ + const char internet_suffix[] = "_1"; + + DBG("Service path: %s", cellular->path); + + if (g_str_has_suffix(cellular->path, internet_suffix) == TRUE) + return TRUE; + + return FALSE; +} + +static gboolean __connman_service_is_tethering_profile( + struct connman_service *cellular) +{ + const char tethering_suffix[] = "_5"; + + DBG("Service path: %s", cellular->path); + + if (g_str_has_suffix(cellular->path, tethering_suffix) == TRUE) + return TRUE; + + return FALSE; +} + +struct connman_service *connman_service_get_default_connection(void) +{ + GList *list; + struct connman_service *service; + struct connman_service *default_service = NULL; + + for (list = service_list; list; list = list->next) { + service = list->data; + + DBG("service: %p %s %s %s", service, service->name, + state2string(service->state), + __connman_service_type2string(service->type)); + + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && + is_connected(service->state) == TRUE) { + return service; + } else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR && + __connman_service_is_internet_profile(service) == TRUE) { + if (default_service == NULL) + default_service = service; + else if (is_connected(service->state) == TRUE && + is_connected(default_service->state) == FALSE) + default_service = service; + } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET && + is_connected(service->state) == TRUE) { + if (default_service == NULL) + default_service = service; + } else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH && + is_connected(service->state) == TRUE) { + if (default_service == NULL) + default_service = service; + } + } + + return default_service; +} +#endif + struct connman_service *__connman_service_get_default(void) { struct connman_service *service; @@ -1511,9 +2215,15 @@ static void default_changed(void) current_default ? current_default->identifier : ""); DBG("new default %p %s", service, service ? service->identifier : ""); +#if defined TIZEN_EXT + current_default = service; + + __connman_service_timeserver_changed(service, NULL); +#else __connman_service_timeserver_changed(current_default, NULL); current_default = service; +#endif if (service) { if (service->hostname && @@ -1537,9 +2247,13 @@ static void state_changed(struct connman_service *service) if (!str) return; +#if !defined TIZEN_EXT if (!allow_property_changed(service)) return; - +#endif +#if defined TIZEN_EXT + DBG(" %s, %s", str, service->path); +#endif connman_dbus_property_changed_basic(service->path, CONNMAN_SERVICE_INTERFACE, "State", DBUS_TYPE_STRING, &str); @@ -1726,20 +2440,143 @@ static void append_nameservers(DBusMessageIter *iter, } } +#if defined TIZEN_EXT +static void append_nameserver_manual(DBusMessageIter *iter, + struct connman_service *service, const char *server) +{ + bool available = true; + + if (service) + available = nameserver_available(service, + CONNMAN_IPCONFIG_TYPE_ALL, server); + + if (available) + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &server); +} + +static void append_nameserver_dhcp(DBusMessageIter *iter, + struct connman_service *service, const char *server) +{ + bool available = true; + + if (service) + available = nameserver_available(service, + CONNMAN_IPCONFIG_TYPE_ALL, server); + + if (available) + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &server); +} +#endif + static void append_dns(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; +#if defined TIZEN_EXT + int i; +#endif if (!is_connected(service->state)) return; +#ifdef TIZEN_EXT + const char *str; + + str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4); + if(str != NULL) { + char *str1 = g_strdup_printf("ipv4.%s", str); + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &str1); + g_free(str1); + } + + str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6); + if(str != NULL) { + char *str1 = g_strdup_printf("ipv6.%s", str); + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &str1); + g_free(str1); + } +#endif + if (service->nameservers_config) { +#if defined TIZEN_EXT + i = 0; + while (service->nameservers_config[i]) { + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET && + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_MANUAL) { + append_nameserver_manual(iter, service, + service->nameservers_config[i]); + } + + if (connman_inet_check_ipaddress( + service->nameservers_config[i]) == AF_INET6 && + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_MANUAL) { + append_nameserver_manual(iter, service, + service->nameservers_config[i]); + } + i++; + } + /* In case of mixed DNS Config Type one of IPv4/IPv6 can be + * dynamic while other is static so try to append the DNS + * Address which is dynamic also */ + if (service->nameservers != NULL) { + i = 0; + while (service->nameservers[i]) { + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET && + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + append_nameserver_dhcp(iter, service, + service->nameservers[i]); + } + + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET6 && + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + append_nameserver_dhcp(iter, service, + service->nameservers[i]); + } + i++; + } + } +#else append_nameservers(iter, service, service->nameservers_config); +#endif return; } else { if (service->nameservers) +#if defined TIZEN_EXT + { + i = 0; + while (service->nameservers[i]) { + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET && + service->dns_config_method_ipv4 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + append_nameserver_dhcp(iter, service, + service->nameservers[i]); + } + + if (connman_inet_check_ipaddress( + service->nameservers[i]) == AF_INET6 && + service->dns_config_method_ipv6 == + CONNMAN_DNSCONFIG_METHOD_DHCP) { + append_nameserver_dhcp(iter, service, + service->nameservers[i]); + } + i++; + } + } +#else append_nameservers(iter, service, service->nameservers); +#endif if (service->nameservers_auto) append_nameservers(iter, service, @@ -1761,10 +2598,46 @@ static void append_dnsconfig(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; +#ifdef TIZEN_EXT + /* Append DNS Config Type */ + const char *str; + str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4); + if(str != NULL) { + char *str1 = g_strdup_printf("ipv4.%s", str); + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &str1); + g_free(str1); + } + + str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6); + if(str != NULL) { + char *str1 = g_strdup_printf("ipv6.%s", str); + dbus_message_iter_append_basic(iter, + DBUS_TYPE_STRING, &str1); + g_free(str1); + } +#endif + if (!service->nameservers_config) return; +#if defined TIZEN_EXT + int i = 0; + while (service->nameservers_config[i]) { + if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET && + service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL) { + append_nameserver_manual(iter, NULL, service->nameservers_config[i]); + } + + if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET6 && + service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL) { + append_nameserver_manual(iter, NULL, service->nameservers_config[i]); + } + i++; + } +#else append_nameservers(iter, NULL, service->nameservers_config); +#endif } static void append_ts(DBusMessageIter *iter, void *user_data) @@ -2338,6 +3211,86 @@ int __connman_service_iterate_services(service_iterate_cb cb, void *user_data) return 0; } +#if defined TIZEN_EXT +static void append_wifi_ext_info(DBusMessageIter *dict, + struct connman_network *network) +{ + char bssid_buff[WIFI_BSSID_STR_LEN] = {0,}; + char *bssid_str = bssid_buff; + const void *ssid; + unsigned int ssid_len; + unsigned char *bssid; + unsigned int maxrate; + unsigned int keymgmt; + uint16_t frequency; + const char *enc_mode; + const char *str; + gboolean passpoint; + + ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len); + bssid = connman_network_get_bssid(network); + maxrate = connman_network_get_maxrate(network); + frequency = connman_network_get_frequency(network); + enc_mode = connman_network_get_enc_mode(network); + passpoint = connman_network_get_bool(network, "WiFi.HS20AP"); + keymgmt = connman_network_get_keymgmt(network); + + snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x", + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5]); + + connman_dbus_dict_append_fixed_array(dict, "SSID", + DBUS_TYPE_BYTE, &ssid, ssid_len); + connman_dbus_dict_append_basic(dict, "BSSID", + DBUS_TYPE_STRING, &bssid_str); + connman_dbus_dict_append_basic(dict, "MaxRate", + DBUS_TYPE_UINT32, &maxrate); + connman_dbus_dict_append_basic(dict, "Frequency", + DBUS_TYPE_UINT16, &frequency); + connman_dbus_dict_append_basic(dict, "EncryptionMode", + DBUS_TYPE_STRING, &enc_mode); + connman_dbus_dict_append_basic(dict, "Passpoint", + DBUS_TYPE_BOOLEAN, &passpoint); + connman_dbus_dict_append_basic(dict, "Keymgmt", + DBUS_TYPE_UINT32, &keymgmt); + + str = connman_network_get_string(network, "WiFi.Security"); + if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) { + str = connman_network_get_string(network, "WiFi.EAP"); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "EAP", + DBUS_TYPE_STRING, &str); + + str = connman_network_get_string(network, "WiFi.Phase2"); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "Phase2", + DBUS_TYPE_STRING, &str); + + str = connman_network_get_string(network, "WiFi.Identity"); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "Identity", + DBUS_TYPE_STRING, &str); + + str = connman_network_get_string(network, "WiFi.CACertFile"); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "CACertFile", + DBUS_TYPE_STRING, &str); + + str = connman_network_get_string(network, + "WiFi.ClientCertFile"); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "ClientCertFile", + DBUS_TYPE_STRING, &str); + + str = connman_network_get_string(network, + "WiFi.PrivateKeyFile"); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "PrivateKeyFile", + DBUS_TYPE_STRING, &str); + } +} +#endif + static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, struct connman_service *service) { @@ -2345,6 +3298,23 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, const char *str; GSList *list; +#if defined TIZEN_EXT + unsigned int frequency = 0U; + if (service && service->network) { + frequency = connman_network_get_frequency(service->network); + connman_dbus_dict_append_basic(dict, "Frequency", + DBUS_TYPE_UINT16, &frequency); + } + const void *wifi_vsie; + unsigned int wifi_vsie_len; + wifi_vsie = connman_network_get_blob(service->network, "WiFi.Vsie", &wifi_vsie_len); + if(wifi_vsie_len > 0) { + DBG("ConnMan, service->path=%s vsie length=%d", service->path, wifi_vsie_len); + } + connman_dbus_dict_append_fixed_array(dict, "Vsie", DBUS_TYPE_BYTE, + &wifi_vsie, wifi_vsie_len); +#endif + str = __connman_service_type2string(service->type); if (str) connman_dbus_dict_append_basic(dict, "Type", @@ -2358,6 +3328,13 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, connman_dbus_dict_append_basic(dict, "State", DBUS_TYPE_STRING, &str); +#ifdef TIZEN_EXT + str = state2string(service->state_ipv6); + if (str != NULL) + connman_dbus_dict_append_basic(dict, "StateIPv6", + DBUS_TYPE_STRING, &str); +#endif + str = error2string(service->error); if (str) connman_dbus_dict_append_basic(dict, "Error", @@ -2403,6 +3380,21 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, append_ethernet, service); break; case CONNMAN_SERVICE_TYPE_WIFI: +#if defined TIZEN_EXT + if (service->network != NULL) + append_wifi_ext_info(dict, service->network); + + connman_dbus_dict_append_dict(dict, "Ethernet", + append_ethernet, service); + + connman_dbus_dict_append_basic(dict, "DisconnectReason", + DBUS_TYPE_INT32, &service->disconnect_reason); + + connman_dbus_dict_append_basic(dict, "AssocStatusCode", + DBUS_TYPE_INT32, &service->assoc_status_code); + + break; +#endif case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_BLUETOOTH: case CONNMAN_SERVICE_TYPE_GADGET: @@ -2635,6 +3627,54 @@ char **connman_service_get_timeservers(struct connman_service *service) return service->timeservers; } +#if defined TIZEN_EXT +/* + * Description: Telephony plug-in requires manual PROXY setting function + */ +int connman_service_set_proxy(struct connman_service *service, + const char *proxy, gboolean active) +{ + char **proxies_array = NULL; + + if (service == NULL) + return -EINVAL; + + switch (service->type) { + case CONNMAN_SERVICE_TYPE_CELLULAR: + case CONNMAN_SERVICE_TYPE_ETHERNET: + case CONNMAN_SERVICE_TYPE_WIFI: + break; + + default: + return -EINVAL; + } + + g_strfreev(service->proxies); + service->proxies = NULL; + + if (proxy != NULL) + proxies_array = g_strsplit(proxy, " ", 0); + + service->proxies = proxies_array; + + if (proxy == NULL) { + service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_DIRECT; + DBG("proxy changed (%d)", active); + } else { + service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_MANUAL; + DBG("proxy chagned %s (%d)", proxy, active); + } + + if (active == TRUE) { + proxy_changed(service); + + __connman_notifier_proxy_changed(service); + } + + return 0; +} +#endif + void connman_service_set_proxy_method(struct connman_service *service, enum connman_service_proxy_method method) { @@ -2722,6 +3762,18 @@ const char *connman_service_get_proxy_autoconfig(struct connman_service *service return NULL; } +#if defined TIZEN_EXT +int connman_service_get_ipv6_dns_method(struct connman_service *service) +{ + if (!service) { + DBG("Service is NULL"); + return -1; + } + + return service->dns_config_method_ipv6; +} +#endif + void __connman_service_set_timeservers(struct connman_service *service, char **timeservers) { @@ -2849,6 +3901,22 @@ void __connman_service_set_pac(struct connman_service *service, proxy_changed(service); } +#if defined TIZEN_EXT +void __connman_service_set_proxy(struct connman_service *service, + const char *proxies) +{ + char **proxies_array = NULL; + + g_strfreev(service->proxies); + service->proxies = NULL; + + if (proxies != NULL) + proxies_array = g_strsplit(proxies, " ", 0); + + service->proxies = proxies_array; +} +#endif + void __connman_service_set_identity(struct connman_service *service, const char *identity) { @@ -2968,7 +4036,9 @@ int __connman_service_check_passphrase(enum connman_service_security security, case CONNMAN_SERVICE_SECURITY_UNKNOWN: case CONNMAN_SERVICE_SECURITY_NONE: case CONNMAN_SERVICE_SECURITY_WPA: +#if !defined TIZEN_EXT case CONNMAN_SERVICE_SECURITY_RSN: +#endif DBG("service security '%s' (%d) not handled", security2string(security), security); @@ -2976,6 +4046,9 @@ int __connman_service_check_passphrase(enum connman_service_security security, return -EOPNOTSUPP; case CONNMAN_SERVICE_SECURITY_PSK: +#if defined TIZEN_EXT + case CONNMAN_SERVICE_SECURITY_RSN: +#endif /* A raw key is always 64 bytes length, * its content is in hex representation. * A PSK key must be between [8..63]. @@ -3019,7 +4092,14 @@ int __connman_service_set_passphrase(struct connman_service *service, if (service->immutable && service->security != CONNMAN_SERVICE_SECURITY_8021X) return -EINVAL; - +#if defined TIZEN_EXT + /* The encrypted passphrase is used here + * and validation is done by net-config before being encrypted. + */ + if (service->security != CONNMAN_SERVICE_SECURITY_PSK && + service->security != CONNMAN_SERVICE_SECURITY_RSN && + service->security != CONNMAN_SERVICE_SECURITY_WEP) +#endif err = __connman_service_check_passphrase(service->security, passphrase); if (err < 0) @@ -3347,6 +4427,21 @@ static DBusMessage *set_property(DBusConnection *conn, if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) return __connman_error_invalid_arguments(msg); + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && is_connected(service->state)) { + uid_t uid; + if (connman_dbus_get_connection_unix_user_sync(conn, + dbus_message_get_sender(msg), + &uid) < 0) { + DBG("Can not get unix user id!"); + return __connman_error_permission_denied(msg); + } + + if (!connman_service_is_user_allowed(service, uid)) { + DBG("Not allow this user to operate this wifi service now!"); + return __connman_error_permission_denied(msg); + } + } + dbus_message_iter_get_basic(&iter, &name); dbus_message_iter_next(&iter); @@ -3384,6 +4479,10 @@ static DBusMessage *set_property(DBusConnection *conn, GString *str; int index; const char *gw; +#if defined TIZEN_EXT + enum connman_ipconfig_type ip_type = CONNMAN_IPCONFIG_TYPE_ALL; + DBG("%s", name); +#endif if (__connman_provider_is_immutable(service->provider) || service->immutable) @@ -3400,17 +4499,64 @@ static DBusMessage *set_property(DBusConnection *conn, gw = __connman_ipconfig_get_gateway_from_index(index, CONNMAN_IPCONFIG_TYPE_ALL); +#if !defined TIZEN_EXT if (gw && strlen(gw)) __connman_service_nameserver_del_routes(service, CONNMAN_IPCONFIG_TYPE_ALL); - +#endif dbus_message_iter_recurse(&value, &entry); +#if defined TIZEN_EXT + /* IPv4/IPv6 Last DNS config method */ + int last_dns_ipv4 = service->dns_config_method_ipv4; + int last_dns_ipv6 = service->dns_config_method_ipv6; + DBG("Last DNS Config Method IPv4: %d IPv6: %d", last_dns_ipv4, last_dns_ipv6); +#endif + while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) { const char *val; dbus_message_iter_get_basic(&entry, &val); dbus_message_iter_next(&entry); +#ifdef TIZEN_EXT + /* First unpack the DNS Config Method */ + DBG("DNS Config Method: %s", val); + if((g_strcmp0(val, "ipv4.manual") == 0)) { + service->dns_config_method_ipv4 = + CONNMAN_DNSCONFIG_METHOD_MANUAL; + + if(last_dns_ipv4 != CONNMAN_DNSCONFIG_METHOD_MANUAL) { + if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN) + ip_type = CONNMAN_IPCONFIG_TYPE_IPV4; + else + ip_type = CONNMAN_IPCONFIG_TYPE_ALL; + } + continue; + } else if(g_strcmp0(val, "ipv4.dhcp") == 0) { + service->dns_config_method_ipv4 = + CONNMAN_DNSCONFIG_METHOD_DHCP; + if(last_dns_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL) + ip_type = CONNMAN_IPCONFIG_TYPE_IPV4; + + continue; + } else if(g_strcmp0(val, "ipv6.manual") == 0) { + service->dns_config_method_ipv6 = + CONNMAN_DNSCONFIG_METHOD_MANUAL; + if(last_dns_ipv6 != CONNMAN_DNSCONFIG_METHOD_MANUAL) { + if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN) + ip_type = CONNMAN_IPCONFIG_TYPE_IPV6; + else + ip_type = CONNMAN_IPCONFIG_TYPE_ALL; + } + continue; + } else if(g_strcmp0(val, "ipv6.dhcp") == 0) { + service->dns_config_method_ipv6 = + CONNMAN_DNSCONFIG_METHOD_DHCP; + if(last_dns_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL) + ip_type = CONNMAN_IPCONFIG_TYPE_IPV6; + continue; + } +#endif if (!val[0]) continue; @@ -3420,7 +4566,21 @@ static DBusMessage *set_property(DBusConnection *conn, g_string_append(str, val); } +#if defined TIZEN_EXT + if (service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_DHCP && + service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_DHCP) { + DBG("Both IPv4 and IPv6 DNS Method DHCP"); + ip_type = CONNMAN_IPCONFIG_TYPE_ALL; + } + if (gw && strlen(gw)) + __connman_service_nameserver_del_routes(service, + ip_type); + + DBG("%s ip_type: %d nameserver remove all", name, ip_type); + nameserver_remove_all(service, ip_type); +#else nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL); +#endif g_strfreev(service->nameservers_config); if (str->len > 0) { @@ -3443,7 +4603,12 @@ static DBusMessage *set_property(DBusConnection *conn, if (gw && strlen(gw)) __connman_service_nameserver_add_routes(service, gw); +#if defined TIZEN_EXT + DBG("%s ip_type: %d nameserver add all", name, ip_type); + nameserver_add_all(service, ip_type); +#else nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL); +#endif dns_configuration_changed(service); if (__connman_service_is_connected_state(service, @@ -3646,8 +4811,10 @@ static void set_error(struct connman_service *service, if (!service->path) return; +#if !defined TIZEN_EXT if (!allow_property_changed(service)) return; +#endif str = error2string(service->error); @@ -3694,6 +4861,14 @@ static void service_complete(struct connman_service *service) service_save(service); } +static void set_idle(struct connman_service *service) +{ + service->state = service->state_ipv4 = service->state_ipv6 = + CONNMAN_SERVICE_STATE_IDLE; + set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); + state_changed(service); +} + static DBusMessage *clear_property(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -3856,6 +5031,17 @@ static GList *preferred_tech_list_get(void) CONNMAN_SERVICE_CONNECT_REASON_USER) { DBG("service %p name %s is user connected", service, service->name); +#if defined TIZEN_EXT + /* We can connect to a favorite service like + * wifi even we have a userconnect for cellular + * because we have refount for cellular service + */ + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + break; + + if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH) + break; +#endif return NULL; } } @@ -3930,6 +5116,20 @@ static bool auto_connect_service(GList *services, continue; } +#if defined TIZEN_EXT + DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)", + service, service->name, + state2string(service->state), + __connman_service_type2string(service->type), + service->favorite, is_ignore(service), + service->hidden, service->hidden_service); + + /* Tizen takes Wi-Fi as the highest priority into consideration. */ + if (service->type != CONNMAN_SERVICE_TYPE_WIFI) + if (is_connecting(service->state) == TRUE || is_connected(service->state) == TRUE) + continue; +#endif + if (service->pending || is_connecting(service->state) || is_connected(service->state)) { @@ -3949,9 +5149,21 @@ static bool auto_connect_service(GList *services, if (preferred) continue; +#if defined TIZEN_EXT + DBG("Service is not favorite, autoconnecting %d", + autoconnecting); +#endif return autoconnecting; } +#if defined TIZEN_EXT + DBG("service %p identifier %s roaming %d ignore %d " + "ipconfig_usable %d autoconnect %d state %d", + service, + service->identifier, service->roaming, + service->ignore, is_ipconfig_usable(service), + service->autoconnect, service->state); +#endif if (is_ignore(service) || service->state != CONNMAN_SERVICE_STATE_IDLE) continue; @@ -3962,6 +5174,11 @@ static bool auto_connect_service(GList *services, continue; } + if (!is_service_owner_user_login(service)) { + DBG("favorite user not login, wifi auto connect denied"); + continue; + } + DBG("service %p %s %s", service, service->name, (preferred) ? "preferred" : reason2string(reason)); @@ -3999,6 +5216,21 @@ static gboolean run_auto_connect(gpointer data) return FALSE; } +#if defined TIZEN_EXT +bool __connman_service_get_auto_connect_mode(void) +{ + return auto_connect_mode; +} + +void __connman_service_set_auto_connect_mode(bool enable) +{ + DBG("set auto_connect_mode = %d", enable); + + if (auto_connect_mode != enable) + auto_connect_mode = enable; +} +#endif + void __connman_service_auto_connect(enum connman_service_connect_reason reason) { DBG(""); @@ -4006,10 +5238,33 @@ void __connman_service_auto_connect(enum connman_service_connect_reason reason) if (autoconnect_timeout != 0) return; +#if defined TIZEN_EXT + if (auto_connect_mode == FALSE) { + DBG("Currently, not auto connection mode"); + return; + } +#endif + if (!__connman_session_policy_autoconnect(reason)) return; +#if defined TIZEN_EXT + /* Adding Timeout of 500ms before trying to auto connect. + * This is done because of below scenario + * 1. Device is connected to AP1 + * 2. WPS Connection request is initiated for AP2 + * 3. Immediately WPS Connection is Cancelled + * When WPS Connection Connection is initiated for AP2 then + * sometimes there is a scenario where connman gets in ASSOCIATED + * state with AP1 due to autoconnect and subsequently the connection + * initiated by AP1 fails and connman service for AP1 comes in + * FAILURE state due to this when connection with AP2 is cancelled + * then autoconnect with AP1 doesn't works because its autoconnection + * is ignored as its last state was FAILURE rather than IDLE */ + autoconnect_timeout = g_timeout_add(500, run_auto_connect, +#else autoconnect_timeout = g_idle_add(run_auto_connect, +#endif GUINT_TO_POINTER(reason)); } @@ -4173,19 +5428,67 @@ static DBusMessage *connect_service(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct connman_service *service = user_data; +#if defined TIZEN_EXT + int err = 0; +#else int index, err = 0; GList *list; +#endif DBG("service %p", service); +#if defined TIZEN_EXT + /* + * Description: TIZEN implements system global connection management. + */ + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + connman_service_user_pdn_connection_ref(service); + + /*Reset the Disconnect Reason while issue connect request*/ + service->disconnect_reason = 0; + + /*Reset the association status code while issue connect request*/ + service->assoc_status_code = 0; +#endif + if (service->pending) return __connman_error_in_progress(msg); + if (service->type == CONNMAN_SERVICE_TYPE_WIFI) { + uid_t uid; + if (connman_dbus_get_connection_unix_user_sync(conn, + dbus_message_get_sender(msg), + &uid) < 0) { + DBG("Can not get unix user id!"); + return __connman_error_permission_denied(msg); + } + + if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) { + DBG("Not allow this user to connect this wifi service now!"); + return __connman_error_permission_denied(msg); + } + + if (uid != USER_ROOT && uid != service->user.favorite_user) + service->request_passphrase_input = true; + + service->user.current_user = uid; + + if (!service->passphrase && uid == service->user.favorite_user) { + DBG("Now load this favorite user's passphrase."); + service_load_passphrase(service); + } + } + +#if !defined TIZEN_EXT index = __connman_service_get_index(service); for (list = service_list; list; list = list->next) { struct connman_service *temp = list->data; +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + break; +#endif if (!is_connecting(temp->state) && !is_connected(temp->state)) break; @@ -4202,6 +5505,7 @@ static DBusMessage *connect_service(DBusConnection *conn, } if (err == -EINPROGRESS) return __connman_error_operation_timeout(msg); +#endif service->ignore = false; @@ -4232,6 +5536,35 @@ static DBusMessage *disconnect_service(DBusConnection *conn, DBG("service %p", service); +#if defined TIZEN_EXT + /* + * Description: TIZEN implements system global connection management. + */ + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) { + if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE) + return __connman_error_failed(msg, EISCONN); + + if (is_connected(service->state) == TRUE && + service == connman_service_get_default_connection()) + return __connman_error_failed(msg, EISCONN); + } +#endif + + if (service->type == CONNMAN_SERVICE_TYPE_WIFI) { + uid_t uid; + if (connman_dbus_get_connection_unix_user_sync(conn, + dbus_message_get_sender(msg), + &uid) < 0) { + DBG("Can not get unix user id!"); + return __connman_error_permission_denied(msg); + } + + if (!connman_service_is_user_allowed(service, uid)) { + DBG("Not allow this user to disconnect this wifi service now!"); + return __connman_error_permission_denied(msg); + } + } + service->ignore = true; err = __connman_service_disconnect(service); @@ -4241,6 +5574,24 @@ static DBusMessage *disconnect_service(DBusConnection *conn, return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } +#if defined TIZEN_EXT +static void __connman_service_cleanup_network_8021x(struct connman_service *service) +{ + if (service == NULL) + return; + + DBG("service %p ", service); + + connman_network_set_string(service->network, "WiFi.EAP", NULL); + connman_network_set_string(service->network, "WiFi.Identity", NULL); + connman_network_set_string(service->network, "WiFi.CACertFile", NULL); + connman_network_set_string(service->network, "WiFi.ClientCertFile", NULL); + connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL); + connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL); + connman_network_set_string(service->network, "WiFi.Phase2", NULL); +} +#endif + bool __connman_service_remove(struct connman_service *service) { if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET || @@ -4251,8 +5602,10 @@ bool __connman_service_remove(struct connman_service *service) __connman_provider_is_immutable(service->provider)) return false; +#if !defined TIZEN_EXT if (!service->favorite && !is_idle(service->state)) return false; +#endif __connman_service_disconnect(service); @@ -4283,13 +5636,62 @@ bool __connman_service_remove(struct connman_service *service) g_free(service->eap); service->eap = NULL; +#if defined TIZEN_EXT + g_free(service->ca_cert_file); + service->ca_cert_file = NULL; + + g_free(service->client_cert_file); + service->client_cert_file = NULL; + + g_free(service->private_key_file); + service->private_key_file = NULL; + + g_free(service->private_key_passphrase); + service->private_key_passphrase = NULL; + + g_free(service->phase2); + service->phase2 = NULL; + + __connman_service_cleanup_network_8021x(service); + + __connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP); + __connman_ipconfig_set_method(service->ipconfig_ipv6, CONNMAN_IPCONFIG_METHOD_AUTO); + connman_service_set_proxy(service, NULL, false); + + __connman_service_nameserver_clear(service); + + g_strfreev(service->nameservers_config); + service->nameservers_config = NULL; + +#endif + +#if defined TIZEN_EXT + if (service->security != CONNMAN_SERVICE_SECURITY_8021X) +#endif + set_idle(service); + service->error = CONNMAN_SERVICE_ERROR_UNKNOWN; + service->user.favorite_user = USER_NONE; + __connman_service_set_favorite(service, false); __connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6); +#if defined TIZEN_EXT + /* Reset IP Method and DNS Method to DHCP */ + __connman_ipconfig_set_method(service->ipconfig_ipv4, + CONNMAN_IPCONFIG_METHOD_DHCP); + service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP; + g_strfreev(service->nameservers_config); + service->nameservers_config = NULL; +#endif + +#if defined TIZEN_EXT + __connman_storage_remove_service(service->identifier); +#else service_save(service); +#endif return true; } @@ -4301,6 +5703,23 @@ static DBusMessage *remove_service(DBusConnection *conn, DBG("service %p", service); + if (service->type == CONNMAN_SERVICE_TYPE_WIFI) { + uid_t uid; + if (connman_dbus_get_connection_unix_user_sync(conn, + dbus_message_get_sender(msg), + &uid) < 0) { + DBG("Can not get unix user id!"); + return __connman_error_permission_denied(msg); + } + +#if !defined TIZEN_EXT + if (!connman_service_is_user_allowed(service, uid)) { + DBG("Not allow this user to remove this wifi service now!"); + return __connman_error_permission_denied(msg); + } +#endif + } + if (!__connman_service_remove(service)) return __connman_error_not_supported(msg); @@ -4510,6 +5929,30 @@ static DBusMessage *reset_counters(DBusConnection *conn, return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } +static DBusMessage *get_user_favorite(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + DBusMessage *reply; + uid_t uid = USER_NONE; + dbus_bool_t user_favorite = false; + struct connman_service *service = user_data; + + connman_dbus_get_connection_unix_user_sync(conn, + dbus_message_get_sender(msg), + &uid); + if (uid == USER_ROOT) + user_favorite = service->favorite; + else if (uid != USER_NONE && uid == service->user.favorite_user) { + DBG("The service is favorite to this user!"); + user_favorite = true; + } + + reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, + &user_favorite, DBUS_TYPE_INVALID); + return reply; +} + static struct _services_notify { int id; GHashTable *add; @@ -4522,17 +5965,23 @@ static void service_append_added_foreach(gpointer data, gpointer user_data) DBusMessageIter *iter = user_data; if (!service || !service->path) { +#if !defined TIZEN_EXT DBG("service %p or path is NULL", service); +#endif return; } if (g_hash_table_lookup(services_notify->add, service->path)) { +#if !defined TIZEN_EXT DBG("new %s", service->path); +#endif append_struct(service, iter); g_hash_table_remove(services_notify->add, service->path); } else { +#if !defined TIZEN_EXT DBG("changed %s", service->path); +#endif append_struct_service(iter, NULL, service); } @@ -4620,6 +6069,10 @@ static void service_schedule_removed(struct connman_service *service) static bool allow_property_changed(struct connman_service *service) { +#if defined TIZEN_EXT + if (service->path == NULL) + return FALSE; +#endif if (g_hash_table_lookup_extended(services_notify->add, service->path, NULL, NULL)) return false; @@ -4649,6 +6102,9 @@ static const GDBusMethodTable service_methods[] = { GDBUS_ARGS({ "service", "o" }), NULL, move_after) }, { GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) }, + { GDBUS_METHOD("GetUserFavorite", + NULL, GDBUS_ARGS({ "value", "v" }), + get_user_favorite) }, { }, }; @@ -4789,6 +6245,11 @@ static void service_initialize(struct connman_service *service) service->ignore = false; + service->user.favorite_user = USER_NONE; + service->user.current_user = USER_NONE; + + service->request_passphrase_input = false; + service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE; service->order = 0; @@ -4798,6 +6259,14 @@ static void service_initialize(struct connman_service *service) service->provider = NULL; service->wps = false; +#if defined TIZEN_EXT + service->storage_reload = false; + /* + * Description: TIZEN implements system global connection management. + */ + service->user_pdn_connection_refcount = 0; + __sync_synchronize(); +#endif } /** @@ -5035,6 +6504,40 @@ char *connman_service_get_interface(struct connman_service *service) } /** + * __connman_service_is_user_allowed: + * @type: service type + * @uid: user id + * + * Check a user is allowed to operate a type of service + */ +bool __connman_service_is_user_allowed(enum connman_service_type type, + uid_t uid) +{ + GList *list; + uid_t owner_user = USER_NONE; + + for (list = service_list; list; list = list->next) { + struct connman_service *service = list->data; + + if (service->type != type) + continue; + + if (is_connected(service->state)) { + owner_user = service->user.favorite_user; + break; + } + } + + if (uid == USER_NONE || + (uid != USER_ROOT && + owner_user != USER_NONE && + owner_user != uid)) + return false; + + return true; +} + +/** * connman_service_get_network: * @service: service structure * @@ -5129,6 +6632,53 @@ void __connman_service_mark_dirty(void) services_dirty = true; } +#if defined TIZEN_EXT +/** + * Returns profile count if there is any connected profiles + * that use same interface + */ +int __connman_service_get_connected_count_of_iface( + struct connman_service *service) +{ + GList *list; + int count = 0; + int index1 = 0; + int index2 = 0; + + DBG(""); + + index1 = __connman_service_get_index(service); + + if (index1 <= 0) + return 0; + + for (list = service_list; list; list = list->next) { + struct connman_service *service2 = list->data; + + if (service == service2) + continue; + + index2 = __connman_service_get_index(service2); + + if (is_connected(service2->state) && index2 > 0 && index1 == index2) + count++; + + index2 = 0; + } + + DBG("Interface index %d, count %d", index1, count); + + return count; +} + +void __connman_service_set_storage_reload(struct connman_service *service, + bool storage_reload) +{ + if (service != NULL) + service->storage_reload = storage_reload; +} +#endif + /** * __connman_service_set_favorite_delayed: * @service: service structure @@ -5141,6 +6691,10 @@ int __connman_service_set_favorite_delayed(struct connman_service *service, bool favorite, bool delay_ordering) { +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + return -EIO; +#endif if (service->hidden) return -EOPNOTSUPP; @@ -5285,7 +6839,14 @@ static void report_error_cb(void *user_context, bool retry, /* It is not relevant to stay on Failure state * when failing is due to wrong user input */ __connman_service_clear_error(service); +#if defined TIZEN_EXT + /* Reseting the state back in case of failure state */ + service->state_ipv4 = service->state_ipv6 = + CONNMAN_SERVICE_STATE_IDLE; + if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED) + set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN); +#endif service_complete(service); __connman_connection_update_gateway(); } @@ -5467,6 +7028,126 @@ static int service_update_preferred_order(struct connman_service *default_servic return -EALREADY; } +#if defined TIZEN_EXT +static gboolean __connman_service_can_drop(struct connman_service *service) +{ + if (is_connected(service->state) == TRUE || is_connecting(service->state) == TRUE) { + if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR) + return TRUE; + else if (connman_service_is_no_ref_user_pdn_connection(service) == TRUE) + return TRUE; + } + return FALSE; +} + +static struct connman_device *default_connecting_device = NULL; + +static void __connman_service_disconnect_default(struct connman_service *service) +{ + struct connman_device *default_device = NULL; + + if (default_connecting_device == NULL) + return; + + default_device = connman_network_get_device( + __connman_service_get_network(service)); + + DBG("Disconnecting service %p %s", service, service->path); + DBG("Disconnecting device %p %p %s", + default_connecting_device, + default_device, + connman_device_get_string(default_device, "Name")); + + if (default_connecting_device == default_device) + default_connecting_device = NULL; +} + +static void __connman_service_connect_default(struct connman_service *current) +{ + int err; + GList *list; + bool default_internet; + struct connman_service *service; + struct connman_service *default_service = NULL; + struct connman_device *default_device = NULL; + + if (current->type == CONNMAN_SERVICE_TYPE_CELLULAR) { + switch (current->state) { + case CONNMAN_SERVICE_STATE_UNKNOWN: + case CONNMAN_SERVICE_STATE_ASSOCIATION: + case CONNMAN_SERVICE_STATE_CONFIGURATION: + return; + default: + break; + } + + if (default_connecting_device && + __connman_service_is_internet_profile(current) == TRUE) { + if (current->network == NULL) + return; + + default_device = connman_network_get_device(current->network); + if (default_connecting_device == default_device) { + DBG("Cellular service[%s] %p %s", + state2string(current->state), current, current->path); + DBG("Cellular device %p %p %s", + default_connecting_device, default_device, + connman_device_get_string(default_device, "Name")); + + default_connecting_device = NULL; + } + } + + return; + } else if (is_connected(current->state) == TRUE || is_connecting(current->state) == TRUE) + return; + + /* Always-on: keep default cellular connection as possible */ + for (list = service_list; list; list = list->next) { + service = list->data; + + if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR || + __connman_service_is_internet_profile(service) != TRUE || + service->network == NULL) { + continue; + } + + default_internet = + connman_network_get_bool(service->network, "DefaultInternet"); + + DBG("service: %p %s %s %s (default: %d)", service, service->name, + __connman_service_type2string(service->type), + state2string(service->state), default_internet); + + if (default_internet) { + default_service = service; + if (is_connected(default_service->state) == TRUE || + is_connecting(default_service->state) == TRUE) + return; + + default_device = connman_network_get_device(default_service->network); + if (default_connecting_device == default_device) { + DBG("Device is connecting (%p)", default_connecting_device); + return; + } + + default_connecting_device = default_device; + default_service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER; + + err = __connman_network_connect(default_service->network); + DBG("Connecting default service %p %s [%d]", + default_service, default_service->path, err); + DBG("Connecting device %p %s", default_connecting_device, + connman_device_get_string(default_connecting_device, "Name")); + if (err < 0 && err != -EINPROGRESS) { + default_connecting_device = NULL; + } else + break; + } + } +} +#endif + static void single_connected_tech(struct connman_service *allowed) { struct connman_service *service; @@ -5475,15 +7156,24 @@ static void single_connected_tech(struct connman_service *allowed) DBG("keeping %p %s", allowed, allowed->path); +#if defined TIZEN_EXT + if (!allowed || allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR) + return; +#endif + for (iter = service_list; iter; iter = iter->next) { service = iter->data; +#if defined TIZEN_EXT + if (service != allowed && service->type != allowed->type && + __connman_service_can_drop(service) == TRUE) +#else if (!is_connected(service->state)) break; if (service == allowed) continue; - +#endif services = g_slist_prepend(services, service); } @@ -5491,12 +7181,32 @@ static void single_connected_tech(struct connman_service *allowed) service = list->data; DBG("disconnecting %p %s", service, service->path); +#if defined TIZEN_EXT + __connman_service_disconnect_default(service); +#endif __connman_service_disconnect(service); } g_slist_free(services); } +#if defined TIZEN_EXT +static void set_priority_connected_service(void) +{ + struct connman_service *service; + GList *list; + + for (list = service_list; list; list = list->next) { + service = list->data; + + if (is_connected(service->state) == FALSE) + service->order = 5; + else + service->order = 6; + } +} +#endif + static const char *get_dbus_sender(struct connman_service *service) { if (!service->pending) @@ -5640,6 +7350,11 @@ static int service_indicate_state(struct connman_service *service) else if (service->type != CONNMAN_SERVICE_TYPE_VPN) vpn_auto_connect(); +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_WIFI) + set_priority_connected_service(); +#endif + break; case CONNMAN_SERVICE_STATE_ONLINE: @@ -5652,6 +7367,8 @@ static int service_indicate_state(struct connman_service *service) reply_pending(service, ECONNABORTED); def_service = __connman_service_get_default(); + service->disconnect_reason = connman_network_get_disconnect_reason(service->network); + service->assoc_status_code = connman_network_get_assoc_status_code(service->network); if (!__connman_notifier_is_connected() && def_service && @@ -5664,8 +7381,20 @@ static int service_indicate_state(struct connman_service *service) __connman_wpad_stop(service); +#if defined TIZEN_EXT + /** + * Skip the functions if there is any connected profiles + * that use same interface + */ + if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR || + __connman_service_get_connected_count_of_iface( + service) <= 0) { +#endif domain_changed(service); proxy_changed(service); +#if defined TIZEN_EXT + } +#endif /* * Previous services which are connected and which states @@ -5678,7 +7407,11 @@ static int service_indicate_state(struct connman_service *service) break; case CONNMAN_SERVICE_STATE_FAILURE: - +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_WIFI) + service->order = 5; + __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO); +#endif if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER && connman_agent_report_error(service, service->path, error2string(service->error), @@ -5693,6 +7426,10 @@ static int service_indicate_state(struct connman_service *service) service_list_sort(); +#if defined TIZEN_EXT + __connman_service_connect_default(service); +#endif + __connman_connection_update_gateway(); if ((old_state == CONNMAN_SERVICE_STATE_ONLINE && @@ -5707,6 +7444,20 @@ static int service_indicate_state(struct connman_service *service) default_changed(); } + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && + service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER && + (new_state == CONNMAN_SERVICE_STATE_READY || + new_state == CONNMAN_SERVICE_STATE_ONLINE)) { + if (service->user.favorite_user != service->user.current_user) { + DBG("Now set service favorite user id from %d to %d", + service->user.favorite_user, service->user.current_user); + + service->user.favorite_user = service->user.current_user; + + service_save(service); + } + } + return 0; } @@ -5723,6 +7474,23 @@ int __connman_service_indicate_error(struct connman_service *service, set_error(service, error); +/* default internet service: fix not cleared if pdp activation*/ +#if defined TIZEN_EXT + /* + * If connection failed for default service(DefaultInternet), + * default_connecting_device should be cleared. + */ + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR && + service->error == CONNMAN_SERVICE_ERROR_CONNECT_FAILED) + __connman_service_disconnect_default(service); + + if (service->type == CONNMAN_SERVICE_TYPE_WIFI && + service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) { + g_free(service->passphrase); + service->passphrase = NULL; + } +#endif + __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_FAILURE, CONNMAN_IPCONFIG_TYPE_IPV4); @@ -5825,6 +7593,15 @@ done: __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4); } +#if defined TIZEN_EXT +void connman_check_proxy_setup_and_wispr_start(struct connman_service *service){ + + DBG("check the proxy and start wispr"); + check_proxy_setup(service); + return; +} +#endif + /* * How many networks are connected at the same time. If more than 1, * then set the rp_filter setting properly (loose mode routing) so that network @@ -5976,6 +7753,18 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, if (old_state == new_state) return -EALREADY; +#if defined TIZEN_EXT + __sync_synchronize(); + if (service->user_pdn_connection_refcount > 0 && + service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + if (new_state == CONNMAN_SERVICE_STATE_FAILURE || + new_state == CONNMAN_SERVICE_STATE_DISCONNECT || + new_state == CONNMAN_SERVICE_STATE_IDLE) { + service->user_pdn_connection_refcount = 0; + __sync_synchronize(); + } +#endif + DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)", service, service ? service->identifier : NULL, old_state, state2string(old_state), @@ -5989,14 +7778,25 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, case CONNMAN_SERVICE_STATE_CONFIGURATION: break; case CONNMAN_SERVICE_STATE_READY: - if (connman_setting_get_bool("EnableOnlineCheck")) +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR && + __connman_service_is_internet_profile(service) != TRUE) { + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + service_rp_filter(service, TRUE); + + break; + } +#endif + if (connman_setting_get_bool("EnableOnlineCheck")) { if (type == CONNMAN_IPCONFIG_TYPE_IPV4) { +#if !defined TIZEN_EXT check_proxy_setup(service); +#endif } else { service->online_check_count = 1; __connman_wispr_start(service, type); } - else + } else connman_info("Online check disabled. " "Default service remains in READY state."); if (type == CONNMAN_IPCONFIG_TYPE_IPV4) @@ -6033,6 +7833,19 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service, __connman_timeserver_sync(service); +#if defined TIZEN_EXT + int ret = service_indicate_state(service); + /*Sent the Ready changed signal again in case IPv4 IP set + after IPv6 IP set*/ + + if(ret == -EALREADY && type == CONNMAN_IPCONFIG_TYPE_IPV4 + && new_state == CONNMAN_SERVICE_STATE_READY) { + DBG("Notify IPv4 state new/old %d/%d", new_state,old_state); + state_changed(service); + } + + return ret; +#endif return service_indicate_state(service); } @@ -6129,6 +7942,33 @@ static int service_connect(struct connman_service *service) if (service->hidden) return -EPERM; +#if defined TIZEN_EXT + GList *list; + int index; + + index = __connman_service_get_index(service); + + for (list = service_list; list; list = list->next) { + struct connman_service *temp = list->data; + + if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + break; + + if (!is_connecting(temp->state) && !is_connected(temp->state)) + break; + + if (service == temp) + continue; + + if (service->type != temp->type) + continue; + + if (__connman_service_get_index(temp) == index && + __connman_service_disconnect(temp) == -EINPROGRESS) + return -EINPROGRESS; + } +#endif + switch (service->type) { case CONNMAN_SERVICE_TYPE_UNKNOWN: case CONNMAN_SERVICE_TYPE_SYSTEM: @@ -6153,7 +7993,11 @@ static int service_connect(struct connman_service *service) if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) return -ENOKEY; - if (!service->passphrase) { + if (service->request_passphrase_input) { + DBG("Now try to connect other user's favorite service"); + service->request_passphrase_input = false; + return -ENOKEY; + } else if (!service->passphrase) { if (!service->network) return -EOPNOTSUPP; @@ -6167,13 +8011,25 @@ static int service_connect(struct connman_service *service) if (!service->eap) return -EINVAL; +#if defined TIZEN_EXT + /* + * never request credentials if using EAP-TLS, EAP-SIM + * or EAP-AKA (EAP-TLS, EAP-SIM and EAP-AKA networks + * need to be fully provisioned) + */ + DBG("service eap: %s", service->eap); + if (g_str_equal(service->eap, "tls") || + g_str_equal(service->eap, "sim") || + g_str_equal(service->eap, "aka")) + break; +#else /* * never request credentials if using EAP-TLS * (EAP-TLS networks need to be fully provisioned) */ if (g_str_equal(service->eap, "tls")) break; - +#endif /* * Return -ENOKEY if either identity or passphrase is * missing. Agent provided credentials can be used as @@ -6279,7 +8135,6 @@ int __connman_service_connect(struct connman_service *service, DBG("service %p err %d", service, err); service->connect_reason = reason; - if (err >= 0) return 0; @@ -6361,6 +8216,14 @@ int __connman_service_disconnect(struct connman_service *service) __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6, NULL); +#if defined TIZEN_EXT + /** + * Skip the functions If there is any connected profiles + * that use same interface + */ + if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR || + __connman_service_get_connected_count_of_iface(service) <= 0) { +#endif __connman_ipconfig_address_remove(service->ipconfig_ipv4); settings_changed(service, service->ipconfig_ipv4); @@ -6369,6 +8232,9 @@ int __connman_service_disconnect(struct connman_service *service) __connman_ipconfig_disable(service->ipconfig_ipv4); __connman_ipconfig_disable(service->ipconfig_ipv6); +#if defined TIZEN_EXT + } +#endif __connman_stats_service_unregister(service); @@ -6581,6 +8447,9 @@ static void service_ip_bound(struct connman_ipconfig *ipconfig, struct connman_service *service = __connman_ipconfig_get_data(ipconfig); enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN; enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN; +#if defined TIZEN_EXT + int err; +#endif DBG("%s ip bound", ifname); @@ -6592,9 +8461,18 @@ static void service_ip_bound(struct connman_ipconfig *ipconfig, if (type == CONNMAN_IPCONFIG_TYPE_IPV6 && method == CONNMAN_IPCONFIG_METHOD_AUTO) +#if defined TIZEN_EXT + { + err = __connman_ipconfig_gateway_add(ipconfig, service); + + if(err < 0) + DBG("Failed to add gateway"); + } +#else __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_READY, CONNMAN_IPCONFIG_TYPE_IPV6); +#endif settings_changed(service, ipconfig); address_updated(service, type); @@ -6835,6 +8713,28 @@ unsigned int __connman_service_get_order(struct connman_service *service) if (!service->favorite) return 0; +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_VPN && + service->do_split_routing == FALSE) + order = 10; + else if (service->type == CONNMAN_SERVICE_TYPE_WIFI) { + if (service->order < 5) + order = 5; + } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET) + order = 4; + else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH) + order = 3; + else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR && + __connman_service_is_internet_profile(service) == TRUE) + order = 1; + else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR && + __connman_service_is_tethering_profile(service) == TRUE) + order = 0; + else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) + order = 0; + else + order = 2; +#else if (service == service_list->data) order = 1; @@ -6843,7 +8743,7 @@ unsigned int __connman_service_get_order(struct connman_service *service) service->order = 10; order = 10; } - +#endif DBG("service %p name %s order %d split %d", service, service->name, order, service->do_split_routing); @@ -6890,10 +8790,30 @@ static enum connman_service_security convert_wifi_security(const char *security) return CONNMAN_SERVICE_SECURITY_WPA; else if (g_str_equal(security, "rsn")) return CONNMAN_SERVICE_SECURITY_RSN; +#if defined TIZEN_EXT + else if (g_str_equal(security, "ft_psk") == TRUE) + return CONNMAN_SERVICE_SECURITY_PSK; + else if (g_str_equal(security, "ft_ieee8021x") == TRUE) + return CONNMAN_SERVICE_SECURITY_8021X; +#endif else return CONNMAN_SERVICE_SECURITY_UNKNOWN; } +#if defined TIZEN_EXT +int check_passphrase_ext(struct connman_network *network, + const char *passphrase) +{ + const char *str; + enum connman_service_security security; + + str = connman_network_get_string(network, "WiFi.Security"); + security = convert_wifi_security(str); + + return __connman_service_check_passphrase(security, passphrase); +} +#endif + static void update_from_network(struct connman_service *service, struct connman_network *network) { @@ -7067,6 +8987,19 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne break; } } + +#if defined TIZEN_EXT + /* TIZEN synchronizes below information when the service creates */ + if (service->eap != NULL) + connman_network_set_string(service->network, "WiFi.EAP", + service->eap); + if (service->identity != NULL) + connman_network_set_string(service->network, "WiFi.Identity", + service->identity); + if (service->phase2 != NULL) + connman_network_set_string(service->network, "WiFi.Phase2", + service->phase2); +#endif } __connman_notifier_service_add(service, service->name); @@ -7090,6 +9023,13 @@ void __connman_service_update_from_network(struct connman_network *network) if (!service->network) return; +#if defined TIZEN_EXT + if (service->storage_reload) { + service_load(service); + __connman_service_set_storage_reload(service, false); + } +#endif + name = connman_network_get_string(service->network, "Name"); if (g_strcmp0(service->name, name) != 0) { g_free(service->name); diff --git a/src/session.c b/src/session.c index 9e3c5594..9e3c5594 100644..100755 --- a/src/session.c +++ b/src/session.c diff --git a/src/shared/netlink.c b/src/shared/netlink.c index b32ab854..b32ab854 100644..100755 --- a/src/shared/netlink.c +++ b/src/shared/netlink.c diff --git a/src/shared/netlink.h b/src/shared/netlink.h index 62bb3e01..62bb3e01 100644..100755 --- a/src/shared/netlink.h +++ b/src/shared/netlink.h diff --git a/src/shared/util.c b/src/shared/util.c index df045c5b..df045c5b 100644..100755 --- a/src/shared/util.c +++ b/src/shared/util.c diff --git a/src/shared/util.h b/src/shared/util.h index 293fb3a4..293fb3a4 100644..100755 --- a/src/shared/util.h +++ b/src/shared/util.h diff --git a/src/stats.c b/src/stats.c index 663bc382..663bc382 100644..100755 --- a/src/stats.c +++ b/src/stats.c diff --git a/src/storage.c b/src/storage.c index 5e877ef1..50c8e955 100644..100755 --- a/src/storage.c +++ b/src/storage.c @@ -23,6 +23,7 @@ #include <config.h> #endif +#include <stdio.h> #include <errno.h> #include <unistd.h> #include <sys/stat.h> @@ -71,6 +72,19 @@ static int storage_save(GKeyFile *keyfile, char *pathname) ret = -EIO; } +#if defined TIZEN_EXT + { + FILE *fp = NULL; + fp = fopen(pathname, "a+"); + if(fp){ + fflush(fp); + fsync(fp->_fileno); + fclose(fp); + DBG("sync the file to disk"); + } + } +#endif + g_free(data); return ret; diff --git a/src/task.c b/src/task.c index 953cc409..953cc409 100644..100755 --- a/src/task.c +++ b/src/task.c diff --git a/src/technology.c b/src/technology.c index d2f0ae2b..5aea9f4f 100644..100755 --- a/src/technology.c +++ b/src/technology.c @@ -43,6 +43,16 @@ static GHashTable *rfkill_list; static bool global_offlinemode; +#if defined TIZEN_EXT +typedef enum { + CONNMAN_SCAN_TYPE_FULL_CHANNEL = 0x00, + CONNMAN_SCAN_TYPE_SPECIFIC_AP, + CONNMAN_SCAN_TYPE_MULTI_AP, +} connman_scan_type_e; + +static connman_scan_type_e g_scan_type = -1; +#endif + struct connman_rfkill { unsigned int index; enum connman_service_type type; @@ -66,6 +76,7 @@ struct connman_technology { */ char *tethering_ident; char *tethering_passphrase; + bool tethering_hidden; bool enable_persistent; /* Save the tech state */ @@ -180,6 +191,9 @@ static void technology_save(struct connman_technology *technology) g_key_file_set_boolean(keyfile, identifier, "Tethering", technology->tethering_persistent); + g_key_file_set_boolean(keyfile, identifier, "Hidden", + technology->tethering_hidden); + if (technology->tethering_ident) g_key_file_set_string(keyfile, identifier, "Tethering.Identifier", @@ -253,8 +267,7 @@ static int set_tethering(struct connman_technology *technology, if (!bridge) return -EOPNOTSUPP; - if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && - (!ident || !passphrase)) + if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && (!ident)) return -EINVAL; for (tech_drivers = technology->driver_list; tech_drivers; @@ -546,6 +559,11 @@ static void append_properties(DBusMessageIter *iter, DBUS_TYPE_STRING, &technology->tethering_passphrase); + val = technology->tethering_hidden; + connman_dbus_dict_append_basic(&dict, "Hidden", + DBUS_TYPE_BOOLEAN, + &val); + connman_dbus_dict_close(iter, &dict); } @@ -682,6 +700,10 @@ static void powered_changed(struct connman_technology *technology) __sync_synchronize(); enabled = technology->enabled; +#if defined TIZEN_EXT + DBG("ConnMan, Powered : %s, %s", + enabled ? "TRUE" : "FALSE",technology->path); +#endif connman_dbus_property_changed_basic(technology->path, CONNMAN_TECHNOLOGY_INTERFACE, "Powered", DBUS_TYPE_BOOLEAN, &enabled); @@ -882,6 +904,21 @@ static DBusMessage *set_property(DBusConnection *conn, DBG("property %s", name); + if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && technology->connected) { + uid_t uid; + if (connman_dbus_get_connection_unix_user_sync(conn, + dbus_message_get_sender(msg), + &uid) < 0) { + DBG("Can not get unix user id!"); + return __connman_error_permission_denied(msg); + } + + if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) { + DBG("Not allow this user to operate wifi technology now!"); + return __connman_error_permission_denied(msg); + } + } + if (g_str_equal(name, "Tethering")) { dbus_bool_t tethering; int err; @@ -958,6 +995,25 @@ static DBusMessage *set_property(DBusConnection *conn, DBUS_TYPE_STRING, &technology->tethering_passphrase); } + } else if (g_str_equal(name, "Hidden")) { + dbus_bool_t hidden; + + if (type != DBUS_TYPE_BOOLEAN) + return __connman_error_invalid_arguments(msg); + + dbus_message_iter_get_basic(&value, &hidden); + + if (technology->type != CONNMAN_SERVICE_TYPE_WIFI) + return __connman_error_not_supported(msg); + + technology->tethering_hidden = hidden; + technology_save(technology); + + connman_dbus_property_changed_basic(technology->path, + CONNMAN_TECHNOLOGY_INTERFACE, + "Hidden", + DBUS_TYPE_BOOLEAN, + &hidden); } else if (g_str_equal(name, "Powered")) { dbus_bool_t enable; @@ -997,9 +1053,38 @@ static void reply_scan_pending(struct connman_technology *technology, int err) } } +#if defined TIZEN_EXT +dbus_bool_t __connman_technology_notify_scan_changed(const char *key, void *val) +{ + DBG("key %s", key); + DBusMessage *signal; + DBusMessageIter iter; + dbus_bool_t result = FALSE; + + signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH, + CONNMAN_MANAGER_INTERFACE, "ScanChanged"); + if (!signal) + return result; + + dbus_message_iter_init_append(signal, &iter); + connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_BOOLEAN, val); + + result = dbus_connection_send(connection, signal, NULL); + dbus_message_unref(signal); + + DBG("Successfuly sent signal"); + + return result; +} +#endif + void __connman_technology_scan_started(struct connman_device *device) { DBG("device %p", device); +#if defined TIZEN_EXT + dbus_bool_t status = 1; + __connman_technology_notify_scan_changed("scan_started", &status); +#endif } void __connman_technology_scan_stopped(struct connman_device *device, @@ -1029,8 +1114,32 @@ void __connman_technology_scan_stopped(struct connman_device *device, count += 1; } +#if defined TIZEN_EXT + if (count == 0) { + DBusMessage *signal; + DBusMessageIter iter; + dbus_bool_t status = 0; + __connman_technology_notify_scan_changed("scan_done", &status); + + signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH, + CONNMAN_MANAGER_INTERFACE, "ScanDone"); + if (!signal) + return; + + dbus_message_iter_init_append(signal, &iter); + connman_dbus_property_append_basic(&iter, "Scantype", + DBUS_TYPE_INT32, &g_scan_type); + + dbus_connection_send(connection, signal, NULL); + dbus_message_unref(signal); + reply_scan_pending(technology, 0); + + DBG("Successfuly sent ScanDone signal"); + } +#else if (count == 0) reply_scan_pending(technology, 0); +#endif } void __connman_technology_notify_regdom_by_device(struct connman_device *device, @@ -1082,16 +1191,156 @@ static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data) return __connman_error_permission_denied(msg); dbus_message_ref(msg); +#if !defined TIZEN_EXT technology->scan_pending = g_slist_prepend(technology->scan_pending, msg); +#endif err = __connman_device_request_scan(technology->type); +#if defined TIZEN_EXT + if (err < 0) + return __connman_error_failed(msg, -err); +#else if (err < 0) reply_scan_pending(technology, err); +#endif +#if defined TIZEN_EXT + if (err == 0) { + g_scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL; + DBG("g_scan_type %d", g_scan_type); + } + technology->scan_pending = + g_slist_prepend(technology->scan_pending, msg); +#endif return NULL; } +#if defined TIZEN_EXT +static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data) +{ + struct connman_technology *technology = data; + GSList *specific_scan_list = NULL; + int scan_type = 0; + const char *name = NULL; + unsigned int freq = 0; + DBusMessageIter iter, dict; + int err; + + DBG("technology %p request from %s", technology, + dbus_message_get_sender(msg)); + + if (!dbus_message_iter_init(msg, &iter)) + return __connman_error_invalid_arguments(msg); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) + return __connman_error_invalid_arguments(msg); + + dbus_message_iter_recurse(&iter, &dict); + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, value2; + const char *key; + int type; + + dbus_message_iter_recurse(&dict, &entry); + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) { + g_slist_free_full(specific_scan_list, g_free); + return __connman_error_invalid_arguments(msg); + } + + dbus_message_iter_get_basic(&entry, &key); + dbus_message_iter_next(&entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) { + g_slist_free_full(specific_scan_list, g_free); + return __connman_error_invalid_arguments(msg); + } + + dbus_message_iter_recurse(&entry, &value2); + type = dbus_message_iter_get_arg_type(&value2); + if (g_str_equal(key, "SSID")) { + if (type != DBUS_TYPE_STRING) { + g_slist_free_full(specific_scan_list, g_free); + return __connman_error_invalid_arguments(msg); + } + + scan_type = 1; /* SSID based scan */ + dbus_message_iter_get_basic(&value2, &name); + DBG("name %s", name); + specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name)); + } else if (g_str_equal(key, "Frequency")) { + if (type != DBUS_TYPE_UINT16) { + g_slist_free_full(specific_scan_list, g_free); + return __connman_error_invalid_arguments(msg); + } + + scan_type = 2; /* Frequency based scan */ + dbus_message_iter_get_basic(&value2, &freq); + DBG("freq %d", freq); + specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(freq)); + } + dbus_message_iter_next(&dict); + } + + dbus_message_ref(msg); + + err = __connman_device_request_specific_scan(technology->type, scan_type, specific_scan_list); + if (err < 0) + return __connman_error_failed(msg, -err); + + if (err == 0) { + guint list_size = g_slist_length(specific_scan_list); + if (list_size == 1) + g_scan_type = CONNMAN_SCAN_TYPE_SPECIFIC_AP; + else + g_scan_type = CONNMAN_SCAN_TYPE_MULTI_AP; + DBG("list_size %u g_scan_type %d", list_size, g_scan_type); + } + technology->scan_pending = + g_slist_prepend(technology->scan_pending, msg); + + if (scan_type == 1) { + g_slist_free_full(specific_scan_list, g_free); + scan_type = 0; + } + return NULL; +} + +static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data) +{ + DBusMessage *reply; + DBusMessageIter iter, dict; + GSList *list; + struct connman_technology *technology = data; + dbus_bool_t scanning = false; + + DBG("technology %p", technology); + + for (list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + scanning = connman_device_get_scanning(device); + if(scanning) + break; + } + + DBG("scanning : %d", scanning); + reply = dbus_message_new_method_return(msg); + if (!reply) + return NULL; + + dbus_message_iter_init_append(reply, &iter); + + connman_dbus_dict_open(&iter, &dict); + connman_dbus_dict_append_basic(&dict, "Scanstate", + DBUS_TYPE_BOOLEAN, + &scanning); + + connman_dbus_dict_close(&iter, &dict); + + return reply; +} +#endif + static const GDBusMethodTable technology_methods[] = { { GDBUS_DEPRECATED_METHOD("GetProperties", NULL, GDBUS_ARGS({ "properties", "a{sv}" }), @@ -1100,12 +1349,28 @@ static const GDBusMethodTable technology_methods[] = { GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL, set_property) }, { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) }, +#if defined TIZEN_EXT + { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }), + NULL, specific_scan) }, + { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }), + get_scan_state) }, +#endif { }, }; static const GDBusSignalTable technology_signals[] = { { GDBUS_SIGNAL("PropertyChanged", GDBUS_ARGS({ "name", "s" }, { "value", "v" })) }, + { GDBUS_SIGNAL("DhcpConnected", + GDBUS_ARGS({ "aptype", "s" }, + { "ipaddr", "s" }, + { "macaddr", "s" }, + { "hostname", "s" })) }, + { GDBUS_SIGNAL("DhcpLeaseDeleted", + GDBUS_ARGS({ "aptype", "s" }, + { "ipaddr", "s" }, + { "macaddr", "s" }, + { "hostname", "s" })) }, { }, }; @@ -1227,6 +1492,7 @@ static struct connman_technology *technology_get(enum connman_service_type type) technology->refcount = 1; technology->type = type; + technology->tethering_hidden = FALSE; technology->path = g_strdup_printf("%s/technology/%s", CONNMAN_PATH, str); @@ -1532,12 +1798,13 @@ int __connman_technology_enabled(enum connman_service_type type) DBG("technology %p type %s rfkill %d enabled %d", technology, get_name(type), technology->rfkill_driven, technology->enabled); - +#if !defined TIZEN_EXT if (technology->rfkill_driven) { if (technology->tethering_persistent) enable_tethering(technology); return 0; } +#endif return technology_enabled(technology); } @@ -1550,10 +1817,10 @@ int __connman_technology_disabled(enum connman_service_type type) technology = technology_find(type); if (!technology) return -ENXIO; - +#if !defined TIZEN_EXT if (technology->rfkill_driven) return 0; - +#endif for (list = technology->device_list; list; list = list->next) { struct connman_device *device = list->data; @@ -1732,6 +1999,10 @@ int __connman_technology_add_rfkill(unsigned int index, g_hash_table_insert(rfkill_list, GINT_TO_POINTER(index), rfkill); done: +#if defined TIZEN_EXT + /* Fix Svace Issue [WGID: 1348]. */ + g_free(rfkill); +#endif technology = technology_get(type); /* If there is no driver for this type, ignore it. */ if (!technology) @@ -1739,11 +2010,12 @@ done: technology->rfkill_driven = true; +#if !defined TIZEN_EXT /* If hardblocked, there is no need to handle softblocked state */ if (technology_apply_rfkill_change(technology, softblock, hardblock, true)) return 0; - +#endif if (global_offlinemode) return 0; diff --git a/src/tethering.c b/src/tethering.c index c929ba71..891ee51f 100644..100755 --- a/src/tethering.c +++ b/src/tethering.c @@ -52,6 +52,9 @@ #define DEFAULT_MTU 1500 +#define CONNMAN_STATION_STR_INFO_LEN 64 +#define CONNMAN_STATION_MAC_INFO_LEN 32 + static char *private_network_primary_dns = NULL; static char *private_network_secondary_dns = NULL; @@ -60,6 +63,7 @@ static GDHCPServer *tethering_dhcp_server = NULL; static struct connman_ippool *dhcp_ippool = NULL; static DBusConnection *connection; static GHashTable *pn_hash; +static GHashTable *sta_hash; struct connman_private_network { char *owner; @@ -76,6 +80,164 @@ struct connman_private_network { char *secondary_dns; }; +struct connman_station_info { + bool is_connected; + char *path; + char *type; + char ip[CONNMAN_STATION_STR_INFO_LEN]; + char mac[CONNMAN_STATION_MAC_INFO_LEN]; + char hostname[CONNMAN_STATION_STR_INFO_LEN]; +}; + +static void emit_station_signal(char *action_str, + const struct connman_station_info *station_info) +{ + char *ip, *mac, *hostname; + + if (station_info->path == NULL || station_info->type == NULL + || station_info->ip == NULL || station_info->mac == NULL + || station_info->hostname == NULL) + return; + + ip = g_strdup(station_info->ip); + mac = g_strdup(station_info->mac); + hostname = g_strdup(station_info->hostname); + + g_dbus_emit_signal(connection, station_info->path, + CONNMAN_TECHNOLOGY_INTERFACE, action_str, + DBUS_TYPE_STRING, &station_info->type, + DBUS_TYPE_STRING, &ip, + DBUS_TYPE_STRING, &mac, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_INVALID); + + g_free(ip); + g_free(mac); + g_free(hostname); +} +static void destroy_station(gpointer key, gpointer value, gpointer user_data) +{ + struct connman_station_info *station_info; + + __sync_synchronize(); + + station_info = value; + + if (station_info->is_connected) { + station_info->is_connected = FALSE; + emit_station_signal("DhcpLeaseDeleted", station_info); + } + + g_free(station_info->path); + g_free(station_info->type); + g_free(station_info); +} + +static void save_dhcp_ack_lease_info(char *hostname, + unsigned char *mac, unsigned int nip) +{ + char *lower_mac; + const char *ip; + char sta_mac[CONNMAN_STATION_MAC_INFO_LEN]; + struct connman_station_info *info_found; + struct in_addr addr; + int str_len; + + __sync_synchronize(); + + snprintf(sta_mac, CONNMAN_STATION_MAC_INFO_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + lower_mac = g_ascii_strdown(sta_mac, -1); + + info_found = g_hash_table_lookup(sta_hash, lower_mac); + if (info_found == NULL) { + g_free(lower_mac); + return; + } + + /* get the ip */ + addr.s_addr = nip; + ip = inet_ntoa(addr); + str_len = strlen(ip) + 1; + if (str_len > CONNMAN_STATION_STR_INFO_LEN) + str_len = CONNMAN_STATION_STR_INFO_LEN - 1; + memcpy(info_found->ip, ip, str_len); + + /* get hostname */ + str_len = strlen(hostname) + 1; + if (str_len > CONNMAN_STATION_STR_INFO_LEN) + str_len = CONNMAN_STATION_STR_INFO_LEN - 1; + memcpy(info_found->hostname, hostname, str_len); + + /* emit a signal */ + info_found->is_connected = TRUE; + emit_station_signal("DhcpConnected", info_found); + g_free(lower_mac); +} + +int connman_technology_tethering_add_station(enum connman_service_type type, + const char *mac) +{ + const char *str_type; + char *lower_mac; + char *path; + struct connman_station_info *station_info; + + __sync_synchronize(); + + DBG("type %d", type); + + str_type = __connman_service_type2string(type); + if (str_type == NULL) + return 0; + + path = g_strdup_printf("%s/technology/%s", CONNMAN_PATH, str_type); + + station_info = g_try_new0(struct connman_station_info, 1); + if (station_info == NULL) + return -ENOMEM; + + lower_mac = g_ascii_strdown(mac, -1); + + memcpy(station_info->mac, lower_mac, strlen(lower_mac) + 1); + station_info->path = path; + station_info->type = g_strdup(str_type); + + g_hash_table_insert(sta_hash, station_info->mac, station_info); + + g_free(lower_mac); + return 0; +} + +int connman_technology_tethering_remove_station(const char *mac) +{ + char *lower_mac; + struct connman_station_info *info_found; + + __sync_synchronize(); + + lower_mac = g_ascii_strdown(mac, -1); + + info_found = g_hash_table_lookup(sta_hash, lower_mac); + if (info_found == NULL) { + g_free(lower_mac); + return -EACCES; + } + + if (info_found->is_connected) { + info_found->is_connected = FALSE; + emit_station_signal("DhcpLeaseDeleted", info_found); + } + g_free(lower_mac); + g_hash_table_remove(sta_hash, info_found->mac); + g_free(info_found->path); + g_free(info_found->type); + g_free(info_found); + + return 0; +} + const char *__connman_tethering_get_bridge(void) { int sk, err; @@ -161,6 +323,9 @@ static GDHCPServer *dhcp_server_start(const char *bridge, g_dhcp_server_set_option(dhcp_server, G_DHCP_DNS_SERVER, dns); g_dhcp_server_set_ip_range(dhcp_server, start_ip, end_ip); + g_dhcp_server_set_save_ack_lease(dhcp_server, + save_dhcp_ack_lease_info, NULL); + g_dhcp_server_start(dhcp_server); return dhcp_server; @@ -538,6 +703,9 @@ int __connman_tethering_init(void) pn_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, remove_private_network); + sta_hash = g_hash_table_new_full(g_str_hash, + g_str_equal, NULL, NULL); + return 0; } @@ -558,5 +726,7 @@ void __connman_tethering_cleanup(void) return; g_hash_table_destroy(pn_hash); + g_hash_table_foreach(sta_hash, destroy_station, NULL); + g_hash_table_destroy(sta_hash); dbus_connection_unref(connection); } diff --git a/src/timeserver.c b/src/timeserver.c index 0e555a73..6325eceb 100644..100755 --- a/src/timeserver.c +++ b/src/timeserver.c @@ -88,6 +88,15 @@ static void resolv_result(GResolvResultStatus status, char **results, { int i; +#if defined TIZEN_EXT + gchar *server = NULL; + + server = g_strdup((gchar *)user_data); + ts_list = g_slist_append(ts_list, server); + + DBG("added server %s", server); +#endif + DBG("status %d", status); if (status == G_RESOLV_RESULT_STATUS_SUCCESS) { @@ -148,8 +157,13 @@ void __connman_timeserver_sync_next() DBG("Resolving timeserver %s", ts_current); +#if defined TIZEN_EXT + resolv_id = g_resolv_lookup_hostname(resolv, ts_current, + resolv_result, ts_current); +#else resolv_id = g_resolv_lookup_hostname(resolv, ts_current, resolv_result, NULL); +#endif return; } diff --git a/src/timezone.c b/src/timezone.c index e346b11a..e346b11a 100644..100755 --- a/src/timezone.c +++ b/src/timezone.c diff --git a/src/util.c b/src/util.c index 732d4512..732d4512 100644..100755 --- a/src/util.c +++ b/src/util.c diff --git a/src/utsname.c b/src/utsname.c index 1dd5e0f2..1dd5e0f2 100644..100755 --- a/src/utsname.c +++ b/src/utsname.c diff --git a/src/wispr.c b/src/wispr.c index 03b38bb8..adf62303 100644..100755 --- a/src/wispr.c +++ b/src/wispr.c @@ -879,7 +879,9 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context) goto done; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_WEB_DEBUG")) +#endif g_web_set_debug(wp_context->web, web_debug, "WEB"); if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) { @@ -925,6 +927,11 @@ int __connman_wispr_start(struct connman_service *service, DBG("service %p", service); +#if defined TIZEN_EXT + if (connman_service_get_type(service) == CONNMAN_SERVICE_TYPE_CELLULAR) + return -EPERM; +#endif + if (!wispr_portal_list) return -EINVAL; diff --git a/src/wpad.c b/src/wpad.c index f066feee..b7f1f1e5 100644..100755 --- a/src/wpad.c +++ b/src/wpad.c @@ -161,7 +161,9 @@ int __connman_wpad_start(struct connman_service *service) return -ENOMEM; } +#if !defined TIZEN_EXT if (getenv("CONNMAN_RESOLV_DEBUG")) +#endif g_resolv_set_debug(wpad->resolv, resolv_debug, "RESOLV"); for (i = 0; nameservers[i]; i++) |