mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-02 22:29:25 +00:00
Merge 02fc377e95
into 431c9ee33b
This commit is contained in:
commit
79e003ac18
9 changed files with 293 additions and 13 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "abstractcat"]
|
||||||
|
path = abstractcat
|
||||||
|
url = https://github.com/excitoon/abstractcat
|
1
abstractcat
Submodule
1
abstractcat
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit f232a5a7d590089721c64b5257198064bdf9fab7
|
|
@ -651,6 +651,8 @@ guess_record_format(const char *filename) {
|
||||||
#define OPT_DISABLE_SCREENSAVER 1020
|
#define OPT_DISABLE_SCREENSAVER 1020
|
||||||
#define OPT_SHORTCUT_MOD 1021
|
#define OPT_SHORTCUT_MOD 1021
|
||||||
#define OPT_NO_KEY_REPEAT 1022
|
#define OPT_NO_KEY_REPEAT 1022
|
||||||
|
#define OPT_USE_SSH 1024
|
||||||
|
#define OPT_SSH_ENDPOINT 1025
|
||||||
|
|
||||||
bool
|
bool
|
||||||
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
|
@ -686,6 +688,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
{"serial", required_argument, NULL, 's'},
|
{"serial", required_argument, NULL, 's'},
|
||||||
{"shortcut-mod", required_argument, NULL, OPT_SHORTCUT_MOD},
|
{"shortcut-mod", required_argument, NULL, OPT_SHORTCUT_MOD},
|
||||||
{"show-touches", no_argument, NULL, 't'},
|
{"show-touches", no_argument, NULL, 't'},
|
||||||
|
{"ssh-endpoint", required_argument, NULL, OPT_SSH_ENDPOINT},
|
||||||
{"stay-awake", no_argument, NULL, 'w'},
|
{"stay-awake", no_argument, NULL, 'w'},
|
||||||
{"turn-screen-off", no_argument, NULL, 'S'},
|
{"turn-screen-off", no_argument, NULL, 'S'},
|
||||||
{"verbosity", required_argument, NULL, 'V'},
|
{"verbosity", required_argument, NULL, 'V'},
|
||||||
|
@ -697,6 +700,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
{"window-height", required_argument, NULL, OPT_WINDOW_HEIGHT},
|
{"window-height", required_argument, NULL, OPT_WINDOW_HEIGHT},
|
||||||
{"window-borderless", no_argument, NULL,
|
{"window-borderless", no_argument, NULL,
|
||||||
OPT_WINDOW_BORDERLESS},
|
OPT_WINDOW_BORDERLESS},
|
||||||
|
{"use-ssh", no_argument, NULL, OPT_USE_SSH},
|
||||||
{NULL, 0, NULL, 0 },
|
{NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -799,6 +803,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
case OPT_WINDOW_TITLE:
|
case OPT_WINDOW_TITLE:
|
||||||
opts->window_title = optarg;
|
opts->window_title = optarg;
|
||||||
break;
|
break;
|
||||||
|
case OPT_SSH_ENDPOINT:
|
||||||
|
opts->ssh_endpoint = optarg;
|
||||||
|
break;
|
||||||
case OPT_WINDOW_X:
|
case OPT_WINDOW_X:
|
||||||
if (!parse_window_position(optarg, &opts->window_x)) {
|
if (!parse_window_position(optarg, &opts->window_x)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -856,6 +863,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPT_USE_SSH:
|
||||||
|
opts->use_ssh = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// getopt prints the error message on stderr
|
// getopt prints the error message on stderr
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -102,6 +102,49 @@ show_adb_err_msg(enum process_result err, const char *const argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process_t
|
||||||
|
scp_execute(const char *const scp_cmd[], size_t len) {
|
||||||
|
const char *cmd[len + 2];
|
||||||
|
unsigned i = 0;
|
||||||
|
process_t process;
|
||||||
|
|
||||||
|
cmd[i++] = "scp";
|
||||||
|
memcpy(&cmd[i], scp_cmd, len * sizeof(const char *));
|
||||||
|
i += len;
|
||||||
|
cmd[i] = NULL;
|
||||||
|
enum process_result r = cmd_execute(cmd, &process);
|
||||||
|
if (r != PROCESS_SUCCESS) {
|
||||||
|
show_adb_err_msg(r, cmd);
|
||||||
|
return PROCESS_NONE;
|
||||||
|
}
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
|
process_t
|
||||||
|
ssh_execute(const char *endpoint, const char *const ssh_cmd[], size_t len,
|
||||||
|
const char *const prefix_cmd[], size_t prefix_cmd_len,
|
||||||
|
const char *const ssh_options[], size_t ssh_options_len) {
|
||||||
|
const char *cmd[len + prefix_cmd_len + ssh_options_len + 3];
|
||||||
|
unsigned i = 0;
|
||||||
|
process_t process;
|
||||||
|
|
||||||
|
cmd[i++] = "ssh";
|
||||||
|
memcpy(&cmd[i], ssh_options, ssh_options_len * sizeof(const char *));
|
||||||
|
i += ssh_options_len;
|
||||||
|
cmd[i++] = endpoint;
|
||||||
|
memcpy(&cmd[i], prefix_cmd, prefix_cmd_len * sizeof(const char *));
|
||||||
|
i += prefix_cmd_len;
|
||||||
|
memcpy(&cmd[i], ssh_cmd, len * sizeof(const char *));
|
||||||
|
i += len;
|
||||||
|
cmd[i] = NULL;
|
||||||
|
enum process_result r = cmd_execute(cmd, &process);
|
||||||
|
if (r != PROCESS_SUCCESS) {
|
||||||
|
show_adb_err_msg(r, cmd);
|
||||||
|
return PROCESS_NONE;
|
||||||
|
}
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
process_t
|
process_t
|
||||||
adb_execute(const char *serial, const char *const adb_cmd[], size_t len) {
|
adb_execute(const char *serial, const char *const adb_cmd[], size_t len) {
|
||||||
const char *cmd[len + 4];
|
const char *cmd[len + 4];
|
||||||
|
@ -164,6 +207,38 @@ adb_reverse_remove(const char *serial, const char *device_socket_name) {
|
||||||
return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
return adb_execute(serial, adb_cmd, ARRAY_LEN(adb_cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process_t
|
||||||
|
ssh_push(const char *endpoint, const char *local, const char *remote) {
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
// Windows will parse the string, so the paths must be quoted
|
||||||
|
// (see sys/win/command.c)
|
||||||
|
local = strquote(local);
|
||||||
|
if (!local) {
|
||||||
|
return PROCESS_NONE;
|
||||||
|
}
|
||||||
|
remote = strquote(remote);
|
||||||
|
if (!remote) {
|
||||||
|
SDL_free((void *) local);
|
||||||
|
return PROCESS_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char * destination = (char *) SDL_malloc(strlen(remote) + strlen(endpoint) + 2);
|
||||||
|
strcpy(destination, endpoint);
|
||||||
|
strcat(destination, ":");
|
||||||
|
strcat(destination, remote);
|
||||||
|
const char *const scp_cmd[] = {local, destination};
|
||||||
|
process_t proc = scp_execute(scp_cmd, ARRAY_LEN(scp_cmd));
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
SDL_free((void *) remote);
|
||||||
|
SDL_free((void *) local);
|
||||||
|
#endif
|
||||||
|
SDL_free((void *) destination);
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
process_t
|
process_t
|
||||||
adb_push(const char *serial, const char *local, const char *remote) {
|
adb_push(const char *serial, const char *local, const char *remote) {
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
|
|
|
@ -57,6 +57,14 @@ cmd_terminate(process_t pid);
|
||||||
bool
|
bool
|
||||||
cmd_simple_wait(process_t pid, exit_code_t *exit_code);
|
cmd_simple_wait(process_t pid, exit_code_t *exit_code);
|
||||||
|
|
||||||
|
process_t
|
||||||
|
scp_execute(const char *const ssh_cmd[], size_t len);
|
||||||
|
|
||||||
|
process_t
|
||||||
|
ssh_execute(const char *endpoint, const char *const ssh_cmd[], size_t len,
|
||||||
|
const char *const prefix_cmd[], size_t prefix_cmd_len,
|
||||||
|
const char *const ssh_options[], size_t ssh_options_len);
|
||||||
|
|
||||||
process_t
|
process_t
|
||||||
adb_execute(const char *serial, const char *const adb_cmd[], size_t len);
|
adb_execute(const char *serial, const char *const adb_cmd[], size_t len);
|
||||||
|
|
||||||
|
@ -74,6 +82,9 @@ adb_reverse(const char *serial, const char *device_socket_name,
|
||||||
process_t
|
process_t
|
||||||
adb_reverse_remove(const char *serial, const char *device_socket_name);
|
adb_reverse_remove(const char *serial, const char *device_socket_name);
|
||||||
|
|
||||||
|
process_t
|
||||||
|
ssh_push(const char *endpoint, const char *local, const char *remote);
|
||||||
|
|
||||||
process_t
|
process_t
|
||||||
adb_push(const char *serial, const char *local, const char *remote);
|
adb_push(const char *serial, const char *local, const char *remote);
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,8 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
.stay_awake = options->stay_awake,
|
.stay_awake = options->stay_awake,
|
||||||
.codec_options = options->codec_options,
|
.codec_options = options->codec_options,
|
||||||
.force_adb_forward = options->force_adb_forward,
|
.force_adb_forward = options->force_adb_forward,
|
||||||
|
.use_ssh = options->use_ssh,
|
||||||
|
.ssh_endpoint = options->ssh_endpoint,
|
||||||
};
|
};
|
||||||
if (!server_start(&server, options->serial, ¶ms)) {
|
if (!server_start(&server, options->serial, ¶ms)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -51,6 +51,7 @@ struct scrcpy_options {
|
||||||
const char *push_target;
|
const char *push_target;
|
||||||
const char *render_driver;
|
const char *render_driver;
|
||||||
const char *codec_options;
|
const char *codec_options;
|
||||||
|
const char *ssh_endpoint;
|
||||||
enum sc_log_level log_level;
|
enum sc_log_level log_level;
|
||||||
enum sc_record_format record_format;
|
enum sc_record_format record_format;
|
||||||
struct sc_port_range port_range;
|
struct sc_port_range port_range;
|
||||||
|
@ -79,6 +80,7 @@ struct scrcpy_options {
|
||||||
bool force_adb_forward;
|
bool force_adb_forward;
|
||||||
bool disable_screensaver;
|
bool disable_screensaver;
|
||||||
bool forward_key_repeat;
|
bool forward_key_repeat;
|
||||||
|
bool use_ssh;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCRCPY_OPTIONS_DEFAULT { \
|
#define SCRCPY_OPTIONS_DEFAULT { \
|
||||||
|
@ -123,6 +125,8 @@ struct scrcpy_options {
|
||||||
.force_adb_forward = false, \
|
.force_adb_forward = false, \
|
||||||
.disable_screensaver = false, \
|
.disable_screensaver = false, \
|
||||||
.forward_key_repeat = true, \
|
.forward_key_repeat = true, \
|
||||||
|
.use_ssh = false, \
|
||||||
|
.ssh_endpoint = NULL, \
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
196
app/src/server.c
196
app/src/server.c
|
@ -16,11 +16,18 @@
|
||||||
#include "util/str_util.h"
|
#include "util/str_util.h"
|
||||||
|
|
||||||
#define SOCKET_NAME "scrcpy"
|
#define SOCKET_NAME "scrcpy"
|
||||||
|
#define SSH_SOCKET_NAME "/dev/socket/scrcpy"
|
||||||
#define SERVER_FILENAME "scrcpy-server"
|
#define SERVER_FILENAME "scrcpy-server"
|
||||||
|
#define ABSTRACTCAT_FILENAME "abstractcat"
|
||||||
|
|
||||||
#define DEFAULT_SERVER_PATH PREFIX "/share/scrcpy/" SERVER_FILENAME
|
#define DEFAULT_SERVER_PATH PREFIX "/share/scrcpy/" SERVER_FILENAME
|
||||||
#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
|
#define DEVICE_SERVER_PATH "/data/local/tmp/scrcpy-server.jar"
|
||||||
|
|
||||||
|
#define DEFAULT_ABSTRACTCAT_PATH PREFIX "/share/scrcpy/" ABSTRACTCAT_FILENAME
|
||||||
|
#define DEVICE_ABSTRACTCAT_PATH "/data/local/tmp/" ABSTRACTCAT_FILENAME
|
||||||
|
|
||||||
|
static void close_socket(socket_t socket);
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_server_path(void) {
|
get_server_path(void) {
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
|
@ -87,8 +94,90 @@ get_server_path(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_abstractcat_path(void) {
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
const wchar_t *abstractcat_path_env = _wgetenv(L"SCRCPY_ABSTRACTCAT_PATH");
|
||||||
|
#else
|
||||||
|
const char *abstractcat_path_env = getenv("SCRCPY_ABSTRACTCAT_PATH");
|
||||||
|
#endif
|
||||||
|
if (abstractcat_path_env) {
|
||||||
|
// if the envvar is set, use it
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
char *abstractcat_path = utf8_from_wide_char(abstractcat_path_env);
|
||||||
|
#else
|
||||||
|
char *abstractcat_path = SDL_strdup(abstractcat_path_env);
|
||||||
|
#endif
|
||||||
|
if (!abstractcat_path) {
|
||||||
|
LOGE("Could not allocate memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
LOGD("Using SCRCPY_ABSTRACTCAT_PATH: %s", abstractcat_path);
|
||||||
|
return abstractcat_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef PORTABLE
|
||||||
|
LOGD("Using abstractcat: " DEFAULT_ABSTRACTCAT_PATH);
|
||||||
|
char *abstractcat_path = SDL_strdup(DEFAULT_ABSTRACTCAT_PATH);
|
||||||
|
if (!abstractcat_path) {
|
||||||
|
LOGE("Could not allocate memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// the absolute path is hardcoded
|
||||||
|
return abstractcat_path;
|
||||||
|
#else
|
||||||
|
|
||||||
|
// use scrcpy-server in the same directory as the executable
|
||||||
|
char *executable_path = get_executable_path();
|
||||||
|
if (!executable_path) {
|
||||||
|
LOGE("Could not get executable path, "
|
||||||
|
"using " ABSTRACTCAT_FILENAME " from current directory");
|
||||||
|
// not found, use current directory
|
||||||
|
return ABSTRACTCAT_FILENAME;
|
||||||
|
}
|
||||||
|
char *dir = dirname(executable_path);
|
||||||
|
size_t dirlen = strlen(dir);
|
||||||
|
|
||||||
|
// sizeof(ABSTRACTCAT_FILENAME) gives statically the size including the null byte
|
||||||
|
size_t len = dirlen + 1 + sizeof(ABSTRACTCAT_FILENAME);
|
||||||
|
char *abstractcat_path = SDL_malloc(len);
|
||||||
|
if (!abstractcat_path) {
|
||||||
|
LOGE("Could not alloc abstractcat path string, "
|
||||||
|
"using " ABSTRACTCAT_FILENAME " from current directory");
|
||||||
|
SDL_free(executable_path);
|
||||||
|
return ABSTRACTCAT_FILENAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(abstractcat_path, dir, dirlen);
|
||||||
|
abstractcat_path[dirlen] = PATH_SEPARATOR;
|
||||||
|
memcpy(&abstractcat_path[dirlen + 1], ABSTRACTCAT_FILENAME, sizeof(ABSTRACTCAT_FILENAME));
|
||||||
|
// the final null byte has been copied with ABSTRACTCAT_FILENAME
|
||||||
|
|
||||||
|
SDL_free(executable_path);
|
||||||
|
|
||||||
|
LOGD("Using abstractcat (portable): %s", abstractcat_path);
|
||||||
|
return abstractcat_path;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
push_server(const char *serial) {
|
push_abstractcat(const struct server_params *params) {
|
||||||
|
char *abstractcat_path = get_abstractcat_path();
|
||||||
|
if (!abstractcat_path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!is_regular_file(abstractcat_path)) {
|
||||||
|
LOGE("'%s' does not exist or is not a regular file\n", abstractcat_path);
|
||||||
|
SDL_free(abstractcat_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
process_t process = ssh_push(params->ssh_endpoint, abstractcat_path, DEVICE_ABSTRACTCAT_PATH);
|
||||||
|
SDL_free(abstractcat_path);
|
||||||
|
return process_check_success(process, "scp");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
push_server(const char *serial, const struct server_params *params) {
|
||||||
char *server_path = get_server_path();
|
char *server_path = get_server_path();
|
||||||
if (!server_path) {
|
if (!server_path) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -98,11 +187,26 @@ push_server(const char *serial) {
|
||||||
SDL_free(server_path);
|
SDL_free(server_path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
process_t process = adb_push(serial, server_path, DEVICE_SERVER_PATH);
|
process_t process;
|
||||||
|
if (params->use_ssh)
|
||||||
|
process = ssh_push(params->ssh_endpoint, server_path, DEVICE_SERVER_PATH);
|
||||||
|
else
|
||||||
|
process = adb_push(serial, server_path, DEVICE_SERVER_PATH);
|
||||||
SDL_free(server_path);
|
SDL_free(server_path);
|
||||||
return process_check_success(process, "adb push");
|
return process_check_success(process, "adb push");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool prepare_ssh_socket_path(const struct server_params *params) {
|
||||||
|
const char *const cmd[] = {
|
||||||
|
"rm",
|
||||||
|
"-f",
|
||||||
|
SSH_SOCKET_NAME,
|
||||||
|
};
|
||||||
|
process_t process = ssh_execute(params->ssh_endpoint, cmd, sizeof(cmd) / sizeof(cmd[0]),
|
||||||
|
NULL, 0, NULL, 0);
|
||||||
|
return process_check_success(process, "ssh rm -f " SSH_SOCKET_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
enable_tunnel_reverse(const char *serial, uint16_t local_port) {
|
enable_tunnel_reverse(const char *serial, uint16_t local_port) {
|
||||||
process_t process = adb_reverse(serial, SOCKET_NAME, local_port);
|
process_t process = adb_reverse(serial, SOCKET_NAME, local_port);
|
||||||
|
@ -264,9 +368,9 @@ execute_server(struct server *server, const struct server_params *params) {
|
||||||
sprintf(lock_video_orientation_string, "%"PRIi8, params->lock_video_orientation);
|
sprintf(lock_video_orientation_string, "%"PRIi8, params->lock_video_orientation);
|
||||||
sprintf(display_id_string, "%"PRIu16, params->display_id);
|
sprintf(display_id_string, "%"PRIu16, params->display_id);
|
||||||
const char *const cmd[] = {
|
const char *const cmd[] = {
|
||||||
"shell",
|
params->use_ssh ? "ANDROID_DATA=/data" : "shell",
|
||||||
"CLASSPATH=" DEVICE_SERVER_PATH,
|
"CLASSPATH=" DEVICE_SERVER_PATH,
|
||||||
"app_process",
|
"/system/bin/app_process",
|
||||||
#ifdef SERVER_DEBUGGER
|
#ifdef SERVER_DEBUGGER
|
||||||
# define SERVER_DEBUGGER_PORT "5005"
|
# define SERVER_DEBUGGER_PORT "5005"
|
||||||
# ifdef SERVER_DEBUGGER_METHOD_NEW
|
# ifdef SERVER_DEBUGGER_METHOD_NEW
|
||||||
|
@ -286,7 +390,7 @@ execute_server(struct server *server, const struct server_params *params) {
|
||||||
bit_rate_string,
|
bit_rate_string,
|
||||||
max_fps_string,
|
max_fps_string,
|
||||||
lock_video_orientation_string,
|
lock_video_orientation_string,
|
||||||
server->tunnel_forward ? "true" : "false",
|
server->tunnel_forward || params->force_adb_forward ? "true" : "false",
|
||||||
params->crop ? params->crop : "-",
|
params->crop ? params->crop : "-",
|
||||||
"true", // always send frame meta (packet boundaries + timestamp)
|
"true", // always send frame meta (packet boundaries + timestamp)
|
||||||
params->control ? "true" : "false",
|
params->control ? "true" : "false",
|
||||||
|
@ -306,7 +410,59 @@ 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]));
|
if (params->use_ssh)
|
||||||
|
{
|
||||||
|
for (uint16_t port = server->port_range.first;;) {
|
||||||
|
server->server_socket = listen_on_port(port);
|
||||||
|
if (server->server_socket == INVALID_SOCKET) {
|
||||||
|
if (port < server->port_range.last) {
|
||||||
|
LOGW("Could not listen on port %" PRIu16", retrying on %" PRIu16,
|
||||||
|
port, (uint16_t) (port + 1));
|
||||||
|
port++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server->port_range.first == server->port_range.last) {
|
||||||
|
LOGE("Could not listen on port %" PRIu16, server->port_range.first);
|
||||||
|
} else {
|
||||||
|
LOGE("Could not listen on any port in range %" PRIu16 ":%" PRIu16,
|
||||||
|
server->port_range.first, server->port_range.last);
|
||||||
|
}
|
||||||
|
return PROCESS_NONE;
|
||||||
|
}
|
||||||
|
server->local_port = port;
|
||||||
|
char *tunnel_desc = SDL_strdup(SSH_SOCKET_NAME ":localhost:12345");
|
||||||
|
|
||||||
|
if (params->force_adb_forward)
|
||||||
|
sprintf(tunnel_desc, "localhost:%d:" SSH_SOCKET_NAME, port);
|
||||||
|
else
|
||||||
|
sprintf(tunnel_desc, SSH_SOCKET_NAME ":localhost:%d", port);
|
||||||
|
|
||||||
|
const char *const ssh_options[] = {
|
||||||
|
"-o", "ExitOnForwardFailure=yes",
|
||||||
|
params->force_adb_forward ? "-L" : "-R", tunnel_desc,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *const prefix_cmd[] = {
|
||||||
|
DEVICE_ABSTRACTCAT_PATH,
|
||||||
|
params->force_adb_forward ? SSH_SOCKET_NAME : "@" SOCKET_NAME, // Source.
|
||||||
|
params->force_adb_forward ? "@" SOCKET_NAME : SSH_SOCKET_NAME, // Destination.
|
||||||
|
"2", // Maximum connections to forward.
|
||||||
|
};
|
||||||
|
|
||||||
|
if (params->force_adb_forward) {
|
||||||
|
close_socket(server->server_socket);
|
||||||
|
server->server_socket = INVALID_SOCKET;
|
||||||
|
server->tunnel_forward = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ssh_execute(params->ssh_endpoint, cmd, sizeof(cmd) / sizeof(cmd[0]),
|
||||||
|
prefix_cmd, sizeof(prefix_cmd) / sizeof(prefix_cmd[0]),
|
||||||
|
ssh_options, sizeof(ssh_options) / sizeof(ssh_options[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return adb_execute(server->serial, cmd, sizeof(cmd) / sizeof(cmd[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static socket_t
|
static socket_t
|
||||||
|
@ -385,11 +541,19 @@ server_start(struct server *server, const char *serial,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!push_server(serial)) {
|
server->use_ssh = params->use_ssh;
|
||||||
|
|
||||||
|
if (!push_server(serial, params)) {
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enable_tunnel_any_port(server, params->port_range,
|
if (params->use_ssh && !push_abstractcat(params))
|
||||||
|
goto error1;
|
||||||
|
|
||||||
|
if (params->use_ssh && !prepare_ssh_socket_path(params))
|
||||||
|
goto error1;
|
||||||
|
|
||||||
|
if (!params->use_ssh && !enable_tunnel_any_port(server, params->port_range,
|
||||||
params->force_adb_forward)) {
|
params->force_adb_forward)) {
|
||||||
goto error1;
|
goto error1;
|
||||||
}
|
}
|
||||||
|
@ -427,7 +591,10 @@ error2:
|
||||||
(void) was_closed;
|
(void) was_closed;
|
||||||
close_socket(server->server_socket);
|
close_socket(server->server_socket);
|
||||||
}
|
}
|
||||||
disable_tunnel(server);
|
|
||||||
|
if (!server->use_ssh) {
|
||||||
|
disable_tunnel(server);
|
||||||
|
}
|
||||||
error1:
|
error1:
|
||||||
SDL_free(server->serial);
|
SDL_free(server->serial);
|
||||||
return false;
|
return false;
|
||||||
|
@ -470,9 +637,12 @@ server_connect_to(struct server *server) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't need the adb tunnel anymore
|
if (server->tunnel_enabled) {
|
||||||
disable_tunnel(server); // ignore failure
|
// we don't need the adb tunnel anymore
|
||||||
server->tunnel_enabled = false;
|
if (!server->use_ssh)
|
||||||
|
disable_tunnel(server); // ignore failure
|
||||||
|
server->tunnel_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -494,7 +664,7 @@ server_stop(struct server *server) {
|
||||||
|
|
||||||
cmd_terminate(server->process);
|
cmd_terminate(server->process);
|
||||||
|
|
||||||
if (server->tunnel_enabled) {
|
if (server->tunnel_enabled && !server->use_ssh) {
|
||||||
// ignore failure
|
// ignore failure
|
||||||
disable_tunnel(server);
|
disable_tunnel(server);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ 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"
|
||||||
|
bool use_ssh;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_INITIALIZER { \
|
#define SERVER_INITIALIZER { \
|
||||||
|
@ -42,12 +43,14 @@ struct server {
|
||||||
.local_port = 0, \
|
.local_port = 0, \
|
||||||
.tunnel_enabled = false, \
|
.tunnel_enabled = false, \
|
||||||
.tunnel_forward = false, \
|
.tunnel_forward = false, \
|
||||||
|
.use_ssh = false, \
|
||||||
}
|
}
|
||||||
|
|
||||||
struct server_params {
|
struct server_params {
|
||||||
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;
|
||||||
|
const char *ssh_endpoint;
|
||||||
struct sc_port_range port_range;
|
struct sc_port_range port_range;
|
||||||
uint16_t max_size;
|
uint16_t max_size;
|
||||||
uint32_t bit_rate;
|
uint32_t bit_rate;
|
||||||
|
@ -58,6 +61,7 @@ struct server_params {
|
||||||
bool show_touches;
|
bool show_touches;
|
||||||
bool stay_awake;
|
bool stay_awake;
|
||||||
bool force_adb_forward;
|
bool force_adb_forward;
|
||||||
|
bool use_ssh;
|
||||||
};
|
};
|
||||||
|
|
||||||
// init default values
|
// init default values
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue