Merge branch 'ipsec' into tizen 26/126026/1
authorchleun.moon <chleun.moon@samsung.com>
Thu, 20 Apr 2017 02:00:24 +0000 (11:00 +0900)
committerchleun.moon <chleun.moon@samsung.com>
Thu, 20 Apr 2017 02:00:58 +0000 (11:00 +0900)
Change-Id: I2ecaece689f43bb0c03c9c5929274bfe43e346b0
Signed-off-by: cheoleun <chleun.moon@samsung.com>
21 files changed:
gdhcp/client.c
gsupplicant/gsupplicant.h
gsupplicant/supplicant.c
packaging/connman.spec
plugins/telephony.c
plugins/wifi.c
src/config.c
src/connman.h
src/connman.socket
src/dhcp.c
src/dhcpv6.c
src/inet.c
src/ipconfig.c
src/log.c
src/manager.c
src/network.c
src/provider.c
src/resolver.c
src/rtnl.c
src/service.c
src/technology.c

index 9b2de9d..ff4539b 100755 (executable)
 #define DISCOVER_TIMEOUT 5
 #define DISCOVER_RETRIES 6
 
+#if defined TIZEN_EXT
+#define REQUEST_TIMEOUT 1
+#else
 #define REQUEST_TIMEOUT 5
+#endif
 #define REQUEST_RETRIES 3
 
+#if defined TIZEN_EXT
+#define DISCOVER_TIMEOUT_WIFI 1
+#define DISCOVER_RETRIES_WIFI 10
+static int dhcp_discover_timeout = DISCOVER_TIMEOUT_WIFI;
+static int dhcp_discover_max_retry = DISCOVER_RETRIES_WIFI;
+
+void set_dhcp_discover_timeout(int timeout_value)
+{
+       dhcp_discover_timeout = timeout_value;
+}
+
+void set_dhcp_discover_retry_count(int retry_count)
+{
+       dhcp_discover_max_retry = retry_count;
+}
+#endif
+
 typedef enum _listen_mode {
        L_NONE,
        L2,
@@ -833,16 +854,19 @@ int g_dhcpv6_client_get_timeouts(GDHCPClient *dhcp_client,
                return -EINVAL;
 
        if (T1)
-               *T1 = dhcp_client->T1;
+               *T1 = (dhcp_client->expire == 0xffffffff) ? 0xffffffff:
+                       dhcp_client->T1;
 
        if (T2)
-               *T2 = dhcp_client->T2;
+               *T2 = (dhcp_client->expire == 0xffffffff) ? 0xffffffff:
+                       dhcp_client->T2;
 
        if (started)
                *started = dhcp_client->last_request;
 
        if (expire)
-               *expire = dhcp_client->last_request + dhcp_client->expire;
+               *expire = (dhcp_client->expire == 0xffffffff) ? 0xffffffff:
+                       dhcp_client->last_request + dhcp_client->expire;
 
        return 0;
 }
@@ -2688,6 +2712,11 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
        uint32_t addr;
        uint64_t rand;
 
+#if defined TIZEN_EXT
+       int discover_retry = 0;
+       int timeout = 0;
+#endif
+
        remove_timeouts(dhcp_client);
 
        if (dhcp_client->type == G_DHCP_IPV6) {
@@ -2774,13 +2803,32 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
                return 0;
        }
 
+#if defined TIZEN_EXT
+       if (g_ascii_strncasecmp(dhcp_client->interface, "wlan", 4)
+                       == 0) {
+               discover_retry = DISCOVER_RETRIES_WIFI;
+               timeout = DISCOVER_TIMEOUT_WIFI;
+       } else {
+               discover_retry = DISCOVER_RETRIES;
+               timeout = DISCOVER_TIMEOUT;
+       }
+
+       debug(dhcp_client, "[DHCPC] Discover retry/total : [%d]/[%d] timeout [%d]",
+                       dhcp_client->retry_times, discover_retry, timeout);
+#endif
+
+
        if (dhcp_client->type == G_DHCP_IPV4LL) {
                dhcp_client->state = INIT_SELECTING;
                ipv4ll_start(dhcp_client);
                return 0;
        }
 
-       if (dhcp_client->retry_times == DISCOVER_RETRIES) {
+#if defined TIZEN_EXT
+               if (dhcp_client->retry_times == discover_retry) {
+#else
+               if (dhcp_client->retry_times == DISCOVER_RETRIES) {
+#endif
                if (dhcp_client->no_lease_cb)
                        dhcp_client->no_lease_cb(dhcp_client,
                                                dhcp_client->no_lease_data);
@@ -2823,7 +2871,11 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
 
                dhcp_client->timeout = g_timeout_add_seconds_full(
                                                                G_PRIORITY_HIGH,
+#if defined TIZEN_EXT
+                                                               timeout,
+#else
                                                                REQUEST_TIMEOUT,
+#endif
                                                                reboot_timeout,
                                                                dhcp_client,
                                                                NULL);
@@ -2832,7 +2884,11 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
        send_discover(dhcp_client, addr);
 
        dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+#if defined TIZEN_EXT
+                                                       timeout,
+#else
                                                        DISCOVER_TIMEOUT,
+#endif
                                                        discover_timeout,
                                                        dhcp_client,
                                                        NULL);
@@ -2973,7 +3029,11 @@ char *g_dhcp_client_get_server_address(GDHCPClient *dhcp_client)
        if (!dhcp_client)
                return NULL;
 
+#if defined TIZEN_EXT
+       return get_ip(htonl(dhcp_client->server_ip));
+#else
        return get_ip(dhcp_client->server_ip);
+#endif
 }
 
 char *g_dhcp_client_get_address(GDHCPClient *dhcp_client)
index ffd07b2..fe693cd 100755 (executable)
@@ -293,7 +293,6 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
 
 #if defined TIZEN_EXT
 int g_supplicant_interface_remove_network(GSupplicantInterface *interface);
-int g_supplicant_interface_get_disconnect_reason(GSupplicantInterface *interface);
 #endif
 int g_supplicant_interface_set_apscan(GSupplicantInterface *interface,
                                                        unsigned int ap_scan);
@@ -407,6 +406,8 @@ struct _GSupplicantCallbacks {
                                        GSupplicantPeerState state);
        void (*peer_request) (GSupplicantPeer *peer);
        void (*debug) (const char *str);
+       void (*disconnect_reasoncode)(GSupplicantInterface *interface,
+                                                               int reasoncode);
 };
 
 typedef struct _GSupplicantCallbacks GSupplicantCallbacks;
index c596619..50b0e67 100755 (executable)
@@ -559,6 +559,20 @@ static void callback_peer_request(GSupplicantPeer *peer)
        callbacks_pointer->peer_request(peer);
 }
 
