#include <sys/ioctl.h>
#else
#define EISCONN WSAEISCONN
+#define EALREADY WSAEALREADY
#endif
#include "qemu-common.h"
break;
case TETHERING__EVENT_MSG__TYPE__TERMINATE:
break;
+
default:
TRACE("invalid event_msg type\n");
ret = false;
int sock = -1;
int ret = 0;
-
addr.sin_family = AF_INET;
addr.sin_port = htons(port); // i.e. 1234
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) {
{
int status = TETHERING__STATE__DISABLED;
+ TRACE("enter: %s\n", __func__);
+
if (closesocket(sockfd) < 0) {
perror("closesocket failure");
return;
set_tethering_connection_status(DISCONNECTED);
set_tethering_sensor_status(status);
set_tethering_touch_status(status);
+
+ TRACE("leave: %s\n", __func__);
}
#if 0
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;
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