Compare commits
5 Commits
cleanup_se
...
server_thr
Author | SHA1 | Date | |
---|---|---|---|
c37d455fa2 | |||
6e8df74c41 | |||
52f5c6d4c1 | |||
efb531943d | |||
4dcda82582 |
@ -243,10 +243,6 @@ av_log_callback(void *avcl, int level, const char *fmt, va_list vl) {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
scrcpy(const struct scrcpy_options *options) {
|
scrcpy(const struct scrcpy_options *options) {
|
||||||
if (!server_init(&server)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
bool server_started = false;
|
bool server_started = false;
|
||||||
@ -263,6 +259,7 @@ scrcpy(const struct scrcpy_options *options) {
|
|||||||
|
|
||||||
bool record = !!options->record_filename;
|
bool record = !!options->record_filename;
|
||||||
struct server_params params = {
|
struct server_params params = {
|
||||||
|
.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,
|
||||||
@ -279,7 +276,12 @@ scrcpy(const struct scrcpy_options *options) {
|
|||||||
.force_adb_forward = options->force_adb_forward,
|
.force_adb_forward = options->force_adb_forward,
|
||||||
.power_off_on_close = options->power_off_on_close,
|
.power_off_on_close = options->power_off_on_close,
|
||||||
};
|
};
|
||||||
if (!server_start(&server, options->serial, ¶ms)) {
|
|
||||||
|
if (!server_init(&server, ¶ms)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!server_start(&server)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +313,7 @@ scrcpy(const struct scrcpy_options *options) {
|
|||||||
fps_counter_initialized = true;
|
fps_counter_initialized = true;
|
||||||
|
|
||||||
if (options->control) {
|
if (options->control) {
|
||||||
if (!file_handler_init(&file_handler, server.serial,
|
if (!file_handler_init(&file_handler, options->serial,
|
||||||
options->push_target)) {
|
options->push_target)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
115
app/src/server.c
115
app/src/server.c
@ -128,9 +128,10 @@ disable_tunnel_forward(const char *serial, uint16_t local_port) {
|
|||||||
static bool
|
static bool
|
||||||
disable_tunnel(struct server *server) {
|
disable_tunnel(struct server *server) {
|
||||||
if (server->tunnel_forward) {
|
if (server->tunnel_forward) {
|
||||||
return disable_tunnel_forward(server->serial, server->local_port);
|
return disable_tunnel_forward(server->params.serial,
|
||||||
|
server->local_port);
|
||||||
}
|
}
|
||||||
return disable_tunnel_reverse(server->serial);
|
return disable_tunnel_reverse(server->params.serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static socket_t
|
static socket_t
|
||||||
@ -144,7 +145,7 @@ enable_tunnel_reverse_any_port(struct server *server,
|
|||||||
struct sc_port_range port_range) {
|
struct sc_port_range port_range) {
|
||||||
uint16_t port = port_range.first;
|
uint16_t port = port_range.first;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!enable_tunnel_reverse(server->serial, port)) {
|
if (!enable_tunnel_reverse(server->params.serial, port)) {
|
||||||
// the command itself failed, it will fail on any port
|
// the command itself failed, it will fail on any port
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -163,7 +164,7 @@ enable_tunnel_reverse_any_port(struct server *server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// failure, disable tunnel and try another port
|
// failure, disable tunnel and try another port
|
||||||
if (!disable_tunnel_reverse(server->serial)) {
|
if (!disable_tunnel_reverse(server->params.serial)) {
|
||||||
LOGW("Could not remove reverse tunnel on port %" PRIu16, port);
|
LOGW("Could not remove reverse tunnel on port %" PRIu16, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +192,7 @@ enable_tunnel_forward_any_port(struct server *server,
|
|||||||
server->tunnel_forward = true;
|
server->tunnel_forward = true;
|
||||||
uint16_t port = port_range.first;
|
uint16_t port = port_range.first;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (enable_tunnel_forward(server->serial, port)) {
|
if (enable_tunnel_forward(server->params.serial, port)) {
|
||||||
// success
|
// success
|
||||||
server->local_port = port;
|
server->local_port = port;
|
||||||
return true;
|
return true;
|
||||||
@ -306,7 +307,7 @@ execute_server(struct server *server, const struct server_params *params) {
|
|||||||
// Port: 5005
|
// Port: 5005
|
||||||
// Then click on "Debug"
|
// Then click on "Debug"
|
||||||
#endif
|
#endif
|
||||||
return adb_execute(server->serial, cmd, sizeof(cmd) / sizeof(cmd[0]));
|
return adb_execute(server->params.serial, cmd, ARRAY_LEN(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
static socket_t
|
static socket_t
|
||||||
@ -352,21 +353,75 @@ close_socket(socket_t socket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
server_params_destroy(struct server_params *params) {
|
||||||
|
// The server stores a copy of the params provided by the user
|
||||||
|
free((char *) params->crop);
|
||||||
|
free((char *) params->codec_options);
|
||||||
|
free((char *) params->encoder_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
server_params_copy(struct server_params *dst, const struct server_params *src) {
|
||||||
|
// params reference user-allocated memory, so we must copy them to handle
|
||||||
|
// them from a separate thread
|
||||||
|
|
||||||
|
*dst = *src;
|
||||||
|
|
||||||
|
dst->crop = NULL;
|
||||||
|
dst->codec_options = NULL;
|
||||||
|
dst->encoder_name = NULL;
|
||||||
|
|
||||||
|
if (src->crop) {
|
||||||
|
dst->crop = strdup(src->crop);
|
||||||
|
if (!dst->crop) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->codec_options) {
|
||||||
|
dst->codec_options = strdup(src->codec_options);
|
||||||
|
if (!dst->codec_options) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->encoder_name) {
|
||||||
|
dst->encoder_name = strdup(src->encoder_name);
|
||||||
|
if (!dst->encoder_name) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
server_params_destroy(dst);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
server_init(struct server *server) {
|
server_init(struct server *server, const struct server_params *params) {
|
||||||
server->serial = NULL;
|
if (!server_params_copy(&server->params, params)) {
|
||||||
|
LOGE("Could not copy server params");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
server->process = PROCESS_NONE;
|
server->process = PROCESS_NONE;
|
||||||
atomic_flag_clear_explicit(&server->server_socket_closed,
|
atomic_flag_clear_explicit(&server->server_socket_closed,
|
||||||
memory_order_relaxed);
|
memory_order_relaxed);
|
||||||
|
|
||||||
bool ok = sc_mutex_init(&server->mutex);
|
bool ok = sc_mutex_init(&server->mutex);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
|
server_params_destroy(&server->params);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = sc_cond_init(&server->process_terminated_cond);
|
ok = sc_cond_init(&server->process_terminated_cond);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
sc_mutex_destroy(&server->mutex);
|
sc_mutex_destroy(&server->mutex);
|
||||||
|
server_params_destroy(&server->params);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,31 +461,41 @@ run_wait_server(void *data) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static int
|
||||||
server_start(struct server *server, const char *serial,
|
run_server(void *data) {
|
||||||
const struct server_params *params) {
|
struct server *server = data;
|
||||||
if (serial) {
|
|
||||||
server->serial = strdup(serial);
|
|
||||||
if (!server->serial) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!push_server(serial)) {
|
const struct server_params *params = &server->params;
|
||||||
goto error1;
|
const struct server_callbacks *cbs = &server->cbs;
|
||||||
|
void *userdata = server->userdata;
|
||||||
|
|
||||||
|
if (!push_server(params->serial)) {
|
||||||
|
cbs->on_connection_failed(server);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enable_tunnel_any_port(server, params->port_range,
|
if (!enable_tunnel_any_port(server, params->port_range,
|
||||||
params->force_adb_forward)) {
|
params->force_adb_forward)) {
|
||||||
goto error1;
|
cbs->on_connection_failed(server);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// server will connect to our server socket
|
// server will connect to our server socket
|
||||||
server->process = execute_server(server, params);
|
server->process = execute_server(server, params);
|
||||||
if (server->process == PROCESS_NONE) {
|
if (server->process == PROCESS_NONE) {
|
||||||
goto error2;
|
cbs->on_connection_failed(server);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process_wait(server->process, false); // ignore exit code
|
||||||
|
|
||||||
|
end:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
server_start(struct server *server) {
|
||||||
|
|
||||||
// If the server process dies before connecting to the server socket, then
|
// If the server process dies before connecting to the server socket, then
|
||||||
// the client will be stuck forever on accept(). To avoid the problem, we
|
// the client will be stuck forever on accept(). To avoid the problem, we
|
||||||
// must be able to wake up the accept() call when the server dies. To keep
|
// must be able to wake up the accept() call when the server dies. To keep
|
||||||
@ -442,14 +507,14 @@ server_start(struct server *server, const char *serial,
|
|||||||
if (!ok) {
|
if (!ok) {
|
||||||
process_terminate(server->process);
|
process_terminate(server->process);
|
||||||
process_wait(server->process, true); // ignore exit code
|
process_wait(server->process, true); // ignore exit code
|
||||||
goto error2;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
server->tunnel_enabled = true;
|
server->tunnel_enabled = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error2:
|
error:
|
||||||
if (!server->tunnel_forward) {
|
if (!server->tunnel_forward) {
|
||||||
bool was_closed =
|
bool was_closed =
|
||||||
atomic_flag_test_and_set(&server->server_socket_closed);
|
atomic_flag_test_and_set(&server->server_socket_closed);
|
||||||
@ -459,8 +524,7 @@ error2:
|
|||||||
close_socket(server->server_socket);
|
close_socket(server->server_socket);
|
||||||
}
|
}
|
||||||
disable_tunnel(server);
|
disable_tunnel(server);
|
||||||
error1:
|
|
||||||
free(server->serial);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,4 +622,5 @@ server_destroy(struct server *server) {
|
|||||||
free(server->serial);
|
free(server->serial);
|
||||||
sc_cond_destroy(&server->process_terminated_cond);
|
sc_cond_destroy(&server->process_terminated_cond);
|
||||||
sc_mutex_destroy(&server->mutex);
|
sc_mutex_destroy(&server->mutex);
|
||||||
|
server_params_destroy(&server->params);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,25 @@
|
|||||||
#include "util/net.h"
|
#include "util/net.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
|
|
||||||
|
struct server_params {
|
||||||
|
enum sc_log_level log_level;
|
||||||
|
const char *serial;
|
||||||
|
const char *crop;
|
||||||
|
const char *codec_options;
|
||||||
|
const char *encoder_name;
|
||||||
|
struct sc_port_range port_range;
|
||||||
|
uint16_t max_size;
|
||||||
|
uint32_t bit_rate;
|
||||||
|
uint16_t max_fps;
|
||||||
|
int8_t lock_video_orientation;
|
||||||
|
bool control;
|
||||||
|
uint32_t display_id;
|
||||||
|
bool show_touches;
|
||||||
|
bool stay_awake;
|
||||||
|
bool force_adb_forward;
|
||||||
|
bool power_off_on_close;
|
||||||
|
};
|
||||||
|
|
||||||
struct server {
|
struct server {
|
||||||
char *serial;
|
char *serial;
|
||||||
process_t process;
|
process_t process;
|
||||||
@ -29,34 +48,29 @@ struct server {
|
|||||||
uint16_t local_port; // selected from port_range
|
uint16_t local_port; // selected from port_range
|
||||||
bool tunnel_enabled;
|
bool tunnel_enabled;
|
||||||
bool tunnel_forward; // use "adb forward" instead of "adb reverse"
|
bool tunnel_forward; // use "adb forward" instead of "adb reverse"
|
||||||
|
|
||||||
|
// The internal allocated strings are copies owned by the server
|
||||||
|
struct server_params params;
|
||||||
|
|
||||||
|
const struct server_callbacks *cbs;
|
||||||
|
void *userdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct server_params {
|
struct server_callbacks {
|
||||||
enum sc_log_level log_level;
|
void (*on_connection_failed)(struct server *server);
|
||||||
const char *crop;
|
void (*on_connected)(struct server *server, const char *name,
|
||||||
const char *codec_options;
|
struct size size, void *userdata);
|
||||||
const char *encoder_name;
|
void (*on_disconnected)(struct server *server, void *userdata);
|
||||||
struct sc_port_range port_range;
|
|
||||||
uint16_t max_size;
|
|
||||||
uint32_t bit_rate;
|
|
||||||
uint16_t max_fps;
|
|
||||||
int8_t lock_video_orientation;
|
|
||||||
bool control;
|
|
||||||
uint32_t display_id;
|
|
||||||
bool show_touches;
|
|
||||||
bool stay_awake;
|
|
||||||
bool force_adb_forward;
|
|
||||||
bool power_off_on_close;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// init default values
|
// init server fields
|
||||||
bool
|
bool
|
||||||
server_init(struct server *server);
|
server_init(struct server *server, const struct server_params *params);
|
||||||
|
|
||||||
// push, enable tunnel et start the server
|
// push, enable tunnel et start the server
|
||||||
bool
|
bool
|
||||||
server_start(struct server *server, const char *serial,
|
server_start(struct server *server, const struct server_callbacks *cbs,
|
||||||
const struct server_params *params);
|
void *userdata);
|
||||||
|
|
||||||
// block until the communication with the server is established
|
// block until the communication with the server is established
|
||||||
bool
|
bool
|
||||||
|
Reference in New Issue
Block a user