mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
d/remote: Support r_hub for Windows
Signed-off-by: utzcoz <utzcoz@outlook.com>
This commit is contained in:
parent
d7468d22da
commit
58193ad1c4
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020-2022, Collabora, Ltd.
|
||||
// Copyright 2020-2023, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
|
@ -17,22 +17,34 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#ifndef _BSD_SOURCE
|
||||
#define _BSD_SOURCE // same, but for musl // NOLINT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET
|
||||
#define SOCKET int
|
||||
#endif
|
||||
|
||||
#ifndef __USE_MISC
|
||||
#define __USE_MISC // SOL_TCP on C11
|
||||
#endif
|
||||
#ifndef _BSD_SOURCE
|
||||
#define _BSD_SOURCE // same, but for musl // NOLINT
|
||||
#endif
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
|
||||
/*
|
||||
|
@ -62,27 +74,100 @@ DEBUG_GET_ONCE_LOG_OPTION(remote_log, "REMOTE_LOG", U_LOGGING_INFO)
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
static void
|
||||
socket_close(SOCKET id)
|
||||
{
|
||||
closesocket(id);
|
||||
}
|
||||
|
||||
static SOCKET
|
||||
socket_create(void)
|
||||
{
|
||||
return socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
|
||||
static int
|
||||
socket_set_opt(SOCKET id, int flag)
|
||||
{
|
||||
return setsockopt(id, SOL_SOCKET, SO_REUSEADDR, (const char *)&flag, sizeof(flag));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
socket_read(SOCKET id, void *ptr, size_t size, size_t current)
|
||||
{
|
||||
return recv(id, (char *)ptr, size - current, 0);
|
||||
}
|
||||
|
||||
static size_t
|
||||
socket_write(SOCKET id, void *ptr, size_t size, size_t current)
|
||||
{
|
||||
return send(id, (const char *)ptr, size - current, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
static void
|
||||
socket_close(SOCKET id)
|
||||
{
|
||||
close(id);
|
||||
}
|
||||
|
||||
static SOCKET
|
||||
socket_create(void)
|
||||
{
|
||||
return socket(AF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
socket_set_opt(SOCKET id, int flag)
|
||||
{
|
||||
return setsockopt(id, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
socket_read(SOCKET id, void *ptr, size_t size, size_t current)
|
||||
{
|
||||
return read(id, ptr, size - current);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
socket_write(SOCKET id, void *ptr, size_t size, size_t current)
|
||||
{
|
||||
return write(id, ptr, size - current);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
setup_accept_fd(struct r_hub *r)
|
||||
{
|
||||
struct sockaddr_in server_address = {0};
|
||||
int ret;
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
// Initialize Winsock.
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
int error = WSAGetLastError();
|
||||
R_ERROR(r, "Failed to do WSAStartup %ld", error);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
SOCKET ret = socket_create();
|
||||
|
||||
ret = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (ret < 0) {
|
||||
R_ERROR(r, "socket: %i", ret);
|
||||
return ret;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
r->accept_fd = ret;
|
||||
|
||||
int flag = 1;
|
||||
ret = setsockopt(r->accept_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
|
||||
ret = socket_set_opt(r->accept_fd, flag);
|
||||
if (ret < 0) {
|
||||
R_ERROR(r, "setsockopt: %i", ret);
|
||||
close(r->accept_fd);
|
||||
socket_close(r->accept_fd);
|
||||
r->accept_fd = -1;
|
||||
return ret;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
server_address.sin_family = AF_INET;
|
||||
|
@ -92,18 +177,25 @@ setup_accept_fd(struct r_hub *r)
|
|||
ret = bind(r->accept_fd, (struct sockaddr *)&server_address, sizeof(server_address));
|
||||
if (ret < 0) {
|
||||
R_ERROR(r, "bind: %i", ret);
|
||||
close(r->accept_fd);
|
||||
socket_close(r->accept_fd);
|
||||
r->accept_fd = -1;
|
||||
return ret;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
R_INFO(r, "Listen address %s on port %d", inet_ntoa(server_address.sin_addr), r->port);
|
||||
|
||||
listen(r->accept_fd, 5);
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
WSACleanup();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
wait_for_read_and_to_continue(struct r_hub *r, int socket)
|
||||
wait_for_read_and_to_continue(struct r_hub *r, SOCKET socket)
|
||||
{
|
||||
fd_set set;
|
||||
int ret = 0;
|
||||
|
@ -139,9 +231,8 @@ do_accept(struct r_hub *r)
|
|||
{
|
||||
struct sockaddr_in addr = {0};
|
||||
int ret = 0;
|
||||
int conn_fd;
|
||||
|
||||
if (!wait_for_read_and_to_continue(r, r->accept_fd)) {
|
||||
R_ERROR(r, "Failed to wait for id %d", r->accept_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -152,13 +243,13 @@ do_accept(struct r_hub *r)
|
|||
return ret;
|
||||
}
|
||||
|
||||
conn_fd = ret;
|
||||
SOCKET conn_fd = ret;
|
||||
|
||||
int flags = 1;
|
||||
ret = setsockopt(conn_fd, SOL_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
|
||||
ret = socket_set_opt(r->accept_fd, flags);
|
||||
if (ret < 0) {
|
||||
R_ERROR(r, "setsockopt: %i", ret);
|
||||
close(conn_fd);
|
||||
socket_close(conn_fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -184,9 +275,13 @@ read_one(struct r_hub *r, struct r_remote_data *data)
|
|||
return -1;
|
||||
}
|
||||
|
||||
ssize_t ret = read(rc->fd, ptr, size - current);
|
||||
ssize_t ret = socket_read(rc->fd, ptr, size, current);
|
||||
if (ret < 0) {
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
RC_ERROR(rc, "recv: %zi", WSAGetLastError());
|
||||
#else
|
||||
RC_ERROR(rc, "read: %zi", ret);
|
||||
#endif
|
||||
return ret;
|
||||
} else if (ret > 0) {
|
||||
current += (size_t)ret;
|
||||
|
@ -257,7 +352,7 @@ r_hub_system_devices_destroy(struct xrt_system_devices *xsysd)
|
|||
|
||||
// Should be safe to destroy the sockets now.
|
||||
if (r->accept_fd >= 0) {
|
||||
close(r->accept_fd);
|
||||
socket_close(r->accept_fd);
|
||||
r->accept_fd = -1;
|
||||
}
|
||||
|
||||
|
@ -267,6 +362,11 @@ r_hub_system_devices_destroy(struct xrt_system_devices *xsysd)
|
|||
}
|
||||
|
||||
free(r);
|
||||
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
// Clean up Winsock.
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,7 +459,6 @@ r_create_devices(uint16_t port, struct xrt_system_devices **out_xsysd)
|
|||
u_var_add_bool(r, &r->latest.right.active, "right.active");
|
||||
u_var_add_pose(r, &r->latest.right.pose, "right.pose");
|
||||
|
||||
|
||||
/*
|
||||
* Done now.
|
||||
*/
|
||||
|
@ -386,42 +485,75 @@ r_remote_connection_init(struct r_remote_connection *rc, const char *ip_addr, ui
|
|||
// Set log level.
|
||||
rc->log_level = debug_get_log_option_remote_log();
|
||||
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
// Initialize Winsock.
|
||||
WSADATA wsaData;
|
||||
ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (ret != 0) {
|
||||
RC_ERROR(rc, "Failed to do WSAStartup %ld", WSAGetLastError());
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Address
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
ret = inet_pton(AF_INET, ip_addr, &addr.sin_addr);
|
||||
// inet_pton/InetPton resolves "localhost" as 0.0.0.0 or 255.255.255.255, and it causes connection error. To
|
||||
// avoid this issue, the following logic converts "localhost" to "127.0.0.1" first.
|
||||
if (strcmp("localhost", ip_addr) == 0) {
|
||||
ret = inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
|
||||
} else {
|
||||
ret = inet_pton(AF_INET, ip_addr, &addr.sin_addr);
|
||||
}
|
||||
if (ret < 0) {
|
||||
RC_ERROR(rc, "inet_pton: %i", ret);
|
||||
return ret;
|
||||
RC_ERROR(rc, "Failed to do inet pton for %s: %i", ip_addr, ret);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = socket(AF_INET, SOCK_STREAM, 0);
|
||||
ret = socket_create();
|
||||
if (ret < 0) {
|
||||
RC_ERROR(rc, "socket: %i", ret);
|
||||
return ret;
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
RC_ERROR(rc, "Failed to create socket %ld", WSAGetLastError());
|
||||
#else
|
||||
RC_ERROR(rc, "Failed to create socket: %i", ret);
|
||||
#endif
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
conn_fd = ret;
|
||||
|
||||
ret = connect(conn_fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
RC_ERROR(rc, "connect: %i", ret);
|
||||
close(conn_fd);
|
||||
return ret;
|
||||
// If connect operation succeed, both Windows and POSIX returns 0.
|
||||
if (ret != 0) {
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
RC_ERROR(rc, "Failed to connect id %d and addr %s with failure %d", conn_fd, inet_ntoa(addr.sin_addr),
|
||||
WSAGetLastError());
|
||||
#else
|
||||
RC_ERROR(rc, "Failed to connect id %d and addr %s with failure %d", conn_fd, inet_ntoa(addr.sin_addr),
|
||||
ret);
|
||||
#endif
|
||||
socket_close(conn_fd);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
int flags = 1;
|
||||
ret = setsockopt(conn_fd, SOL_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
|
||||
ret = socket_set_opt(conn_fd, flags);
|
||||
if (ret < 0) {
|
||||
RC_ERROR(rc, "setsockopt: %i", ret);
|
||||
close(conn_fd);
|
||||
return ret;
|
||||
RC_ERROR(rc, "Failed to setsockopt: %i", ret);
|
||||
socket_close(conn_fd);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc->fd = conn_fd;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
#if defined(XRT_OS_WINDOWS)
|
||||
WSACleanup();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -432,8 +564,7 @@ r_remote_connection_read_one(struct r_remote_connection *rc, struct r_remote_dat
|
|||
|
||||
while (current < size) {
|
||||
void *ptr = (uint8_t *)data + current;
|
||||
|
||||
ssize_t ret = read(rc->fd, ptr, size - current);
|
||||
ssize_t ret = socket_read(rc->fd, ptr, size, current);
|
||||
if (ret < 0) {
|
||||
RC_ERROR(rc, "read: %zi", ret);
|
||||
return ret;
|
||||
|
@ -456,9 +587,9 @@ r_remote_connection_write_one(struct r_remote_connection *rc, const struct r_rem
|
|||
size_t current = 0;
|
||||
|
||||
while (current < size) {
|
||||
const void *ptr = (const uint8_t *)data + current;
|
||||
void *ptr = (uint8_t *)data + current;
|
||||
|
||||
ssize_t ret = write(rc->fd, ptr, size - current);
|
||||
ssize_t ret = socket_write(rc->fd, ptr, size, current);
|
||||
if (ret < 0) {
|
||||
RC_ERROR(rc, "write: %zi", ret);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue