Add option for remote scrcpy connection

This commit is contained in:
RipleyTom 2021-11-18 01:02:53 +01:00
parent 75ebdbeacc
commit 7e5a1d5b7a
7 changed files with 89 additions and 7 deletions

View file

@ -137,6 +137,12 @@ foreach f : check_functions
endif
endforeach
if host_machine.system() == 'windows' or get_option('crossbuild_windows')
# Set the windows version higher than mingw default, needed for inet_pton on windows
add_global_arguments('-D_WIN32_WINNT=0x0600', language : 'c')
add_global_arguments('-DWINVER=0x0600', language : 'c')
endif
# the version, updated on release
conf.set_quoted('SCRCPY_VERSION', meson.project_version())

View file

@ -13,6 +13,14 @@
#include "util/strbuf.h"
#include "util/term.h"
#ifdef __WINDOWS__
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#define STR_IMPL_(x) #x
#define STR(x) STR_IMPL_(x)
@ -46,6 +54,8 @@
#define OPT_V4L2_SINK 1027
#define OPT_DISPLAY_BUFFER 1028
#define OPT_V4L2_BUFFER 1029
#define OPT_TUNNEL_HOST 1030
#define OPT_TUNNEL_PORT 1031
struct sc_option {
char shortopt;
@ -239,6 +249,20 @@ static const struct sc_option options[] = {
"Default is " STR(DEFAULT_LOCAL_PORT_RANGE_FIRST) ":"
STR(DEFAULT_LOCAL_PORT_RANGE_LAST) ".",
},
{
.longopt_id = OPT_TUNNEL_HOST,
.longopt = "tunnel-host",
.argdesc = "host",
.text = "Set the remote IP address of the scrcpy server.\n"
"This option is only valid with --force-adb-forward.",
},
{
.longopt_id = OPT_TUNNEL_PORT,
.longopt = "tunnel-port",
.argdesc = "port",
.text = "Set the remote TCP port of the scrcpy server.\n"
"This option is only valid with --force-adb-forward.",
},
{
.longopt_id = OPT_POWER_OFF_ON_CLOSE,
.longopt = "power-off-on-close",
@ -1123,6 +1147,27 @@ parse_record_format(const char *optarg, enum sc_record_format *format) {
return false;
}
static bool
parse_ip(const char *optarg, uint32_t *ipv4) {
struct in_addr conv;
if (!inet_pton(AF_INET, optarg, &conv)) {
LOGE("IP address is invalid: %s", optarg);
return false;
}
*ipv4 = ntohl(conv.s_addr);
return true;
}
static bool
parse_port(const char *optarg, uint16_t *port) {
long value;
if (!parse_integer_arg(optarg, &value, false, 1, 0xFFFF, "tunnel port")) {
return false;
}
*port = (uint16_t)value;
return true;
}
static enum sc_record_format
guess_record_format(const char *filename) {
size_t len = strlen(filename);
@ -1195,6 +1240,16 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return false;
}
break;
case OPT_TUNNEL_HOST:
if (!parse_ip(optarg, &opts->scrcpy_ip)) {
return false;
}
break;
case OPT_TUNNEL_PORT:
if (!parse_port(optarg, &opts->scrcpy_port)) {
return false;
}
break;
case 'n':
opts->control = false;
break;

View file

@ -19,6 +19,8 @@ const struct scrcpy_options scrcpy_options_default = {
.first = DEFAULT_LOCAL_PORT_RANGE_FIRST,
.last = DEFAULT_LOCAL_PORT_RANGE_LAST,
},
.scrcpy_ip = 0,
.scrcpy_port = 0,
.shortcut_mods = {
.data = {SC_MOD_LALT, SC_MOD_LSUPER},
.count = 2,

View file

@ -77,6 +77,8 @@ struct scrcpy_options {
enum sc_record_format record_format;
enum sc_keyboard_input_mode keyboard_input_mode;
struct sc_port_range port_range;
uint32_t scrcpy_ip;
uint16_t scrcpy_port;
struct sc_shortcut_mods shortcut_mods;
uint16_t max_size;
uint32_t bit_rate;

View file

@ -345,6 +345,8 @@ scrcpy(struct scrcpy_options *options) {
.log_level = options->log_level,
.crop = options->crop,
.port_range = options->port_range,
.scrcpy_ip = options->scrcpy_ip,
.scrcpy_port = options->scrcpy_port,
.max_size = options->max_size,
.bit_rate = options->bit_rate,
.max_fps = options->max_fps,

View file

@ -202,8 +202,8 @@ execute_server(struct sc_server *server,
}
static bool
connect_and_read_byte(struct sc_intr *intr, sc_socket socket, uint16_t port) {
bool ok = net_connect_intr(intr, socket, IPV4_LOCALHOST, port);
connect_and_read_byte(struct sc_intr *intr, sc_socket socket, uint32_t ip, uint16_t port) {
bool ok = net_connect_intr(intr, socket, ip, port);
if (!ok) {
return false;
}
@ -220,13 +220,12 @@ connect_and_read_byte(struct sc_intr *intr, sc_socket socket, uint16_t port) {
}
static sc_socket
connect_to_server(struct sc_server *server, uint32_t attempts, sc_tick delay) {
uint16_t port = server->tunnel.local_port;
connect_to_server(struct sc_server *server, uint32_t attempts, sc_tick delay, uint32_t ip, uint16_t port) {
do {
LOGD("Remaining connection attempts: %d", (int) attempts);
sc_socket socket = net_socket();
if (socket != SC_SOCKET_NONE) {
bool ok = connect_and_read_byte(&server->intr, socket, port);
bool ok = connect_and_read_byte(&server->intr, socket, ip, port);
if (ok) {
// it worked!
return socket;
@ -352,9 +351,23 @@ sc_server_connect_to(struct sc_server *server, struct sc_server_info *info) {
goto fail;
}
} else {
uint32_t ip;
if (server->params.scrcpy_ip) {
ip = server->params.scrcpy_ip;
} else {
ip = IPV4_LOCALHOST;
}
uint16_t port;
if (server->params.scrcpy_port) {
port = server->params.scrcpy_port;
} else {
port = tunnel->local_port;
}
uint32_t attempts = 100;
sc_tick delay = SC_TICK_FROM_MS(100);
video_socket = connect_to_server(server, attempts, delay);
video_socket = connect_to_server(server, attempts, delay, ip, port);
if (video_socket == SC_SOCKET_NONE) {
goto fail;
}
@ -365,7 +378,7 @@ sc_server_connect_to(struct sc_server *server, struct sc_server_info *info) {
goto fail;
}
bool ok = net_connect_intr(&server->intr, control_socket,
IPV4_LOCALHOST, tunnel->local_port);
ip, port);
if (!ok) {
goto fail;
}

View file

@ -29,6 +29,8 @@ struct sc_server_params {
const char *codec_options;
const char *encoder_name;
struct sc_port_range port_range;
uint32_t scrcpy_ip;
uint16_t scrcpy_port;
uint16_t max_size;
uint32_t bit_rate;
uint16_t max_fps;