tethering: fix connection routine.
authorKitae Kim <kt920.kim@samsung.com>
Mon, 4 Aug 2014 08:42:24 +0000 (17:42 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Tue, 5 Aug 2014 07:41:11 +0000 (16:41 +0900)
When client socket connects to server, connection routine was not enough
to handle some error cases, EALREADY or EISCONN.

Change-Id: I3362c039dd840825b22a3861b515641db31b0de3
Signed-off-by: Kitae Kim <kt920.kim@samsung.com>
tizen/src/tethering/common.c

index b2d42c8587d7aa06f382c8851fa73384dd2ee9ed..201b9e4e1164a98d39dfd880537aeecb0d53e76f 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/ioctl.h>
 #else
 #define EISCONN WSAEISCONN
+#define EALREADY WSAEALREADY
 #endif
 
 #include "qemu-common.h"
@@ -391,6 +392,7 @@ static bool msgproc_tethering_event_msg(Tethering__EventMsg *msg)
         break;
     case TETHERING__EVENT_MSG__TYPE__TERMINATE:
         break;
+
     default:
         TRACE("invalid event_msg type\n");
         ret = false;
@@ -608,7 +610,6 @@ static int start_tethering_socket(const char *ipaddress, int port)
     int sock = -1;
     int ret = 0;
 
-
     addr.sin_family = AF_INET;
     addr.sin_port = htons(port); // i.e. 1234
 
@@ -637,18 +638,56 @@ static int start_tethering_socket(const char *ipaddress, int port)
     qemu_set_nonblock(sock);
 
     set_tethering_connection_status(CONNECTING);
-    do {
-        if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-            perror("connect failure");
-            ret = -socket_error();
-        } else {
+
+    while (1) {
+       ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
+
+       if (ret == 0) {
             INFO("tethering socket is connected.\n");
-            ret = 0;
-            // set_tethering_app_state(true);
             break;
+        } else {
+            int connection_errno = socket_error();
+
+            if (connection_errno == EINPROGRESS) {
+                fd_set writefds;
+                struct timeval timeout;
+
+                INFO("connection is progressing\n");
+
+                FD_ZERO(&writefds);
+                FD_SET(sock, &writefds);
+
+                timeout.tv_sec = 1;
+                timeout.tv_usec = 0;
+
+                if (select(sock + 1, NULL, &writefds, NULL, &timeout) > 0) {
+                    int opt;
+                    socklen_t opt_size = sizeof(opt);
+
+                    qemu_getsockopt(sock, SOL_SOCKET, SO_ERROR, &opt, &opt_size);
+                    if (opt) {
+                        ERR("error in connection %d - %s\n", opt, strerror(opt));
+                    } else {
+                        INFO("timeout or error is %d - %s\n", opt, strerror(opt));
+                    }
+                } else {
+                    INFO("error connection %d - %s\n", errno, strerror(errno));
+                }
+                continue;
+            } else if (connection_errno == EALREADY) {
+                ret = 0;
+                INFO("a previous connection has not yet been completed\n");
+                continue;
+            } else if (connection_errno == EISCONN) {
+                ret = 0;
+                INFO("connection is already connected\n");
+                break;
+            } else {
+                perror("connect failure");
+                ret = -connection_errno;
+            }
         }
-        TRACE("ret: %d\n", ret);
-    } while (ret == -EINPROGRESS);
+    }
 
     if (ret < 0 && ret != -EISCONN) {
         if (ret == -ECONNREFUSED) {
@@ -667,6 +706,8 @@ static void end_tethering_socket(int sockfd)
 {
     int status = TETHERING__STATE__DISABLED;
 
+    TRACE("enter: %s\n", __func__);
+
     if (closesocket(sockfd) < 0) {
         perror("closesocket failure");
         return;
@@ -678,6 +719,8 @@ static void end_tethering_socket(int sockfd)
     set_tethering_connection_status(DISCONNECTED);
     set_tethering_sensor_status(status);
     set_tethering_touch_status(status);
+
+    TRACE("leave: %s\n", __func__);
 }
 
 #if 0
@@ -769,23 +812,17 @@ int disconnect_tethering_app(void)
 
     INFO("disconnect app from ecp\n");
     if (!tethering_client) {
+        ERR("tethering client instance is NULL\n");
         return -1;
     }
 
     sock = tethering_client->fd;
     if (sock < 0) {
         ERR("tethering socket is terminated or not ready\n");
+        return -1;
     } else {
-        // destroy_tethering_io_handler(sock);
-#if 0
-        if (get_tethering_app_state()) {
-            send_emul_state_msg();
-        }
-#endif
         send_emul_state_msg();
-
         end_tethering_socket(sock);
-        // release_tethering_thread(tethering_client);
     }
 
     return 0;
@@ -816,39 +853,38 @@ static int tethering_loop(int sockfd)
 
 static void *initialize_tethering_socket(void *opaque)
 {
-    TetheringState *socket = (TetheringState *)opaque;
+    TetheringState *client = (TetheringState *)opaque;
     TRACE("callback function for tethering_thread\n");
 
-    if (!socket) {
+    if (!client) {
         ERR("TetheringState is NULL\n");
         return NULL;
     }
 
-    socket->fd = start_tethering_socket(socket->ipaddress, socket->port);
-    if (socket->fd < 0) {
+    client->fd = start_tethering_socket(client->ipaddress, client->port);
+    if (client->fd < 0) {
         ERR("failed to start tethering_socket\n");
         // tethering_sock = -1;
         return NULL;
     }
-
-    INFO("tethering_sock: %d\n", socket->fd);
+    TRACE("tethering_sock: %d\n", client->fd);
 
     reset_tethering_recv_buf(&recv_buf);
     send_handshake_req_msg();
 
     while (1) {
-        qemu_mutex_lock(&socket->mutex);
-        if (socket->status == DISCONNECTED) {
-            qemu_mutex_unlock(&socket->mutex);
+        qemu_mutex_lock(&client->mutex);
+        if (client->status == DISCONNECTED) {
+            qemu_mutex_unlock(&client->mutex);
             INFO("disconnected socket. destroy this thread\n");
             break;
         }
-        qemu_mutex_unlock(&socket->mutex);
+        qemu_mutex_unlock(&client->mutex);
 
-        tethering_loop(socket->fd);
+        tethering_loop(client->fd);
     }
 
-    return socket;
+    return client;
 }
 
 #if 0