Updated connman to version 1.35
[platform/upstream/connman.git] / gdhcp / client.c
old mode 100644 (file)
new mode 100755 (executable)
index 3e67fcd..5a455f0
 #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,
@@ -156,6 +177,10 @@ struct _GDHCPClient {
        bool retransmit;
        struct timeval start_time;
        bool request_bcast;
+#if defined TIZEN_EXT
+       uint32_t dhcp_lease_seconds;
+       gboolean init_reboot;
+#endif
 };
 
 static inline void debug(GDHCPClient *client, const char *format, ...)
@@ -480,6 +505,9 @@ static int send_request(GDHCPClient *dhcp_client)
        init_packet(dhcp_client, &packet, DHCPREQUEST);
 
        packet.xid = dhcp_client->xid;
+#if defined TIZEN_EXT
+       if (dhcp_client->init_reboot != TRUE)
+#endif
        packet.secs = dhcp_attempt_secs(dhcp_client);
 
        if (dhcp_client->state == REQUESTING || dhcp_client->state == REBOOTING)
@@ -1516,6 +1544,21 @@ static gboolean request_timeout(gpointer user_data)
 {
        GDHCPClient *dhcp_client = user_data;
 
+#if defined TIZEN_EXT
+       if (dhcp_client->init_reboot) {
+               debug(dhcp_client, "DHCPREQUEST of INIT-REBOOT has failed");
+
+               /* Start DHCPDISCOVERY when DHCPREQUEST of INIT-REBOOT has failed */
+               g_dhcp_client_set_address_known(dhcp_client, FALSE);
+
+               dhcp_client->retry_times = 0;
+               dhcp_client->requested_ip = 0;
+
+               g_dhcp_client_start(dhcp_client, dhcp_client->last_address);
+
+               return FALSE;
+       }
+#endif
        debug(dhcp_client, "request timeout (retries %d)",
                                        dhcp_client->retry_times);
 
@@ -1817,71 +1860,6 @@ static char *get_ip(uint32_t ip)
        return g_strdup(inet_ntoa(addr));
 }
 
-/* get a rough idea of how long an option will be */
-static const uint8_t len_of_option_as_string[] = {
-       [OPTION_IP] = sizeof("255.255.255.255 "),
-       [OPTION_STRING] = 1,
-       [OPTION_U8] = sizeof("255 "),
-       [OPTION_U16] = sizeof("65535 "),
-       [OPTION_U32] = sizeof("4294967295 "),
-};
-
-static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
-{
-       return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
-}
-
-/* Create "opt_value1 option_value2 ..." string */
-static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
-{
-       unsigned upper_length;
-       int len, optlen;
-       char *dest, *ret;
-
-       len = option[OPT_LEN - OPT_DATA];
-       type &= OPTION_TYPE_MASK;
-       optlen = dhcp_option_lengths[type];
-       if (optlen == 0)
-               return NULL;
-       upper_length = len_of_option_as_string[type] *
-                       ((unsigned)len / (unsigned)optlen);
-       dest = ret = g_malloc(upper_length + 1);
-       if (!ret)
-               return NULL;
-
-       while (len >= optlen) {
-               switch (type) {
-               case OPTION_IP:
-                       dest += sprint_nip(dest, "", option);
-                       break;
-               case OPTION_U16: {
-                       uint16_t val_u16 = get_be16(option);
-                       dest += sprintf(dest, "%u", val_u16);
-                       break;
-               }
-               case OPTION_U32: {
-                       uint32_t val_u32 = get_be32(option);
-                       dest += sprintf(dest, "%u", val_u32);
-                       break;
-               }
-               case OPTION_STRING:
-                       memcpy(dest, option, len);
-                       dest[len] = '\0';
-                       return ret;
-               default:
-                       break;
-               }
-               option += optlen;
-               len -= optlen;
-               if (len <= 0)
-                       break;
-               *dest++ = ' ';
-               *dest = '\0';
-       }
-
-       return ret;
-}
-
 static GList *get_option_value_list(char *value, GDHCPOptionType type)
 {
        char *pos = value;
@@ -2405,6 +2383,10 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 
                        dhcp_client->lease_seconds = get_lease(&packet);
 
+#if defined TIZEN_EXT
+                       dhcp_client->dhcp_lease_seconds = dhcp_client->lease_seconds;
+#endif
+
                        get_request(dhcp_client, &packet);
 
                        switch_listening_mode(dhcp_client, L_NONE);
@@ -2429,6 +2411,18 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 
                        remove_timeouts(dhcp_client);
 
+#if defined TIZEN_EXT
+                       if (dhcp_client->init_reboot) {
+                               g_dhcp_client_set_address_known(dhcp_client, FALSE);
+                               dhcp_client->timeout = g_idle_add_full(
+                                                               G_PRIORITY_HIGH,
+                                                               restart_dhcp_timeout,
+                                                               dhcp_client,
+                                                               NULL);
+
+                               break;
+                       }
+#endif
                        dhcp_client->timeout = g_timeout_add_seconds_full(
                                                        G_PRIORITY_HIGH, 3,
                                                        restart_dhcp_timeout,
@@ -2666,6 +2660,11 @@ static gboolean ipv4ll_announce_timeout(gpointer dhcp_data)
        GDHCPClient *dhcp_client = dhcp_data;
        uint32_t ip;
 
+#if defined TIZEN_EXT
+       if (!dhcp_client)
+               return FALSE;
+#endif
+
        debug(dhcp_client, "request timeout (retries %d)",
               dhcp_client->retry_times);
 
@@ -2717,6 +2716,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) {
@@ -2803,13 +2807,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);
@@ -2852,7 +2875,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);
@@ -2861,7 +2888,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);
@@ -3002,8 +3033,19 @@ 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
+}
+
+#if defined TIZEN_EXT
+int g_dhcp_client_get_dhcp_lease_duration(GDHCPClient *dhcp_client)
+{
+       return dhcp_client->dhcp_lease_seconds;
 }
+#endif
 
 char *g_dhcp_client_get_address(GDHCPClient *dhcp_client)
 {
@@ -3230,6 +3272,9 @@ void g_dhcp_client_unref(GDHCPClient *dhcp_client)
        g_hash_table_destroy(dhcp_client->send_value_hash);
 
        g_free(dhcp_client);
+#if defined TIZEN_EXT
+       dhcp_client = NULL;
+#endif
 }
 
 void g_dhcp_client_set_debug(GDHCPClient *dhcp_client,
@@ -3265,3 +3310,19 @@ GSList *g_dhcpv6_copy_prefixes(GSList *prefixes)
 
        return copy;
 }
+
+#if defined TIZEN_EXT
+void g_dhcp_client_set_address_known(GDHCPClient *dhcp_client, gboolean known)
+{
+       /* DHCPREQUEST during INIT-REBOOT state (rfc2131)
+        * 4.4.3 Initialization with known network address
+        * 4.3.2 DHCPREQUEST generated during INIT-REBOOT state
+        */
+       debug(dhcp_client, "known network address (%d)", known);
+
+       if (dhcp_client->init_reboot == known)
+               return;
+
+       dhcp_client->init_reboot = known;
+}
+#endif