Store actual serial in sc_server
Before starting the server, the actual device serial (possibly its ip:port if it's over TCP/IP) must be known. A serial might be requested via -s/--serial (stored in the sc_server_params), but the actual serial may change afterwards: - if none is provided, then it is retrieved with "adb get-serialno"; - if --tcpip is requested, then the final serial will be the target ip:port. The requested serial was overwritten by the actual serial in the sc_server_params struct, which was a bit hacky. Instead, store a separate serial field in sc_server (and rename the one from sc_server_params to "req_serial" to avoid confusion).
This commit is contained in:
parent
08f16a9dde
commit
5b3ae2cb2f
3 changed files with 60 additions and 63 deletions
|
@ -296,7 +296,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
struct sc_acksync *acksync = NULL;
|
struct sc_acksync *acksync = NULL;
|
||||||
|
|
||||||
struct sc_server_params params = {
|
struct sc_server_params params = {
|
||||||
.serial = options->serial,
|
.req_serial = options->serial,
|
||||||
.log_level = options->log_level,
|
.log_level = options->log_level,
|
||||||
.crop = options->crop,
|
.crop = options->crop,
|
||||||
.port_range = options->port_range,
|
.port_range = options->port_range,
|
||||||
|
@ -355,7 +355,7 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
// It is necessarily initialized here, since the device is connected
|
// It is necessarily initialized here, since the device is connected
|
||||||
struct sc_server_info *info = &s->server.info;
|
struct sc_server_info *info = &s->server.info;
|
||||||
|
|
||||||
const char *serial = s->server.params.serial;
|
const char *serial = s->server.serial;
|
||||||
assert(serial);
|
assert(serial);
|
||||||
|
|
||||||
struct sc_file_pusher *fp = NULL;
|
struct sc_file_pusher *fp = NULL;
|
||||||
|
|
116
app/src/server.c
116
app/src/server.c
|
@ -65,7 +65,7 @@ get_server_path(void) {
|
||||||
static void
|
static void
|
||||||
sc_server_params_destroy(struct sc_server_params *params) {
|
sc_server_params_destroy(struct sc_server_params *params) {
|
||||||
// The server stores a copy of the params provided by the user
|
// The server stores a copy of the params provided by the user
|
||||||
free((char *) params->serial);
|
free((char *) params->req_serial);
|
||||||
free((char *) params->crop);
|
free((char *) params->crop);
|
||||||
free((char *) params->codec_options);
|
free((char *) params->codec_options);
|
||||||
free((char *) params->encoder_name);
|
free((char *) params->encoder_name);
|
||||||
|
@ -89,7 +89,7 @@ sc_server_params_copy(struct sc_server_params *dst,
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
COPY(serial);
|
COPY(req_serial);
|
||||||
COPY(crop);
|
COPY(crop);
|
||||||
COPY(codec_options);
|
COPY(codec_options);
|
||||||
COPY(encoder_name);
|
COPY(encoder_name);
|
||||||
|
@ -157,7 +157,7 @@ execute_server(struct sc_server *server,
|
||||||
const struct sc_server_params *params) {
|
const struct sc_server_params *params) {
|
||||||
sc_pid pid = SC_PROCESS_NONE;
|
sc_pid pid = SC_PROCESS_NONE;
|
||||||
|
|
||||||
const char *serial = params->serial;
|
const char *serial = server->serial;
|
||||||
assert(serial);
|
assert(serial);
|
||||||
|
|
||||||
const char *cmd[128];
|
const char *cmd[128];
|
||||||
|
@ -353,6 +353,7 @@ sc_server_init(struct sc_server *server, const struct sc_server_params *params,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server->serial = NULL;
|
||||||
server->stopped = false;
|
server->stopped = false;
|
||||||
|
|
||||||
server->video_socket = SC_SOCKET_NONE;
|
server->video_socket = SC_SOCKET_NONE;
|
||||||
|
@ -397,7 +398,9 @@ sc_server_connect_to(struct sc_server *server, struct sc_server_info *info) {
|
||||||
|
|
||||||
assert(tunnel->enabled);
|
assert(tunnel->enabled);
|
||||||
|
|
||||||
const char *serial = server->params.serial;
|
const char *serial = server->serial;
|
||||||
|
assert(serial);
|
||||||
|
|
||||||
bool control = server->params.control;
|
bool control = server->params.control;
|
||||||
|
|
||||||
sc_socket video_socket = SC_SOCKET_NONE;
|
sc_socket video_socket = SC_SOCKET_NONE;
|
||||||
|
@ -500,30 +503,25 @@ sc_server_on_terminated(void *userdata) {
|
||||||
LOGD("Server terminated");
|
LOGD("Server terminated");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static char *
|
||||||
sc_server_fill_serial(struct sc_server *server) {
|
sc_server_read_serial(struct sc_server *server) {
|
||||||
// Retrieve the actual device immediately if not provided, so that all
|
char *serial;
|
||||||
// future adb commands are executed for this specific device, even if other
|
if (server->params.req_serial) {
|
||||||
// devices are connected afterwards (without "more than one
|
// The serial is already known
|
||||||
// device/emulator" error)
|
serial = strdup(server->params.req_serial);
|
||||||
if (!server->params.serial) {
|
if (!serial) {
|
||||||
// The serial is owned by sc_server_params, and will be freed on destroy
|
LOG_OOM();
|
||||||
server->params.serial = sc_adb_get_serialno(&server->intr, 0);
|
|
||||||
if (!server->params.serial) {
|
|
||||||
LOGE("Could not get device serial");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
LOGD("Device serial: %s", server->params.serial);
|
serial = sc_adb_get_serialno(&server->intr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_tcpip_mode_enabled(struct sc_server *server) {
|
is_tcpip_mode_enabled(struct sc_server *server, const char *serial) {
|
||||||
struct sc_intr *intr = &server->intr;
|
struct sc_intr *intr = &server->intr;
|
||||||
const char *serial = server->params.serial;
|
|
||||||
|
|
||||||
char *current_port =
|
char *current_port =
|
||||||
sc_adb_getprop(intr, serial, "service.adb.tcp.port", SC_ADB_SILENT);
|
sc_adb_getprop(intr, serial, "service.adb.tcp.port", SC_ADB_SILENT);
|
||||||
|
@ -538,9 +536,9 @@ is_tcpip_mode_enabled(struct sc_server *server) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
wait_tcpip_mode_enabled(struct sc_server *server, unsigned attempts,
|
wait_tcpip_mode_enabled(struct sc_server *server, const char *serial,
|
||||||
sc_tick delay) {
|
unsigned attempts, sc_tick delay) {
|
||||||
if (is_tcpip_mode_enabled(server)) {
|
if (is_tcpip_mode_enabled(server, serial)) {
|
||||||
LOGI("TCP/IP mode enabled");
|
LOGI("TCP/IP mode enabled");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -555,7 +553,7 @@ wait_tcpip_mode_enabled(struct sc_server *server, unsigned attempts,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_tcpip_mode_enabled(server)) {
|
if (is_tcpip_mode_enabled(server, serial)) {
|
||||||
LOGI("TCP/IP mode enabled");
|
LOGI("TCP/IP mode enabled");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -581,12 +579,13 @@ append_port_5555(const char *ip) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
sc_server_switch_to_tcpip(struct sc_server *server) {
|
sc_server_switch_to_tcpip(struct sc_server *server, const char *serial) {
|
||||||
const char *serial = server->params.serial;
|
|
||||||
assert(serial);
|
assert(serial);
|
||||||
|
|
||||||
struct sc_intr *intr = &server->intr;
|
struct sc_intr *intr = &server->intr;
|
||||||
|
|
||||||
|
LOGI("Switching device %s to TCP/IP...", serial);
|
||||||
|
|
||||||
char *ip = sc_adb_get_device_ip(intr, serial, 0);
|
char *ip = sc_adb_get_device_ip(intr, serial, 0);
|
||||||
if (!ip) {
|
if (!ip) {
|
||||||
LOGE("Device IP not found");
|
LOGE("Device IP not found");
|
||||||
|
@ -599,7 +598,7 @@ sc_server_switch_to_tcpip(struct sc_server *server) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tcp_mode = is_tcpip_mode_enabled(server);
|
bool tcp_mode = is_tcpip_mode_enabled(server, serial);
|
||||||
|
|
||||||
if (!tcp_mode) {
|
if (!tcp_mode) {
|
||||||
bool ok = sc_adb_tcpip(intr, serial, 5555, SC_ADB_NO_STDOUT);
|
bool ok = sc_adb_tcpip(intr, serial, 5555, SC_ADB_NO_STDOUT);
|
||||||
|
@ -610,7 +609,7 @@ sc_server_switch_to_tcpip(struct sc_server *server) {
|
||||||
|
|
||||||
unsigned attempts = 40;
|
unsigned attempts = 40;
|
||||||
sc_tick delay = SC_TICK_FROM_MS(250);
|
sc_tick delay = SC_TICK_FROM_MS(250);
|
||||||
ok = wait_tcpip_mode_enabled(server, attempts, delay);
|
ok = wait_tcpip_mode_enabled(server, serial, attempts, delay);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -630,20 +629,14 @@ sc_server_connect_to_tcpip(struct sc_server *server, const char *ip_port) {
|
||||||
// Error expected if not connected, do not report any error
|
// Error expected if not connected, do not report any error
|
||||||
sc_adb_disconnect(intr, ip_port, SC_ADB_SILENT);
|
sc_adb_disconnect(intr, ip_port, SC_ADB_SILENT);
|
||||||
|
|
||||||
|
LOGI("Connecting to %s...", ip_port);
|
||||||
|
|
||||||
bool ok = sc_adb_connect(intr, ip_port, 0);
|
bool ok = sc_adb_connect(intr, ip_port, 0);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGE("Could not connect to %s", ip_port);
|
LOGE("Could not connect to %s", ip_port);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override the serial, owned by the sc_server_params
|
|
||||||
free((void *) server->params.serial);
|
|
||||||
server->params.serial = strdup(ip_port);
|
|
||||||
if (!server->params.serial) {
|
|
||||||
LOG_OOM();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGI("Connected to %s", ip_port);
|
LOGI("Connected to %s", ip_port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -657,7 +650,7 @@ sc_server_configure_tcpip(struct sc_server *server) {
|
||||||
|
|
||||||
// If tcpip parameter is given, then it must connect to this address.
|
// If tcpip parameter is given, then it must connect to this address.
|
||||||
// Therefore, the device is unknown, so serial is meaningless at this point.
|
// Therefore, the device is unknown, so serial is meaningless at this point.
|
||||||
assert(!params->serial || !params->tcpip_dst);
|
assert(!params->req_serial || !params->tcpip_dst);
|
||||||
|
|
||||||
if (params->tcpip_dst) {
|
if (params->tcpip_dst) {
|
||||||
// Append ":5555" if no port is present
|
// Append ":5555" if no port is present
|
||||||
|
@ -671,30 +664,32 @@ sc_server_configure_tcpip(struct sc_server *server) {
|
||||||
} else {
|
} else {
|
||||||
// The device IP address must be retrieved from the current
|
// The device IP address must be retrieved from the current
|
||||||
// connected device
|
// connected device
|
||||||
if (!sc_server_fill_serial(server)) {
|
char *serial = sc_server_read_serial(server);
|
||||||
|
if (!serial) {
|
||||||
|
LOGE("Could not get device serial");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The serial is either the real serial when connected via USB, or
|
// The serial is either the real serial when connected via USB, or
|
||||||
// the IP:PORT when connected over TCP/IP. Only the latter contains
|
// the IP:PORT when connected over TCP/IP. Only the latter contains
|
||||||
// a colon.
|
// a colon.
|
||||||
bool is_already_tcpip = strchr(params->serial, ':');
|
bool is_already_tcpip = strchr(serial, ':');
|
||||||
if (is_already_tcpip) {
|
if (is_already_tcpip) {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
LOGI("Device already connected via TCP/IP: %s", params->serial);
|
LOGI("Device already connected via TCP/IP: %s", serial);
|
||||||
|
free(serial);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_port = sc_server_switch_to_tcpip(server);
|
ip_port = sc_server_switch_to_tcpip(server, serial);
|
||||||
|
free(serial);
|
||||||
if (!ip_port) {
|
if (!ip_port) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On success, this call changes params->serial
|
server->serial = ip_port;
|
||||||
bool ok = sc_server_connect_to_tcpip(server, ip_port);
|
return sc_server_connect_to_tcpip(server, ip_port);
|
||||||
free(ip_port);
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -703,30 +698,30 @@ run_server(void *data) {
|
||||||
|
|
||||||
const struct sc_server_params *params = &server->params;
|
const struct sc_server_params *params = &server->params;
|
||||||
|
|
||||||
if (params->serial) {
|
|
||||||
LOGD("Device serial: %s", params->serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params->tcpip) {
|
if (params->tcpip) {
|
||||||
// params->serial may be changed after this call
|
|
||||||
bool ok = sc_server_configure_tcpip(server);
|
bool ok = sc_server_configure_tcpip(server);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
assert(server->serial);
|
||||||
|
} else {
|
||||||
|
server->serial = sc_server_read_serial(server);
|
||||||
|
if (!server->serial) {
|
||||||
|
LOGD("Could not get device serial");
|
||||||
|
goto error_connection_failed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is ok to call this function even if the device serial has been
|
const char *serial = server->serial;
|
||||||
// changed by switching over TCP/IP
|
assert(serial);
|
||||||
if (!sc_server_fill_serial(server)) {
|
LOGD("Device serial: %s", serial);
|
||||||
goto error_connection_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok = push_server(&server->intr, params->serial);
|
bool ok = push_server(&server->intr, serial);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = sc_adb_tunnel_open(&server->tunnel, &server->intr, params->serial,
|
ok = sc_adb_tunnel_open(&server->tunnel, &server->intr, serial,
|
||||||
params->port_range, params->force_adb_forward);
|
params->port_range, params->force_adb_forward);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
|
@ -735,7 +730,7 @@ run_server(void *data) {
|
||||||
// server will connect to our server socket
|
// server will connect to our server socket
|
||||||
sc_pid pid = execute_server(server, params);
|
sc_pid pid = execute_server(server, params);
|
||||||
if (pid == SC_PROCESS_NONE) {
|
if (pid == SC_PROCESS_NONE) {
|
||||||
sc_adb_tunnel_close(&server->tunnel, &server->intr, params->serial);
|
sc_adb_tunnel_close(&server->tunnel, &server->intr, serial);
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +742,7 @@ run_server(void *data) {
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
sc_process_terminate(pid);
|
sc_process_terminate(pid);
|
||||||
sc_process_wait(pid, true); // ignore exit code
|
sc_process_wait(pid, true); // ignore exit code
|
||||||
sc_adb_tunnel_close(&server->tunnel, &server->intr, params->serial);
|
sc_adb_tunnel_close(&server->tunnel, &server->intr, serial);
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,6 +835,7 @@ sc_server_destroy(struct sc_server *server) {
|
||||||
net_close(server->control_socket);
|
net_close(server->control_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(server->serial);
|
||||||
sc_server_params_destroy(&server->params);
|
sc_server_params_destroy(&server->params);
|
||||||
sc_intr_destroy(&server->intr);
|
sc_intr_destroy(&server->intr);
|
||||||
sc_cond_destroy(&server->cond_stopped);
|
sc_cond_destroy(&server->cond_stopped);
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct sc_server_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_server_params {
|
struct sc_server_params {
|
||||||
const char *serial;
|
const char *req_serial;
|
||||||
enum sc_log_level log_level;
|
enum sc_log_level log_level;
|
||||||
const char *crop;
|
const char *crop;
|
||||||
const char *codec_options;
|
const char *codec_options;
|
||||||
|
@ -49,6 +49,7 @@ struct sc_server_params {
|
||||||
struct sc_server {
|
struct sc_server {
|
||||||
// The internal allocated strings are copies owned by the server
|
// The internal allocated strings are copies owned by the server
|
||||||
struct sc_server_params params;
|
struct sc_server_params params;
|
||||||
|
char *serial;
|
||||||
|
|
||||||
sc_thread thread;
|
sc_thread thread;
|
||||||
struct sc_server_info info; // initialized once connected
|
struct sc_server_info info; // initialized once connected
|
||||||
|
|
Loading…
Reference in a new issue