+static void callback_disconnect_reason_code(GSupplicantInterface *interface,
+                                       int reason_code)
+{
+       if (!callbacks_pointer)
+               return;
+
+       if (!callbacks_pointer->disconnect_reasoncode)
+               return;
+
+       if (reason_code != 0)
+               callbacks_pointer->disconnect_reasoncode(interface,
+                                                       reason_code);
+}
+
 static void remove_group(gpointer data)
 {
        GSupplicantGroup *group = data;
@@ -2288,17 +2302,12 @@ static void interface_property(const char *key, DBusMessageIter *iter,
        } else if (g_strcmp0(key, "Networks") == 0) {
                supplicant_dbus_array_foreach(iter, interface_network_added,
                                                                interface);
-#if defined TIZEN_EXT
        } else if (g_strcmp0(key, "DisconnectReason") == 0) {
-               int disconnect_reason = 0;
-
-               dbus_message_iter_get_basic(iter, &disconnect_reason);
-               interface->disconnect_reason = disconnect_reason;
-
-               SUPPLICANT_DBG("disconnect reason (%d)",
-                               interface->disconnect_reason);
-
-#endif
+               int reason_code;
+               if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
+                       dbus_message_iter_get_basic(iter, &reason_code);
+                       callback_disconnect_reason_code(interface, reason_code);
+               }
        } else
                SUPPLICANT_DBG("key %s type %c",
                                key, dbus_message_iter_get_arg_type(iter));
@@ -5705,23 +5714,6 @@ int g_supplicant_interface_remove_network(GSupplicantInterface *interface)
 
        return network_remove(data);
 }
-
-int g_supplicant_interface_get_disconnect_reason(GSupplicantInterface *interface)
-{
-       int reason_code = 0;
-
-       SUPPLICANT_DBG("");
-
-       if (interface == NULL)
-               return -EINVAL;
-
-       if (system_available == FALSE)
-               return -EFAULT;
-
-       reason_code = interface->disconnect_reason;
-
-       return reason_code;
-}
 #endif
 
 static const char *g_supplicant_rule0 = "type=signal,"
index 6cf5b37..f9a90f6 100755 (executable)
@@ -5,7 +5,7 @@
 
 Name:           connman
 Version:        1.29
-Release:        20
+Release:        21
 License:        GPL-2.0+
 Summary:        Connection Manager
 Url:            http://connman.net
