Skip to content

Commit

Permalink
Use current adb port (if any) for --tcpip
Browse files Browse the repository at this point in the history
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 <#3591>
  • Loading branch information
rom1v committed Dec 2, 2022
1 parent 6469b55 commit bd1deff
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 41 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion app/scrcpy.1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
85 changes: 47 additions & 38 deletions app/src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

bool tcp_mode = is_tcpip_mode_enabled(server, serial);
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) "...");

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
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions app/src/util/str.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include <stdbool.h>
#include <stddef.h>

/* 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
Expand Down

0 comments on commit bd1deff

Please sign in to comment.