From bd1deffa70832a2ab30b8d060992ca70e3136ba8 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Thu, 24 Nov 2022 09:04:42 +0100 Subject: [PATCH] Use current adb port (if any) for --tcpip If the current adb port is not 5555 (typically 0 because it is not in TCP/IP mode), --tcpip automatically executes (among other commands): adb tcpip 5555 In case adb was already listening on another port, this command forced to listen on 5555, and the connection should still succeed. But this reconfiguration might be inconvenient for the user. If adb is already in TCP/IP mode, use the current enabled port without reconfiguration. Fixes #3591 --- README.md | 4 +-- app/scrcpy.1 | 2 +- app/src/server.c | 85 +++++++++++++++++++++++++--------------------- app/src/util/str.h | 4 +++ 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 20ad0f9c..87091696 100644 --- a/README.md +++ b/README.md @@ -395,8 +395,8 @@ address), connect the device over USB, then run: scrcpy --tcpip # without arguments ``` -It will automatically find the device IP address, enable TCP/IP mode, then -connect to the device before starting. +It will automatically find the device IP address and adb port, enable TCP/IP +mode if necessary, then connect to the device before starting. ##### Manual diff --git a/app/scrcpy.1 b/app/scrcpy.1 index 7cb893b7..852d9d03 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -275,7 +275,7 @@ Configure and reconnect the device over TCP/IP. If a destination address is provided, then scrcpy connects to this address before starting. The device must listen on the given TCP port (default is 5555). -If no destination address is provided, then scrcpy attempts to find the IP address of the current device (typically connected over USB), enables TCP/IP mode, then connects to this address before starting. +If no destination address is provided, then scrcpy attempts to find the IP address and adb port of the current device (typically connected over USB), enables TCP/IP mode if necessary, then connects to this address before starting. .TP .B \-S, \-\-turn\-screen\-off diff --git a/app/src/server.c b/app/src/server.c index 663ef18b..e5970487 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -19,6 +19,8 @@ #define SC_SERVER_PATH_DEFAULT PREFIX "/share/scrcpy/" SC_SERVER_FILENAME #define SC_DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar" +#define SC_ADB_PORT_DEFAULT 5555 + static char * get_server_path(void) { #ifdef __WINDOWS__ @@ -513,27 +515,36 @@ sc_server_on_terminated(void *userdata) { LOGD("Server terminated"); } -static bool -is_tcpip_mode_enabled(struct sc_server *server, const char *serial) { +static uint16_t +get_adb_tcp_port(struct sc_server *server, const char *serial) { struct sc_intr *intr = &server->intr; char *current_port = sc_adb_getprop(intr, serial, "service.adb.tcp.port", SC_ADB_SILENT); if (!current_port) { - return false; + return 0; } - // Is the device is listening on TCP on port 5555? - bool enabled = !strcmp("5555", current_port); + long value; + bool ok = sc_str_parse_integer(current_port, &value); free(current_port); - return enabled; + if (!ok) { + return 0; + } + + if (value < 0 || value > 0xFFFF) { + return 0; + } + + return value; } static bool wait_tcpip_mode_enabled(struct sc_server *server, const char *serial, - unsigned attempts, sc_tick delay) { - if (is_tcpip_mode_enabled(server, serial)) { - LOGI("TCP/IP mode enabled"); + uint16_t expected_port, unsigned attempts, + sc_tick delay) { + uint16_t adb_port = get_adb_tcp_port(server, serial); + if (adb_port == expected_port) { return true; } @@ -547,28 +558,23 @@ wait_tcpip_mode_enabled(struct sc_server *server, const char *serial, return false; } - if (is_tcpip_mode_enabled(server, serial)) { - LOGI("TCP/IP mode enabled"); + adb_port = get_adb_tcp_port(server, serial); + if (adb_port == expected_port) { return true; } } while (--attempts); return false; } -char * -append_port_5555(const char *ip) { - size_t len = strlen(ip); - - // sizeof counts the final '\0' - char *ip_port = malloc(len + sizeof(":5555")); - if (!ip_port) { +static char * +append_port(const char *ip, uint16_t port) { + char *ip_port; + int ret = asprintf(&ip_port, "%s:%" PRIu16, ip, port); + if (ret == -1) { LOG_OOM(); return NULL; } - memcpy(ip_port, ip, len); - memcpy(ip_port + len, ":5555", sizeof(":5555")); - return ip_port; } @@ -586,34 +592,36 @@ sc_server_switch_to_tcpip(struct sc_server *server, const char *serial) { return NULL; } - char *ip_port = append_port_5555(ip); - free(ip); - if (!ip_port) { - return NULL; - } + uint16_t adb_port = get_adb_tcp_port(server, serial); + if (adb_port) { + LOGI("TCP/IP mode already enabled on port %" PRIu16, adb_port); + } else { + LOGI("Enabling TCP/IP mode on port " SC_STR(SC_ADB_PORT_DEFAULT) "..."); - bool tcp_mode = is_tcpip_mode_enabled(server, serial); - - if (!tcp_mode) { - bool ok = sc_adb_tcpip(intr, serial, 5555, SC_ADB_NO_STDOUT); + bool ok = sc_adb_tcpip(intr, serial, SC_ADB_PORT_DEFAULT, + SC_ADB_NO_STDOUT); if (!ok) { LOGE("Could not restart adbd in TCP/IP mode"); - goto error; + free(ip); + return NULL; } unsigned attempts = 40; sc_tick delay = SC_TICK_FROM_MS(250); - ok = wait_tcpip_mode_enabled(server, serial, attempts, delay); + ok = wait_tcpip_mode_enabled(server, serial, SC_ADB_PORT_DEFAULT, + attempts, delay); if (!ok) { - goto error; + free(ip); + return NULL; } + + adb_port = SC_ADB_PORT_DEFAULT; + LOGI("TCP/IP mode enabled on port " SC_STR(SC_ADB_PORT_DEFAULT)); } + char *ip_port = append_port(ip, adb_port); + free(ip); return ip_port; - -error: - free(ip_port); - return NULL; } static bool @@ -640,7 +648,8 @@ sc_server_configure_tcpip_known_address(struct sc_server *server, const char *addr) { // Append ":5555" if no port is present bool contains_port = strchr(addr, ':'); - char *ip_port = contains_port ? strdup(addr) : append_port_5555(addr); + char *ip_port = contains_port ? strdup(addr) + : append_port(addr, SC_ADB_PORT_DEFAULT); if (!ip_port) { LOG_OOM(); return false; diff --git a/app/src/util/str.h b/app/src/util/str.h index 1736bd95..4f7eeeda 100644 --- a/app/src/util/str.h +++ b/app/src/util/str.h @@ -6,6 +6,10 @@ #include #include +/* Stringify a numeric value */ +#define SC_STR(s) SC_XSTR(s) +#define SC_XSTR(s) #s + /** * Like strncpy(), except: * - it copies at most n-1 chars