diff --git a/app/meson.build b/app/meson.build index 83375ee2a3b6d0b92cbbe89db91823e2d4a0e8f9..e574a835d4d6371b189d90d61341ebe9d97642ff 100644 --- a/app/meson.build +++ b/app/meson.build @@ -10,7 +10,7 @@ src = [ 'src/frames.c', 'src/inputmanager.c', 'src/lockutil.c', - 'src/netutil.c', + 'src/net.c', 'src/scrcpy.c', 'src/screen.c', 'src/server.c', @@ -18,20 +18,24 @@ src = [ 'src/tinyxpm.c', ] -if host_machine.system() == 'windows' - src += [ 'src/sys/win/command.c' ] -else - src += [ 'src/sys/unix/command.c' ] -endif - dependencies = [ dependency('libavformat'), dependency('libavcodec'), dependency('libavutil'), dependency('sdl2'), - dependency('SDL2_net'), ] +cc = meson.get_compiler('c') + +if host_machine.system() == 'windows' + src += [ 'src/sys/win/command.c' ] + src += [ 'src/sys/win/net.c' ] + dependencies += cc.find_library('ws2_32') +else + src += [ 'src/sys/unix/command.c' ] + src += [ 'src/sys/unix/net.c' ] +endif + conf = configuration_data() # expose the build type diff --git a/app/src/command.h b/app/src/command.h index adaad836d437997db1d7f13f7c086cf9de3bec98..8232f46cfb9f15ec615282e2bd904195ad8c8745 100644 --- a/app/src/command.h +++ b/app/src/command.h @@ -20,6 +20,7 @@ #endif #ifdef __WINDOWS__ +# include // not needed here, but must never be included AFTER windows.h # include # define PROCESS_NONE NULL typedef HANDLE process_t; diff --git a/app/src/controller.c b/app/src/controller.c index 8f5bddf805ac8ad346d21423a601190ea1b9d302..24485bdddae51541e0c351be844314dca0dc440e 100644 --- a/app/src/controller.c +++ b/app/src/controller.c @@ -3,7 +3,7 @@ #include "lockutil.h" #include "log.h" -SDL_bool controller_init(struct controller *controller, TCPsocket video_socket) { +SDL_bool controller_init(struct controller *controller, socket_t video_socket) { if (!control_event_queue_init(&controller->queue)) { return SDL_FALSE; } @@ -47,7 +47,7 @@ static SDL_bool process_event(struct controller *controller, const struct contro if (!length) { return SDL_FALSE; } - int w = SDLNet_TCP_Send(controller->video_socket, serialized_event, length); + int w = net_send(controller->video_socket, serialized_event, length); return w == length; } diff --git a/app/src/controller.h b/app/src/controller.h index 14b93a2a4dd1be2522e7c699755230e1f24f9a7f..7c22fe0712721d52ad88e62599b88f12575411d7 100644 --- a/app/src/controller.h +++ b/app/src/controller.h @@ -4,11 +4,13 @@ #include "controlevent.h" #include -#include #include +#include + +#include "net.h" struct controller { - TCPsocket video_socket; + socket_t video_socket; SDL_Thread *thread; SDL_mutex *mutex; SDL_cond *event_cond; @@ -16,7 +18,7 @@ struct controller { struct control_event_queue queue; }; -SDL_bool controller_init(struct controller *controller, TCPsocket video_socket); +SDL_bool controller_init(struct controller *controller, socket_t video_socket); void controller_destroy(struct controller *controller); SDL_bool controller_start(struct controller *controller); diff --git a/app/src/decoder.c b/app/src/decoder.c index c3700006d93e9d18b4080712c19f8c920bed0fbb..8f93b9c938f76a23b2938a766ef91ff9ddf26fc1 100644 --- a/app/src/decoder.c +++ b/app/src/decoder.c @@ -1,8 +1,8 @@ #include "decoder.h" #include +#include #include -#include #include #include @@ -11,13 +11,12 @@ #include "frames.h" #include "lockutil.h" #include "log.h" -#include "netutil.h" #define BUFSIZE 0x10000 static int read_packet(void *opaque, uint8_t *buf, int buf_size) { struct decoder *decoder = opaque; - return SDLNet_TCP_Recv(decoder->video_socket, buf, buf_size); + return net_recv(decoder->video_socket, buf, buf_size); } // set the decoded frame as ready for rendering, and notify @@ -147,7 +146,7 @@ run_finally_free_codec_ctx: return ret; } -void decoder_init(struct decoder *decoder, struct frames *frames, TCPsocket video_socket) { +void decoder_init(struct decoder *decoder, struct frames *frames, socket_t video_socket) { decoder->frames = frames; decoder->video_socket = video_socket; } diff --git a/app/src/decoder.h b/app/src/decoder.h index 04ff14a65810e3b0597814506f6577457dae7288..87346114438a4d6d18a19d2657dccab859d16b46 100644 --- a/app/src/decoder.h +++ b/app/src/decoder.h @@ -2,18 +2,20 @@ #define DECODER_H #include -#include +#include + +#include "net.h" struct frames; struct decoder { struct frames *frames; - TCPsocket video_socket; + socket_t video_socket; SDL_Thread *thread; SDL_mutex *mutex; }; -void decoder_init(struct decoder *decoder, struct frames *frames, TCPsocket video_socket); +void decoder_init(struct decoder *decoder, struct frames *frames, socket_t video_socket); SDL_bool decoder_start(struct decoder *decoder); void decoder_stop(struct decoder *decoder); void decoder_join(struct decoder *decoder); diff --git a/app/src/device.c b/app/src/device.c index c1dd7a5d94cea66c159939509b4f6fd82b27043a..761e24465544d15f08d8b9011329f517610d1633 100644 --- a/app/src/device.c +++ b/app/src/device.c @@ -1,9 +1,9 @@ #include "device.h" #include "log.h" -SDL_bool device_read_info(TCPsocket device_socket, char *device_name, struct size *size) { +SDL_bool device_read_info(socket_t device_socket, char *device_name, struct size *size) { unsigned char buf[DEVICE_NAME_FIELD_LENGTH + 4]; - if (SDLNet_TCP_Recv(device_socket, buf, sizeof(buf)) <= 0) { + if (net_recv(device_socket, buf, sizeof(buf)) <= 0) { LOGE("Could not retrieve device information"); return SDL_FALSE; } diff --git a/app/src/device.h b/app/src/device.h index ffaeaa281443fba0892f5e9656dfd0a90e9e3830..d01d6ed294f52e1fba8fe062d24f0c0dff2767f7 100644 --- a/app/src/device.h +++ b/app/src/device.h @@ -1,14 +1,14 @@ #ifndef DEVICE_H #define DEVICE_H -#include #include #include "common.h" +#include "net.h" #define DEVICE_NAME_FIELD_LENGTH 64 // name must be at least DEVICE_NAME_FIELD_LENGTH bytes -SDL_bool device_read_info(TCPsocket device_socket, char *name, struct size *frame_size); +SDL_bool device_read_info(socket_t device_socket, char *name, struct size *frame_size); #endif diff --git a/app/src/main.c b/app/src/main.c index a0e36b74bcd5e6fd141bf9e5776536cd14d74c96..46abd8456c3911e6cb0856047277982e6b73c5a9 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -4,7 +4,6 @@ #include #include #include -#include #include "config.h" #include "log.h" @@ -97,7 +96,6 @@ static void print_version(void) { fprintf(stderr, "dependencies:\n"); fprintf(stderr, " - SDL %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL); - fprintf(stderr, " - SDL_net %d.%d.%d\n", SDL_NET_MAJOR_VERSION, SDL_NET_MINOR_VERSION, SDL_NET_PATCHLEVEL); fprintf(stderr, " - libavcodec %d.%d.%d\n", LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO); fprintf(stderr, " - libavformat %d.%d.%d\n", LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO); fprintf(stderr, " - libavutil %d.%d.%d\n", LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO); diff --git a/app/src/net.c b/app/src/net.c new file mode 100644 index 0000000000000000000000000000000000000000..11a66e4c5eadf9ca0d0ba5cd486c25dc28114f90 --- /dev/null +++ b/app/src/net.c @@ -0,0 +1,56 @@ +#include "net.h" + +#include "log.h" + +#ifdef __WINDOWS__ + typedef int socklen_t; +#else +# include +# include +# include +# include +# include +# define SOCKET_ERROR -1 + typedef struct sockaddr_in SOCKADDR_IN; + typedef struct sockaddr SOCKADDR; + typedef struct in_addr IN_ADDR; +#endif + +socket_t net_listen(Uint32 addr, Uint16 port, int backlog) { + socket_t sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == INVALID_SOCKET) { + LOGE("Cannot create socket"); + return INVALID_SOCKET; + } + + SOCKADDR_IN sin; + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(addr); // htonl() harmless on INADDR_ANY + sin.sin_port = htons(port); + + if (bind(sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) { + LOGE("Cannot bind"); + return INVALID_SOCKET; + } + + if (listen(sock, backlog) == SOCKET_ERROR) { + LOGE("Cannot listen on port %" PRIu16, port); + return INVALID_SOCKET; + } + + return sock; +} + +socket_t net_accept(socket_t server_socket) { + SOCKADDR_IN csin; + socklen_t sinsize = sizeof(csin); + return accept(server_socket, (SOCKADDR *) &csin, &sinsize); +} + +ssize_t net_recv(socket_t socket, void *buf, size_t len) { + return recv(socket, buf, len, 0); +} + +ssize_t net_send(socket_t socket, void *buf, size_t len) { + return send(socket, buf, len, 0); +} diff --git a/app/src/net.h b/app/src/net.h new file mode 100644 index 0000000000000000000000000000000000000000..bf22605cd706a7c94846e6b6a5316e1b86212bcb --- /dev/null +++ b/app/src/net.h @@ -0,0 +1,26 @@ +#ifndef NET_H +#define NET_H + +#include +#include + +#ifdef __WINDOWS__ +# include + typedef SIZE_T size_t; + typedef SSIZE_T ssize_t; + typedef SOCKET socket_t; +#else +# define INVALID_SOCKET -1 + typedef int socket_t; +#endif + +SDL_bool net_init(void); +void net_cleanup(void); + +socket_t net_listen(Uint32 addr, Uint16 port, int backlog); +socket_t net_accept(socket_t server_socket); +ssize_t net_recv(socket_t socket, void *buf, size_t len); +ssize_t net_send(socket_t socket, void *buf, size_t len); +void net_close(socket_t socket); + +#endif diff --git a/app/src/netutil.c b/app/src/netutil.c deleted file mode 100644 index b305458776d10d4310573c1d4de4e535d1c568c8..0000000000000000000000000000000000000000 --- a/app/src/netutil.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "netutil.h" - -#include - -#include "log.h" - -// contrary to SDLNet_TCP_Send and SDLNet_TCP_Recv, SDLNet_TCP_Accept is non-blocking -// so we need to block before calling it -TCPsocket server_socket_accept(TCPsocket server_socket, Uint32 timeout_ms) { - SDLNet_SocketSet set = SDLNet_AllocSocketSet(1); - if (!set) { - LOGC("Could not allocate socket set"); - return NULL; - } - - if (SDLNet_TCP_AddSocket(set, server_socket) == -1) { - LOGC("Could not add socket to set"); - SDLNet_FreeSocketSet(set); - return NULL; - } - - if (SDLNet_CheckSockets(set, timeout_ms) != 1) { - LOGE("No connection to accept"); - SDLNet_FreeSocketSet(set); - return NULL; - } - - SDLNet_FreeSocketSet(set); - - return SDLNet_TCP_Accept(server_socket); -} diff --git a/app/src/netutil.h b/app/src/netutil.h deleted file mode 100644 index d0a3d2a8fa01ff19f1a4c8590ba37f03777f8827..0000000000000000000000000000000000000000 --- a/app/src/netutil.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef NETUTIL_H -#define NETUTIL_H - -#include - -// blocking accept on the server socket -TCPsocket server_socket_accept(TCPsocket server_socket, Uint32 timeout_ms); - -#endif diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 90eb1e52f3a814da110aa9c8838efc99b7f94546..5891658d259c23f205bf73aa5758f91800f82414 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -6,7 +6,6 @@ #include #include #include -#include #include "command.h" #include "common.h" @@ -19,7 +18,7 @@ #include "inputmanager.h" #include "log.h" #include "lockutil.h" -#include "netutil.h" +#include "net.h" #include "screen.h" #include "server.h" #include "tinyxpm.h" @@ -104,8 +103,8 @@ SDL_bool scrcpy(const char *serial, Uint16 local_port, Uint16 max_size, Uint32 b // managed by the event loop. This blocking call blocks the event loop, so // timeout the connection not to block indefinitely in case of SIGTERM. #define SERVER_CONNECT_TIMEOUT_MS 2000 - TCPsocket device_socket = server_connect_to(&server, serial, SERVER_CONNECT_TIMEOUT_MS); - if (!device_socket) { + socket_t device_socket = server_connect_to(&server, serial, SERVER_CONNECT_TIMEOUT_MS); + if (device_socket == INVALID_SOCKET) { server_stop(&server, serial); ret = SDL_FALSE; goto finally_destroy_server; diff --git a/app/src/server.c b/app/src/server.c index 614f78d735767e4098fb39ccb69b34e82c19d574..0cb4f0e6c168bd0c1cabd6f57e4ee7b256216179 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -1,12 +1,12 @@ #include "server.h" -#include #include +#include #include +#include #include "config.h" #include "log.h" -#include "netutil.h" #define SOCKET_NAME "scrcpy" @@ -62,12 +62,9 @@ static void terminate_server(process_t server) { } } -static TCPsocket listen_on_port(Uint16 port) { - IPaddress addr = { - .host = INADDR_ANY, - .port = SDL_SwapBE16(port), - }; - return SDLNet_TCP_Open(&addr); +static socket_t listen_on_port(Uint16 port) { +#define IPV4_LOCALHOST 0x7F000001 + return net_listen(IPV4_LOCALHOST, port, 1); } void server_init(struct server *server) { @@ -91,7 +88,7 @@ SDL_bool server_start(struct server *server, const char *serial, Uint16 local_po // connect until the server socket is listening on the device. server->server_socket = listen_on_port(local_port); - if (!server->server_socket) { + if (server->server_socket == INVALID_SOCKET) { LOGE("Could not listen on port %" PRIu16, local_port); disable_tunnel(serial); return SDL_FALSE; @@ -100,7 +97,7 @@ SDL_bool server_start(struct server *server, const char *serial, Uint16 local_po // server will connect to our server socket server->process = execute_server(serial, max_size, bit_rate); if (server->process == PROCESS_NONE) { - SDLNet_TCP_Close(server->server_socket); + net_close(server->server_socket); disable_tunnel(serial); return SDL_FALSE; } @@ -110,13 +107,15 @@ SDL_bool server_start(struct server *server, const char *serial, Uint16 local_po return SDL_TRUE; } -TCPsocket server_connect_to(struct server *server, const char *serial, Uint32 timeout_ms) { - SDL_assert(server->server_socket); - server->device_socket = server_socket_accept(server->server_socket, timeout_ms); +socket_t server_connect_to(struct server *server, const char *serial, Uint32 timeout_ms) { + server->device_socket = net_accept(server->server_socket); + if (server->device_socket == INVALID_SOCKET) { + return INVALID_SOCKET; + } // we don't need the server socket anymore - SDLNet_TCP_Close(server->server_socket); - server->server_socket = NULL; + net_close(server->server_socket); + server->server_socket = INVALID_SOCKET; // we don't need the adb tunnel anymore disable_tunnel(serial); // ignore failure @@ -136,10 +135,10 @@ void server_stop(struct server *server, const char *serial) { } void server_destroy(struct server *server) { - if (server->server_socket) { - SDLNet_TCP_Close(server->server_socket); + if (server->server_socket != INVALID_SOCKET) { + net_close(server->server_socket); } - if (server->device_socket) { - SDLNet_TCP_Close(server->device_socket); + if (server->device_socket != INVALID_SOCKET) { + net_close(server->device_socket); } } diff --git a/app/src/server.h b/app/src/server.h index 3d877f0c43bd24f44a6dd1b02030239f4689187e..95eb7d16f392eb1002a2582d7a64c2a6a83fc0a0 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -1,20 +1,20 @@ #ifndef SERVER_H #define SERVER_H -#include #include "command.h" +#include "net.h" struct server { process_t process; - TCPsocket server_socket; - TCPsocket device_socket; + socket_t server_socket; + socket_t device_socket; SDL_bool adb_reverse_enabled; }; #define SERVER_INITIALIZER { \ .process = PROCESS_NONE, \ - .server_socket = NULL, \ - .device_socket = NULL, \ + .server_socket = INVALID_SOCKET, \ + .device_socket = INVALID_SOCKET, \ .adb_reverse_enabled = SDL_FALSE, \ } @@ -26,7 +26,7 @@ SDL_bool server_start(struct server *server, const char *serial, Uint16 local_po Uint16 max_size, Uint32 bit_rate); // block until the communication with the server is established -TCPsocket server_connect_to(struct server *server, const char *serial, Uint32 timeout_ms); +socket_t server_connect_to(struct server *server, const char *serial, Uint32 timeout_ms); // disconnect and kill the server process void server_stop(struct server *server, const char *serial); diff --git a/app/src/sys/unix/net.c b/app/src/sys/unix/net.c new file mode 100644 index 0000000000000000000000000000000000000000..4219ddb89726cced7f886242c74d6b447883431d --- /dev/null +++ b/app/src/sys/unix/net.c @@ -0,0 +1,16 @@ +#include "../../net.h" + +# include + +SDL_bool net_init(void) { + // do nothing + return SDL_TRUE; +} + +void net_cleanup(void) { + // do nothing +} + +void net_close(socket_t socket) { + close(socket); +} diff --git a/app/src/sys/win/net.c b/app/src/sys/win/net.c new file mode 100644 index 0000000000000000000000000000000000000000..b328361e4d282780f9926d7e137cf17b3c0fdd57 --- /dev/null +++ b/app/src/sys/win/net.c @@ -0,0 +1,21 @@ +#include "../../net.h" + +#include "../../log.h" + +SDL_bool net_init(void) { + WSADATA wsa; + int res = WSAStartup(MAKEWORD(2, 2), &wsa) < 0; + if (res < 0) { + LOGC("WSAStartup failed with error %d", res); + return SDL_FALSE; + } + return SDL_TRUE; +} + +void net_cleanup(void) { + WSACleanup(); +} + +void net_close(socket_t socket) { + closesocket(socket); +}