@@ -219,10 +219,6 @@ rm %{buildroot}%{_sysconfdir}/dbus-1/system.d/*.conf
 mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d/
 cp src/connman.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/
 
-#License
-mkdir -p %{buildroot}%{_datadir}/license
-cp COPYING %{buildroot}%{_datadir}/license/connman
-
 %if %{with connman_vpnd}
 cp vpn/vpn-dbus.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/connman-vpn-dbus.conf
 %endif
@@ -266,7 +262,7 @@ systemctl daemon-reload
 %attr(644,root,root) %{_libdir}/systemd/system/connman.socket
 %attr(644,root,root) %{_libdir}/systemd/system/sockets.target.wants/connman.socket
 %endif
-%{_datadir}/license/connman
+%license COPYING
 %{upgrade_script_path}/%{upgrade_script_filename}
 
 %files test
@@ -284,6 +280,7 @@ systemctl daemon-reload
 %{_libdir}/connman/plugins-vpn/openconnect.so
 %{_libdir}/connman/scripts/openconnect-script
 %{_datadir}/dbus-1/system-services/net.connman.vpn.service
+%license COPYING
 %endif
 
 %if %{with connman_openvpn}
@@ -292,6 +289,7 @@ systemctl daemon-reload
 %{_libdir}/%{name}/plugins-vpn/openvpn.so
 %{_libdir}/%{name}/scripts/openvpn-script
 %{_datadir}/dbus-1/system-services/net.connman.vpn.service
+%license COPYING
 %endif
 
 %if %{with connman_ipsec}
@@ -311,6 +309,7 @@ systemctl daemon-reload
 %dir %{_libdir}/%{name}/plugins-vpn
 %config %{_sysconfdir}/dbus-1/system.d/connman-vpn-dbus.conf
 %{_datadir}/dbus-1/system-services/net.connman.vpn.service
+%license COPYING
 %endif
 
 %post extension-tv
@@ -318,6 +317,7 @@ mv -f %{_libdir}/systemd/system/connman.service.tv %{_libdir}/systemd/system/con
 mv -f %{_sysconfdir}/connman/main.conf.tv %{_sysconfdir}/connman/main.conf
 %files extension-tv
 %attr(644,root,root) %{_sysconfdir}/connman/main.conf.tv
+%license COPYING
 %if "%{?_lib}" == "lib64"
 %attr(644,root,root) %{_unitdir}/connman.service.tv
 %else
@@ -327,3 +327,5 @@ mv -f %{_sysconfdir}/connman/main.conf.tv %{_sysconfdir}/connman/main.conf
 mv -f %{_sysconfdir}/connman/main.conf.ivi %{_sysconfdir}/connman/main.conf
 %files extension-ivi
 %attr(644,root,root) %{_sysconfdir}/connman/main.conf.ivi
+%license COPYING
+
index 459095d..2b4c5a4 100755 (executable)
@@ -1207,11 +1207,20 @@ static gboolean __set_network_context(
                                                ipv4_netmask, ipv4_gw);
 
        if (ipv4_dns1)
+#if defined TIZEN_EXT
+               __connman_service_nameserver_append(service, ipv4_dns1, FALSE,
+                               CONNMAN_IPCONFIG_TYPE_IPV4);
+#else
                __connman_service_nameserver_append(service, ipv4_dns1, FALSE);
+#endif
        //if (ipv4_dns2)
        if (ipv4_dns2 && !ipv4_dns1)
+#if defined TIZEN_EXT
+               __connman_service_nameserver_append(service, ipv4_dns2, FALSE,
+                               CONNMAN_IPCONFIG_TYPE_IPV4);
+#else
                __connman_service_nameserver_append(service, ipv4_dns2, FALSE);
-
+#endif
        /* ipv6 set */
        if (network->ipv6_address == NULL)
                network->ipv6_address =
@@ -1237,10 +1246,20 @@ static gboolean __set_network_context(
                                                64, ipv6_gw);
 
        if (ipv6_dns1)
+#if defined TIZEN_EXT
+               __connman_service_nameserver_append(service, ipv6_dns1, FALSE,
+                               CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
                __connman_service_nameserver_append(service, ipv6_dns1, FALSE);
+#endif
        //if (ipv6_dns2)
        if (ipv6_dns2 && !ipv6_dns1)
+#if defined TIZEN_EXT
+               __connman_service_nameserver_append(service, ipv6_dns2, FALSE,
+                               CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
                __connman_service_nameserver_append(service, ipv6_dns2, FALSE);
+#endif
 
        if (active == TRUE &&
                        connman_network_get_connected(network->network) == TRUE) {
index 84d0708..7b416fc 100755 (executable)
@@ -134,7 +134,6 @@ struct wifi_data {
        bool allow_full_scan;
 #endif
        int disconnect_code;
-
 };
 
 #if defined TIZEN_EXT
@@ -2638,6 +2637,7 @@ static void interface_state(GSupplicantInterface *interface)
                        break;
 
                connman_network_set_connected(network, true);
+               wifi->disconnect_code = 0;
                break;
 
        case G_SUPPLICANT_STATE_DISCONNECTED:
@@ -2663,10 +2663,6 @@ static void interface_state(GSupplicantInterface *interface)
                                                network, wifi))
                        break;
 
-#if defined TIZEN_EXT
-               wifi->disconnect_code = g_supplicant_interface_get_disconnect_reason(wifi->interface);
-               DBG("Disconnect Reason code %d", wifi->disconnect_code);
-#endif
                /* See table 8-36 Reason codes in IEEE Std 802.11 */
                switch (wifi->disconnect_code) {
                case 1: /* Unspecified reason */
@@ -3402,6 +3398,17 @@ static void debug(const char *str)
                connman_debug("%s", str);
 }
 
+static void disconnect_reasoncode(GSupplicantInterface *interface,
+                               int reasoncode)
+{
+       struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+
+       if (wifi != NULL) {
+               wifi->disconnect_code = reasoncode;
+       }
+}
+
+
 static const GSupplicantCallbacks callbacks = {
        .system_ready           = system_ready,
        .system_killed          = system_killed,
@@ -3424,6 +3431,7 @@ static const GSupplicantCallbacks callbacks = {
        .system_power_off       = system_power_off,
        .network_merged = network_merged,
 #endif
+       .disconnect_reasoncode  = disconnect_reasoncode,
        .debug                  = debug,
 };
 
index 3818fb8..25dd174 100755 (executable)
@@ -1097,6 +1097,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)
 {
@@ -1279,8 +1293,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
                }
        }
 
