From: Kitae Kim Date: Mon, 4 Aug 2014 08:42:24 +0000 (+0900) Subject: tethering: fix connection routine. X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~273 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5eea3af6cb2ee0020d83c93e7eb40dd0f207a5eb;p=sdk%2Femulator%2Fqemu.git tethering: fix connection routine. 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 --- diff --git a/tizen/src/tethering/common.c b/tizen/src/tethering/common.c index b2d42c8587..201b9e4e11 100644 --- a/tizen/src/tethering/common.c +++ b/tizen/src/tethering/common.c @@ -31,6 +31,7 @@ #include #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