index 2217cc4..7c44d1c 100755 (executable)
@@ -169,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,
@@ -452,6 +455,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);
 
@@ -667,6 +675,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
+
 struct connman_service *__connman_service_lookup_from_index(int index);
 struct connman_service *__connman_service_lookup_from_ident(const char *identifier);
 struct connman_service *__connman_service_create_from_network(struct connman_network *network);
@@ -755,10 +772,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);
index 8827498..5d0a280 100644 (file)
@@ -4,7 +4,7 @@ Before=connman.service
 
 [Socket]
 ListenStream=127.0.0.1:53
-ListenDatagram=127.0.0.1:53
+ListenDatagram=0.0.0.0:53
 FreeBind=true
 SmackLabelIPIn=*
 SmackLabelIPOut=@
index 644aac6..0a2f6fc 100755 (executable)
@@ -111,8 +111,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,
+                                               CONNMAN_IPCONFIG_TYPE_IPV4);
+#else
                        __connman_service_nameserver_remove(service,
                                                dhcp->nameservers[i], false);
+#endif
                }
        }
 
@@ -251,9 +257,12 @@ static void no_lease_cb(GDHCPClient *dhcp_client, gpointer user_data)
        DBG("No lease available ipv4ll %d client %p", ipv4ll_running,
                dhcp->ipv4ll_client);
 
+       if (dhcp->timeout > 0)
+               g_source_remove(dhcp->timeout);
+
        dhcp->timeout = g_timeout_add_seconds(RATE_LIMIT_INTERVAL,
-                                               dhcp_retry_cb,
-                                               dhcp);
+                       dhcp_retry_cb,
+                       dhcp);
        if (ipv4ll_running)
                return;
 
@@ -359,18 +368,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);
@@ -416,7 +439,7 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
        char *address, *netmask = NULL, *gateway = NULL;
        const char *c_address, *c_gateway;
        unsigned char prefixlen, c_prefixlen;
-       bool ip_change;
+       bool ip_change = false;
 
        DBG("Lease available");
 
@@ -448,14 +471,21 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
 
        DBG("c_address %s", c_address);
 
-       if (g_strcmp0(address, c_address))
+       if (g_strcmp0(address, c_address)) {
                ip_change = true;
-       else if (g_strcmp0(gateway, c_gateway))
+               if (c_address) {
+                       /* Remove old ip address */
+                       __connman_ipconfig_address_remove(dhcp->ipconfig);
+               }
+       }
+       if (g_strcmp0(gateway, c_gateway)) {
                ip_change = true;
-       else if (prefixlen != c_prefixlen)
+               if (c_gateway) {
+                       /* Remove gateway ip address */
+                       __connman_ipconfig_gateway_remove(dhcp->ipconfig);
+               }
+       } else if (prefixlen != c_prefixlen)
                ip_change = true;
-       else
-               ip_change = false;
 
        __connman_ipconfig_set_method(dhcp->ipconfig,
                                                CONNMAN_IPCONFIG_METHOD_DHCP);
@@ -480,24 +510,11 @@ done:
 static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data)
 {
        struct connman_dhcp *dhcp = user_data;
-#if !defined TIZEN_EXT
                char *address, *netmask;
                unsigned char prefixlen;
-#endif
 
        DBG("IPV4LL available");
 
-#if defined TIZEN_EXT
-               /*
-                * Description: When DHCP is failed,
-                *               most of normal users cannot understand auto-generated IP
-                *              (IPV4 link local) and serious troubles to make Internet connection.
-                */
-               dhcp_invalidate(dhcp, true);
-
-               connman_network_set_error(dhcp->network,
-                                       CONNMAN_NETWORK_ERROR_DHCP_FAIL);
-#else
        address = g_dhcp_client_get_address(ipv4ll_client);
        netmask = g_dhcp_client_get_netmask(ipv4ll_client);
 
@@ -513,7 +530,6 @@ static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data)
 
        g_free(address);
        g_free(netmask);
-#endif
 }
 
 static int dhcp_initialize(struct connman_dhcp *dhcp)
@@ -628,7 +644,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;
 
@@ -642,7 +660,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) {
@@ -674,7 +694,14 @@ 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)
index db9feb6..bf4da3e 100755 (executable)
@@ -327,9 +327,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);
                }
 
@@ -337,9 +347,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);
 
@@ -397,7 +417,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);
@@ -522,9 +544,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);
                }
 
@@ -532,9 +564,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);
 
@@ -1192,12 +1234,17 @@ static int check_restart(struct connman_dhcpv6 *dhcp)
 
        g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, NULL, NULL,
                                NULL, &expired);
+
+       /* infinite lifetime for an DHCPv6 address */
+       if (expired == 0xffffffff)
+               return -EISCONN;
+
        current = time(NULL);
 
        if (current >= expired) {
                DBG("expired by %d secs", (int)(current - expired));
 
-               g_timeout_add(0, dhcpv6_restart, dhcp);
+               g_idle_add(dhcpv6_restart, dhcp);
 
                return -ETIMEDOUT;
        }
@@ -1456,8 +1503,7 @@ int __connman_dhcpv6_start_renew(struct connman_network *network,
                        /* RFC 3315, chapter 18.1.3, start rebind */
                        DBG("start rebind immediately");
 
-                       dhcp->timeout = g_timeout_add_seconds(0, start_rebind,
-                                                       dhcp);
+                       dhcp->timeout = g_idle_add(start_rebind, dhcp);
 
                } else if ((unsigned)current < (unsigned)started + T1) {
                        delta = started + T1 - current;
@@ -1729,7 +1775,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);
@@ -2046,7 +2094,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);
@@ -2159,7 +2209,7 @@ static int check_pd_restart(struct connman_dhcpv6 *dhcp)
        if (current > expired) {
                DBG("expired by %d secs", (int)(current - expired));
 
-               g_timeout_add(0, dhcpv6_restart, dhcp);
+               g_idle_add(dhcpv6_restart, dhcp);
 
                return -ETIMEDOUT;
        }
index 972fdff..fcffab8 100755 (executable)
@@ -1340,6 +1340,37 @@ static int icmpv6_recv(int fd, gpointer user_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));
index 8987ab1..8d1db29 100755 (executable)
@@ -410,7 +410,20 @@ static void free_ipdevice(gpointer data)
 static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice)
 {
        DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
-                                       ipdevice->config_ipv6);
+                       ipdevice->config_ipv6);
+#if defined TIZEN_EXT
+       if (ipdevice->config_ipv6 != NULL &&
+                       ipdevice->config_ipv6->enabled == TRUE)
+               return;
+
+       char *ifname = connman_inet_ifname(ipdevice->index);
+
+       if (__connman_device_isfiltered(ifname) == FALSE) {
+               ipdevice->ipv6_enabled = get_ipv6_state(ifname);
+               set_ipv6_state(ifname, FALSE);
+       }
+       g_free(ifname);
+#endif
 }
 
 static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
@@ -1708,6 +1721,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;
@@ -1821,8 +1839,6 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
        struct connman_ipaddress *append_addr = NULL;
        const char *str;
 
-       DBG("");
-
        if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
                return;
 
@@ -1874,6 +1890,18 @@ 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);
+               }
+       }
+#endif
 }
 
 void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
@@ -1883,8 +1911,6 @@ void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
        struct connman_ipaddress *append_addr = NULL;
        const char *str, *privacy;
 
-       DBG("");
-
        if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
                return;
 
@@ -1946,8 +1972,6 @@ void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
 {
        const char *str, *privacy;
 
-       DBG("");
-
        str = __connman_ipconfig_method2string(ipconfig->method);
        if (!str)
                return;
@@ -1990,8 +2014,6 @@ void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
 {
        const char *str;
 
-       DBG("");
-
        str = __connman_ipconfig_method2string(ipconfig->method);
        if (!str)
                return;
@@ -2123,7 +2145,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:
@@ -2133,7 +2158,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:
index 7a8e7c6..1dbd41a 100755 (executable)
--- a/src/log.c
+++ b/src/log.c
@@ -216,7 +216,6 @@ void connman_error(const char *format, ...)
        vsyslog(LOG_ERR, format, ap);
 
        va_end(ap);
-       fflush(log_file);
 }
 
 /**
@@ -235,7 +234,6 @@ void connman_debug(const char *format, ...)
        vsyslog(LOG_DEBUG, format, ap);
 
        va_end(ap);
-       fflush(log_file);
 }
 
 static void print_backtrace(unsigned int offset)
index bd52f39..32705e4 100755 (executable)
@@ -140,7 +140,9 @@ static DBusMessage *get_technologies(DBusConnection *conn,
 {
        DBusMessage *reply;
 
+#if !defined TIZEN_EXT
        DBG("");
+#endif
 
        reply = dbus_message_new_method_return(msg);
        if (!reply)
index 8687619..c57d70e 100755 (executable)
@@ -111,6 +111,8 @@ struct connman_network {
 
 };
 
+static void autoconf_ipv6_set(struct connman_network *network);
+
 static const char *type2string(enum connman_network_type type)
 {
        switch (type) {
@@ -223,12 +225,27 @@ static void dhcp_callback(struct connman_ipconfig *ipconfig,
                        struct connman_network *network,
                        bool success, gpointer data)
 {
+#if defined TIZEN_EXT
+       struct connman_service *service;
+       struct connman_ipconfig *ipconfig_ipv6;
+#endif
+
        network->connecting = false;
 
        if (success)
                dhcp_success(network);
        else
                dhcp_failure(network);
+
+#if defined TIZEN_EXT
+       service = connman_service_lookup_from_network(network);
+       ipconfig_ipv6 = __connman_service_get_ip6config(service);
+       if (__connman_ipconfig_get_method(ipconfig_ipv6) == CONNMAN_IPCONFIG_METHOD_AUTO) {
+               DBG("IPv6 autoconf start");
+               set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV6);
+               autoconf_ipv6_set(network);
+       }
+#endif
 }
 
 static int set_connected_manual(struct connman_network *network)
@@ -387,7 +404,6 @@ err:
        return err;
 }
 
-static void autoconf_ipv6_set(struct connman_network *network);
 static void dhcpv6_callback(struct connman_network *network,
                        enum __connman_dhcpv6_status status, gpointer data);
 
@@ -502,11 +518,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;
@@ -1307,8 +1333,35 @@ static gboolean __connman_network_clear_associating_delayed(gpointer user_data)
 
        if (network->associating == FALSE &&
                        state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION &&
-                       state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION)
-               connman_network_clear_associating(network);
+                       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;
 }
@@ -1729,6 +1782,29 @@ 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)
 {
@@ -1750,7 +1826,9 @@ int __connman_network_enable_ipconfig(struct connman_network *network,
                return -ENOSYS;
 
        case CONNMAN_IPCONFIG_TYPE_IPV6:
+#if !defined TIZEN_EXT
                set_configuration(network, type);
+#endif
 
                method = __connman_ipconfig_get_method(ipconfig);
 
@@ -1773,11 +1851,16 @@ int __connman_network_enable_ipconfig(struct connman_network *network,
                                CONNMAN_SERVICE_STATE_CONFIGURATION,
                                        CONNMAN_IPCONFIG_TYPE_IPV6);
 #endif
+#if !defined TIZEN_EXT
                        autoconf_ipv6_set(network);
+#endif
                        break;
 
                case CONNMAN_IPCONFIG_METHOD_FIXED:
                case CONNMAN_IPCONFIG_METHOD_MANUAL:
+#if defined TIZEN_EXT
+                       set_configuration(network, type);
+#endif
                        r = manual_ipv6_set(network, ipconfig);
                        break;
 
@@ -2018,8 +2101,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);
index 22ff08a..521346b 100755 (executable)
@@ -576,8 +576,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;
 }
index fae02a8..8a7fa66 100755 (executable)
@@ -301,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);
@@ -392,8 +398,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
                }
        }
 
index 42ebd4a..b7d7f37 100755 (executable)
@@ -1314,6 +1314,34 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr)
        if (index < 0)
                return;
 
+#if defined TIZEN_EXT
+       struct connman_service *service;
+       enum connman_dnsconfig_method ipv6_dns_method;
+       char *ifname;
+
+       service = __connman_service_lookup_from_index(index);
+       if (!service || !(__connman_service_index_is_default(index))) {
+               DBG("Invalid service, index: %d\n", index);
+               return;
+       }
+
+       DBG("service: %p index: %d\n", service, index);
+
+       ifname = connman_inet_ifname(index);
+       if (ifname == NULL) {
+               DBG("Interface is NULL, return");
+               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);
+               g_free(ifname);
+               return;
+       }
+       g_free(ifname);
+#endif
+
        for (opt = (void *)&msg[1];
                        msglen > 0;
                        msglen -= opt->nd_opt_len * 8,
@@ -1326,16 +1354,23 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr)
                        char buf[40];
 
                        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 */
                        g_free(domains);
 
index f561170..772c89f 100755 (executable)
@@ -77,14 +77,6 @@ struct connman_service_user {
        uid_t current_user;
 };
 
-#ifdef TIZEN_EXT
-enum connman_dnsconfig_method {
-       CONNMAN_DNSCONFIG_METHOD_UNKNOWN = 0,
-       CONNMAN_DNSCONFIG_METHOD_MANUAL  = 1,
-       CONNMAN_DNSCONFIG_METHOD_DHCP    = 2,
-};
-#endif
-
 struct connman_service {
        int refcount;
        char *identifier;
@@ -166,7 +158,8 @@ struct connman_service {
        int disconnect_reason;
 #endif
 #ifdef TIZEN_EXT
-       enum connman_dnsconfig_method dns_config_method;
+       enum connman_dnsconfig_method dns_config_method_ipv4;
+       enum connman_dnsconfig_method dns_config_method_ipv6;
 #endif
 };
 
@@ -756,11 +749,14 @@ static int service_load(struct connman_service *service)
 
 #ifdef TIZEN_EXT
        char *dns_method;
-       if (TIZEN_TV_EXT) {
-               dns_method = g_key_file_get_string(keyfile, service->identifier,
-                               "Nameservers.method", NULL);
-               service->dns_config_method = __connman_dnsconfig_string2method(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,
@@ -999,18 +995,26 @@ static int service_save(struct connman_service *service)
        g_key_file_remove_key(keyfile, service->identifier,
                                                        "Nameservers", NULL);
 
-#ifdef TIZEN_EXT
-       if (TIZEN_TV_EXT) {
-               if(service->dns_config_method != 0) {
-                       const char *method;
-                       method = __connman_dnsconfig_method2string(
-                                       service->dns_config_method);
-                       g_key_file_set_string(keyfile, service->identifier,
-                                       "Nameservers.method", method);
-               } else
-               g_key_file_remove_key(keyfile, service->identifier,
-                                                       "Nameservers.method", 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) {
@@ -1332,25 +1336,137 @@ static int nameserver_add(struct connman_service *service,
        if (index < 0)
                return -ENXIO;
 
+#if defined TIZEN_EXT
+       DBG("Resolver append nameserver: %s", nameserver);
+#endif
        return connman_resolver_append(index, NULL, nameserver);
 }
 
+#if defined TIZEN_EXT
+static int nameserver_add_all(struct connman_service *service,
+               enum connman_ipconfig_type type)
+#else
 static int nameserver_add_all(struct connman_service *service)
+#endif
 {
        int i = 0;
 
        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) {
+                               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,
+                                                      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,
+                                                      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,
+                                                      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,
+                                                      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, service->nameservers_config[i]);
+#endif
                        i++;
                }
-
+#if !defined TIZEN_EXT
                return 0;
+#endif
        }
 
+#if defined TIZEN_EXT
+       i = 0;
+#endif
        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,
+                                                      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,
+                                                      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,
+                                                      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,
+                                                      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, service->nameservers[i]);
+#endif
                        i++;
                }
        }
@@ -1373,7 +1489,12 @@ static int nameserver_remove(struct connman_service *service,
        return connman_resolver_remove(index, NULL, nameserver);
 }
 
+#if defined TIZEN_EXT
+static int nameserver_remove_all(struct connman_service *service,
+               enum connman_ipconfig_type type)
+#else
 static int nameserver_remove_all(struct connman_service *service)
+#endif
 {
 #if defined TIZEN_EXT
        /**
@@ -1391,14 +1512,123 @@ 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,
+                                                 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,
+                                                 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,
+                                                 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,
+                                                 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, 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,
+                                                         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,
+                                                         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,
+                                                         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,
+                                                         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, service->nameservers[i]);
+#endif
                i++;
        }
 
@@ -1460,13 +1690,19 @@ static int searchdomain_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;
@@ -1477,8 +1713,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);
@@ -1498,23 +1741,38 @@ int __connman_service_nameserver_append(struct connman_service *service,
        nameservers[len + 1] = NULL;
 
 #ifdef TIZEN_EXT
-       if(TIZEN_TV_EXT &&
-          service->dns_config_method == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
-               service->dns_config_method = CONNMAN_DNSCONFIG_METHOD_DHCP;
+       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 {
                service->nameservers = nameservers;
+#if defined TIZEN_EXT
+               DBG("nameserver add: %s, type: %d", nameserver, type);
+#endif
                nameserver_add(service, nameserver);
        }
 
        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;
@@ -1580,12 +1838,23 @@ set_servers:
 
 void __connman_service_nameserver_clear(struct connman_service *service)
 {
+#if defined TIZEN_EXT
+       DBG("nameserver remove all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
+       nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
+#else
        nameserver_remove_all(service);
+#endif
 
        g_strfreev(service->nameservers);
        service->nameservers = NULL;
 
+#if defined TIZEN_EXT
+       DBG("nameserver add all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
+       nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
+#else
        nameserver_add_all(service);
+#endif
+
 }
 
 static void add_nameserver_route(int family, int index, char *nameserver,
@@ -2112,31 +2381,141 @@ 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, 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, 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))
                return;
 
 #ifdef TIZEN_EXT
        const char *str;
-       if (TIZEN_TV_EXT) {
-               /* Append DNS Config Type */
-               str = __connman_dnsconfig_method2string(service->dns_config_method);
-               if(str != NULL)
-                       dbus_message_iter_append_basic(iter,
-                               DBUS_TYPE_STRING, &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,
@@ -2161,18 +2540,43 @@ static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
 #ifdef TIZEN_EXT
        /* Append DNS Config Type */
        const char *str;
-       if (TIZEN_TV_EXT) {
-               str = __connman_dnsconfig_method2string(service->dns_config_method);
-               if(str != NULL)
-                       dbus_message_iter_append_basic(iter,
-                               DBUS_TYPE_STRING, &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)
@@ -2806,12 +3210,10 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
                                                DBUS_TYPE_STRING, &str);
 
 #ifdef TIZEN_EXT
-       if (TIZEN_TV_EXT) {
-               str = state2string(service->state_ipv6);
-               if (str != NULL)
-                       connman_dbus_dict_append_basic(dict, "StateIPv6",
-                                                       DBUS_TYPE_STRING, &str);
-       }
+       str = state2string(service->state_ipv6);
+       if (str != NULL)
+               connman_dbus_dict_append_basic(dict, "StateIPv6",
+                               DBUS_TYPE_STRING, &str);
 #endif
 
        str = error2string(service->error);
@@ -2867,7 +3269,7 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
                                                append_ethernet, service);
 
                connman_dbus_dict_append_basic(dict, "DisconnectReason",
-                               DBUS_TYPE_INT32, &service->disconnect_reason);
+                               DBUS_TYPE_UINT32, &service->disconnect_reason);
 
                break;
 #endif
@@ -3238,6 +3640,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)
 {
@@ -3841,6 +4255,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)
@@ -3863,22 +4281,55 @@ static DBusMessage *set_property(DBusConnection *conn,
 
                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
-                       if (TIZEN_TV_EXT) {
-                               /* First unpack the DNS Config Method */
-                               if(g_strcmp0(val, "manual") == 0) {
-                                       service->dns_config_method =
-                                               CONNMAN_DNSCONFIG_METHOD_MANUAL;
-                                       continue;
-                               } else if(g_strcmp0(val, "dhcp") == 0) {
-                                       service->dns_config_method =
-                                               CONNMAN_DNSCONFIG_METHOD_DHCP;
-                                       continue;
+                       /* 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 (connman_inet_check_ipaddress(val) > 0) {
@@ -3889,7 +4340,21 @@ static DBusMessage *set_property(DBusConnection *conn,
                        }
                }
 
+#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);
+#endif
                g_strfreev(service->nameservers_config);
 
                if (str->len > 0) {
@@ -3904,7 +4369,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);
+#endif
                dns_configuration_changed(service);
 
                if (__connman_service_is_connected_state(service,
@@ -4867,6 +5337,15 @@ bool __connman_service_remove(struct connman_service *service)
        __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);
@@ -5144,17 +5623,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);
        }
@@ -6956,7 +7441,16 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
 
        if (is_connected_state(service, old_state) &&
                        !is_connected_state(service, new_state))
+#if defined TIZEN_EXT
+       {
+               DBG("nameserver remove all, type: %d", type);
+               nameserver_remove_all(service, type);
+#else
                nameserver_remove_all(service);
+#endif
+#if defined TIZEN_EXT
+       }
+#endif
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                service->state_ipv4 = new_state;
@@ -6965,7 +7459,16 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
 
        if (!is_connected_state(service, old_state) &&
                        is_connected_state(service, new_state))
+#if defined TIZEN_EXT
+       {
+               DBG("nameserver add all, type: %d", type);
+               nameserver_add_all(service, type);
+#else
                nameserver_add_all(service);
+#endif
+#if defined TIZEN_EXT
+       }
+#endif
 
 #if defined TIZEN_EXT
        int ret = service_indicate_state(service);
@@ -7557,6 +8060,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);
 
@@ -7568,9 +8074,19 @@ 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)
+                       __connman_connection_gateway_activate(service,
+                                       CONNMAN_IPCONFIG_TYPE_IPV6);
+       }
+#else
                __connman_service_ipconfig_indicate_state(service,
                                                CONNMAN_SERVICE_STATE_READY,
                                                CONNMAN_IPCONFIG_TYPE_IPV6);
+#endif
 
        settings_changed(service, ipconfig);
 }
index d5d4a40..6a69b4e 100755 (executable)
@@ -1031,9 +1031,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,
@@ -1066,6 +1095,8 @@ void __connman_technology_scan_stopped(struct connman_device *device,
 #if defined TIZEN_EXT
        if (count == 0) {
                DBusMessage *signal;
+               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");
@@ -1137,6 +1168,42 @@ static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
        return NULL;
 }
 
+#if defined TIZEN_EXT
+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}" }),
@@ -1145,6 +1212,10 @@ 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_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
+                       get_scan_state) },
+#endif
        { },
 };