Extract adb tunnel to a separate component
This simplifies the server code.
This commit is contained in:
parent
0d45c29d13
commit
c4d008b96a
5 changed files with 260 additions and 191 deletions
|
@ -1,6 +1,7 @@
|
||||||
src = [
|
src = [
|
||||||
'src/main.c',
|
'src/main.c',
|
||||||
'src/adb.c',
|
'src/adb.c',
|
||||||
|
'src/adb_tunnel.c',
|
||||||
'src/cli.c',
|
'src/cli.c',
|
||||||
'src/clock.c',
|
'src/clock.c',
|
||||||
'src/compat.c',
|
'src/compat.c',
|
||||||
|
|
192
app/src/adb_tunnel.c
Normal file
192
app/src/adb_tunnel.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
#include "adb_tunnel.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "adb.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/net_intr.h"
|
||||||
|
#include "util/process_intr.h"
|
||||||
|
|
||||||
|
#define SC_SOCKET_NAME "scrcpy"
|
||||||
|
|
||||||
|
static bool
|
||||||
|
enable_tunnel_reverse(struct sc_intr *intr, const char *serial,
|
||||||
|
uint16_t local_port) {
|
||||||
|
sc_pid pid = adb_reverse(serial, SC_SOCKET_NAME, local_port);
|
||||||
|
return sc_process_check_success_intr(intr, pid, "adb reverse");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
disable_tunnel_reverse(struct sc_intr *intr, const char *serial) {
|
||||||
|
sc_pid pid = adb_reverse_remove(serial, SC_SOCKET_NAME);
|
||||||
|
return sc_process_check_success_intr(intr, pid, "adb reverse --remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
enable_tunnel_forward(struct sc_intr *intr, const char *serial,
|
||||||
|
uint16_t local_port) {
|
||||||
|
sc_pid pid = adb_forward(serial, local_port, SC_SOCKET_NAME);
|
||||||
|
return sc_process_check_success_intr(intr, pid, "adb forward");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
disable_tunnel_forward(struct sc_intr *intr, const char *serial,
|
||||||
|
uint16_t local_port) {
|
||||||
|
sc_pid pid = adb_forward_remove(serial, local_port);
|
||||||
|
return sc_process_check_success_intr(intr, pid, "adb forward --remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
listen_on_port(struct sc_intr *intr, sc_socket socket, uint16_t port) {
|
||||||
|
return net_listen_intr(intr, socket, IPV4_LOCALHOST, port, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
enable_tunnel_reverse_any_port(struct sc_adb_tunnel *tunnel,
|
||||||
|
struct sc_intr *intr, const char *serial,
|
||||||
|
struct sc_port_range port_range) {
|
||||||
|
uint16_t port = port_range.first;
|
||||||
|
for (;;) {
|
||||||
|
if (!enable_tunnel_reverse(intr, serial, port)) {
|
||||||
|
// the command itself failed, it will fail on any port
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At the application level, the device part is "the server" because it
|
||||||
|
// serves video stream and control. However, at the network level, the
|
||||||
|
// client listens and the server connects to the client. That way, the
|
||||||
|
// client can listen before starting the server app, so there is no
|
||||||
|
// need to try to connect until the server socket is listening on the
|
||||||
|
// device.
|
||||||
|
sc_socket server_socket = net_socket();
|
||||||
|
if (server_socket != SC_INVALID_SOCKET) {
|
||||||
|
bool ok = listen_on_port(intr, server_socket, port);
|
||||||
|
if (ok) {
|
||||||
|
// success
|
||||||
|
tunnel->server_socket = server_socket;
|
||||||
|
tunnel->local_port = port;
|
||||||
|
tunnel->enabled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_close(server_socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc_intr_is_interrupted(intr)) {
|
||||||
|
// Stop immediately
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// failure, disable tunnel and try another port
|
||||||
|
if (!disable_tunnel_reverse(intr, serial)) {
|
||||||
|
LOGW("Could not remove reverse tunnel on port %" PRIu16, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check before incrementing to avoid overflow on port 65535
|
||||||
|
if (port < port_range.last) {
|
||||||
|
LOGW("Could not listen on port %" PRIu16", retrying on %" PRIu16,
|
||||||
|
port, (uint16_t) (port + 1));
|
||||||
|
port++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port_range.first == port_range.last) {
|
||||||
|
LOGE("Could not listen on port %" PRIu16, port_range.first);
|
||||||
|
} else {
|
||||||
|
LOGE("Could not listen on any port in range %" PRIu16 ":%" PRIu16,
|
||||||
|
port_range.first, port_range.last);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
enable_tunnel_forward_any_port(struct sc_adb_tunnel *tunnel,
|
||||||
|
struct sc_intr *intr, const char *serial,
|
||||||
|
struct sc_port_range port_range) {
|
||||||
|
tunnel->forward = true;
|
||||||
|
|
||||||
|
uint16_t port = port_range.first;
|
||||||
|
for (;;) {
|
||||||
|
if (enable_tunnel_forward(intr, serial, port)) {
|
||||||
|
// success
|
||||||
|
tunnel->local_port = port;
|
||||||
|
tunnel->enabled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc_intr_is_interrupted(intr)) {
|
||||||
|
// Stop immediately
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port < port_range.last) {
|
||||||
|
LOGW("Could not forward port %" PRIu16", retrying on %" PRIu16,
|
||||||
|
port, (uint16_t) (port + 1));
|
||||||
|
port++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port_range.first == port_range.last) {
|
||||||
|
LOGE("Could not forward port %" PRIu16, port_range.first);
|
||||||
|
} else {
|
||||||
|
LOGE("Could not forward any port in range %" PRIu16 ":%" PRIu16,
|
||||||
|
port_range.first, port_range.last);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_adb_tunnel_init(struct sc_adb_tunnel *tunnel) {
|
||||||
|
tunnel->enabled = false;
|
||||||
|
tunnel->forward = false;
|
||||||
|
tunnel->server_socket = SC_INVALID_SOCKET;
|
||||||
|
tunnel->local_port = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_adb_tunnel_open(struct sc_adb_tunnel *tunnel, struct sc_intr *intr,
|
||||||
|
const char *serial, struct sc_port_range port_range,
|
||||||
|
bool force_adb_forward) {
|
||||||
|
assert(!tunnel->enabled);
|
||||||
|
|
||||||
|
if (!force_adb_forward) {
|
||||||
|
// Attempt to use "adb reverse"
|
||||||
|
if (enable_tunnel_reverse_any_port(tunnel, intr, serial, port_range)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if "adb reverse" does not work (e.g. over "adb connect"), it
|
||||||
|
// fallbacks to "adb forward", so the app socket is the client
|
||||||
|
|
||||||
|
LOGW("'adb reverse' failed, fallback to 'adb forward'");
|
||||||
|
}
|
||||||
|
|
||||||
|
return enable_tunnel_forward_any_port(tunnel, intr, serial, port_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_adb_tunnel_close(struct sc_adb_tunnel *tunnel, struct sc_intr *intr,
|
||||||
|
const char *serial) {
|
||||||
|
assert(tunnel->enabled);
|
||||||
|
|
||||||
|
bool ret;
|
||||||
|
if (tunnel->forward) {
|
||||||
|
ret = disable_tunnel_forward(intr, serial, tunnel->local_port);
|
||||||
|
} else {
|
||||||
|
ret = disable_tunnel_reverse(intr, serial);
|
||||||
|
|
||||||
|
assert(tunnel->server_socket != SC_INVALID_SOCKET);
|
||||||
|
if (!net_close(tunnel->server_socket)) {
|
||||||
|
LOGW("Could not close server socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
// server_socket is never used anymore
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consider tunnel disabled even if the command failed
|
||||||
|
tunnel->enabled = false;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
47
app/src/adb_tunnel.h
Normal file
47
app/src/adb_tunnel.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef SC_ADB_TUNNEL_H
|
||||||
|
#define SC_ADB_TUNNEL_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "options.h"
|
||||||
|
#include "util/intr.h"
|
||||||
|
#include "util/net.h"
|
||||||
|
|
||||||
|
struct sc_adb_tunnel {
|
||||||
|
bool enabled;
|
||||||
|
bool forward; // use "adb forward" instead of "adb reverse"
|
||||||
|
sc_socket server_socket; // only used if !forward
|
||||||
|
uint16_t local_port;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the adb tunnel struct to default values
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sc_adb_tunnel_init(struct sc_adb_tunnel *tunnel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a tunnel
|
||||||
|
*
|
||||||
|
* Blocking calls may be interrupted asynchronously via `intr`.
|
||||||
|
*
|
||||||
|
* If `force_adb_forward` is not set, then attempts to set up an "adb reverse"
|
||||||
|
* tunnel first. Only if it fails (typical on old Android version connected via
|
||||||
|
* TCP/IP), use "adb forward".
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
sc_adb_tunnel_open(struct sc_adb_tunnel *tunnel, struct sc_intr *intr,
|
||||||
|
const char *serial, struct sc_port_range port_range,
|
||||||
|
bool force_adb_forward);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the tunnel
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
sc_adb_tunnel_close(struct sc_adb_tunnel *tunnel, struct sc_intr *intr,
|
||||||
|
const char *serial);
|
||||||
|
|
||||||
|
#endif
|
205
app/src/server.c
205
app/src/server.c
|
@ -14,7 +14,6 @@
|
||||||
#include "util/process_intr.h"
|
#include "util/process_intr.h"
|
||||||
#include "util/str_util.h"
|
#include "util/str_util.h"
|
||||||
|
|
||||||
#define SOCKET_NAME "scrcpy"
|
|
||||||
#define SERVER_FILENAME "scrcpy-server"
|
#define SERVER_FILENAME "scrcpy-server"
|
||||||
|
|
||||||
#define DEFAULT_SERVER_PATH PREFIX "/share/scrcpy/" SERVER_FILENAME
|
#define DEFAULT_SERVER_PATH PREFIX "/share/scrcpy/" SERVER_FILENAME
|
||||||
|
@ -117,167 +116,6 @@ push_server(struct sc_intr *intr, const char *serial) {
|
||||||
return sc_process_check_success_intr(intr, pid, "adb push");
|
return sc_process_check_success_intr(intr, pid, "adb push");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
enable_tunnel_reverse(struct sc_intr *intr, const char *serial,
|
|
||||||
uint16_t local_port) {
|
|
||||||
sc_pid pid = adb_reverse(serial, SOCKET_NAME, local_port);
|
|
||||||
return sc_process_check_success_intr(intr, pid, "adb reverse");
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
disable_tunnel_reverse(struct sc_intr *intr, const char *serial) {
|
|
||||||
sc_pid pid = adb_reverse_remove(serial, SOCKET_NAME);
|
|
||||||
return sc_process_check_success_intr(intr, pid, "adb reverse --remove");
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
enable_tunnel_forward(struct sc_intr *intr, const char *serial,
|
|
||||||
uint16_t local_port) {
|
|
||||||
sc_pid pid = adb_forward(serial, local_port, SOCKET_NAME);
|
|
||||||
return sc_process_check_success_intr(intr, pid, "adb forward");
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
disable_tunnel_forward(struct sc_intr *intr, const char *serial,
|
|
||||||
uint16_t local_port) {
|
|
||||||
sc_pid pid = adb_forward_remove(serial, local_port);
|
|
||||||
return sc_process_check_success_intr(intr, pid, "adb forward --remove");
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
disable_tunnel(struct server *server) {
|
|
||||||
assert(server->tunnel_enabled);
|
|
||||||
|
|
||||||
const char *serial = server->params.serial;
|
|
||||||
bool ok = server->tunnel_forward
|
|
||||||
? disable_tunnel_forward(&server->intr, serial, server->local_port)
|
|
||||||
: disable_tunnel_reverse(&server->intr, serial);
|
|
||||||
|
|
||||||
// Consider tunnel disabled even if the command failed
|
|
||||||
server->tunnel_enabled = false;
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
listen_on_port(struct sc_intr *intr, sc_socket socket, uint16_t port) {
|
|
||||||
return net_listen_intr(intr, socket, IPV4_LOCALHOST, port, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
enable_tunnel_reverse_any_port(struct server *server,
|
|
||||||
struct sc_port_range port_range) {
|
|
||||||
const char *serial = server->params.serial;
|
|
||||||
uint16_t port = port_range.first;
|
|
||||||
for (;;) {
|
|
||||||
if (!enable_tunnel_reverse(&server->intr, serial, port)) {
|
|
||||||
// the command itself failed, it will fail on any port
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// At the application level, the device part is "the server" because it
|
|
||||||
// serves video stream and control. However, at the network level, the
|
|
||||||
// client listens and the server connects to the client. That way, the
|
|
||||||
// client can listen before starting the server app, so there is no
|
|
||||||
// need to try to connect until the server socket is listening on the
|
|
||||||
// device.
|
|
||||||
sc_socket server_socket = net_socket();
|
|
||||||
if (server_socket != SC_INVALID_SOCKET) {
|
|
||||||
bool ok = listen_on_port(&server->intr, server_socket, port);
|
|
||||||
if (ok) {
|
|
||||||
// success
|
|
||||||
server->server_socket = server_socket;
|
|
||||||
server->local_port = port;
|
|
||||||
server->tunnel_enabled = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_close(server_socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc_intr_is_interrupted(&server->intr)) {
|
|
||||||
// Stop immediately
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// failure, disable tunnel and try another port
|
|
||||||
if (!disable_tunnel_reverse(&server->intr, serial)) {
|
|
||||||
LOGW("Could not remove reverse tunnel on port %" PRIu16, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check before incrementing to avoid overflow on port 65535
|
|
||||||
if (port < port_range.last) {
|
|
||||||
LOGW("Could not listen on port %" PRIu16", retrying on %" PRIu16,
|
|
||||||
port, (uint16_t) (port + 1));
|
|
||||||
port++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port_range.first == port_range.last) {
|
|
||||||
LOGE("Could not listen on port %" PRIu16, port_range.first);
|
|
||||||
} else {
|
|
||||||
LOGE("Could not listen on any port in range %" PRIu16 ":%" PRIu16,
|
|
||||||
port_range.first, port_range.last);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
enable_tunnel_forward_any_port(struct server *server,
|
|
||||||
struct sc_port_range port_range) {
|
|
||||||
server->tunnel_forward = true;
|
|
||||||
|
|
||||||
const char *serial = server->params.serial;
|
|
||||||
uint16_t port = port_range.first;
|
|
||||||
for (;;) {
|
|
||||||
if (enable_tunnel_forward(&server->intr, serial, port)) {
|
|
||||||
// success
|
|
||||||
server->local_port = port;
|
|
||||||
server->tunnel_enabled = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc_intr_is_interrupted(&server->intr)) {
|
|
||||||
// Stop immediately
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port < port_range.last) {
|
|
||||||
LOGW("Could not forward port %" PRIu16", retrying on %" PRIu16,
|
|
||||||
port, (uint16_t) (port + 1));
|
|
||||||
port++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port_range.first == port_range.last) {
|
|
||||||
LOGE("Could not forward port %" PRIu16, port_range.first);
|
|
||||||
} else {
|
|
||||||
LOGE("Could not forward any port in range %" PRIu16 ":%" PRIu16,
|
|
||||||
port_range.first, port_range.last);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
enable_tunnel_any_port(struct server *server, struct sc_port_range port_range,
|
|
||||||
bool force_adb_forward) {
|
|
||||||
if (!force_adb_forward) {
|
|
||||||
// Attempt to use "adb reverse"
|
|
||||||
if (enable_tunnel_reverse_any_port(server, port_range)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if "adb reverse" does not work (e.g. over "adb connect"), it
|
|
||||||
// fallbacks to "adb forward", so the app socket is the client
|
|
||||||
|
|
||||||
LOGW("'adb reverse' failed, fallback to 'adb forward'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return enable_tunnel_forward_any_port(server, port_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
log_level_to_server_string(enum sc_log_level level) {
|
log_level_to_server_string(enum sc_log_level level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
|
@ -336,7 +174,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 ? "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",
|
||||||
|
@ -381,7 +219,7 @@ connect_and_read_byte(struct sc_intr *intr, sc_socket socket, uint16_t port) {
|
||||||
|
|
||||||
static sc_socket
|
static sc_socket
|
||||||
connect_to_server(struct server *server, uint32_t attempts, sc_tick delay) {
|
connect_to_server(struct server *server, uint32_t attempts, sc_tick delay) {
|
||||||
uint16_t port = server->local_port;
|
uint16_t port = server->tunnel.local_port;
|
||||||
do {
|
do {
|
||||||
LOGD("Remaining connection attempts: %d", (int) attempts);
|
LOGD("Remaining connection attempts: %d", (int) attempts);
|
||||||
sc_socket socket = net_socket();
|
sc_socket socket = net_socket();
|
||||||
|
@ -449,14 +287,10 @@ server_init(struct server *server, const struct server_params *params,
|
||||||
|
|
||||||
server->stopped = false;
|
server->stopped = false;
|
||||||
|
|
||||||
server->server_socket = SC_INVALID_SOCKET;
|
|
||||||
server->video_socket = SC_INVALID_SOCKET;
|
server->video_socket = SC_INVALID_SOCKET;
|
||||||
server->control_socket = SC_INVALID_SOCKET;
|
server->control_socket = SC_INVALID_SOCKET;
|
||||||
|
|
||||||
server->local_port = 0;
|
sc_adb_tunnel_init(&server->tunnel);
|
||||||
|
|
||||||
server->tunnel_enabled = false;
|
|
||||||
server->tunnel_forward = false;
|
|
||||||
|
|
||||||
assert(cbs);
|
assert(cbs);
|
||||||
assert(cbs->on_connection_failed);
|
assert(cbs->on_connection_failed);
|
||||||
|
@ -491,27 +325,24 @@ device_read_info(struct sc_intr *intr, sc_socket device_socket,
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
server_connect_to(struct server *server, struct server_info *info) {
|
server_connect_to(struct server *server, struct server_info *info) {
|
||||||
assert(server->tunnel_enabled);
|
struct sc_adb_tunnel *tunnel = &server->tunnel;
|
||||||
|
|
||||||
|
assert(tunnel->enabled);
|
||||||
|
|
||||||
|
const char *serial = server->params.serial;
|
||||||
|
|
||||||
sc_socket video_socket = SC_INVALID_SOCKET;
|
sc_socket video_socket = SC_INVALID_SOCKET;
|
||||||
sc_socket control_socket = SC_INVALID_SOCKET;
|
sc_socket control_socket = SC_INVALID_SOCKET;
|
||||||
if (!server->tunnel_forward) {
|
if (!tunnel->forward) {
|
||||||
video_socket = net_accept_intr(&server->intr, server->server_socket);
|
video_socket = net_accept_intr(&server->intr, tunnel->server_socket);
|
||||||
if (video_socket == SC_INVALID_SOCKET) {
|
if (video_socket == SC_INVALID_SOCKET) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
control_socket = net_accept_intr(&server->intr, server->server_socket);
|
control_socket = net_accept_intr(&server->intr, tunnel->server_socket);
|
||||||
if (control_socket == SC_INVALID_SOCKET) {
|
if (control_socket == SC_INVALID_SOCKET) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't need the server socket anymore
|
|
||||||
if (!net_close(server->server_socket)) {
|
|
||||||
LOGW("Could not close server socket on connect");
|
|
||||||
}
|
|
||||||
|
|
||||||
// server_socket is never used anymore
|
|
||||||
} else {
|
} else {
|
||||||
uint32_t attempts = 100;
|
uint32_t attempts = 100;
|
||||||
sc_tick delay = SC_TICK_FROM_MS(100);
|
sc_tick delay = SC_TICK_FROM_MS(100);
|
||||||
|
@ -526,14 +357,14 @@ server_connect_to(struct server *server, struct server_info *info) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
bool ok = net_connect_intr(&server->intr, control_socket,
|
bool ok = net_connect_intr(&server->intr, control_socket,
|
||||||
IPV4_LOCALHOST, server->local_port);
|
IPV4_LOCALHOST, tunnel->local_port);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't need the adb tunnel anymore
|
// we don't need the adb tunnel anymore
|
||||||
disable_tunnel(server); // ignore failure
|
sc_adb_tunnel_close(tunnel, &server->intr, serial);
|
||||||
|
|
||||||
// The sockets will be closed on stop if device_read_info() fails
|
// The sockets will be closed on stop if device_read_info() fails
|
||||||
bool ok = device_read_info(&server->intr, video_socket, info);
|
bool ok = device_read_info(&server->intr, video_socket, info);
|
||||||
|
@ -563,7 +394,7 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always leave this function with tunnel disabled
|
// Always leave this function with tunnel disabled
|
||||||
disable_tunnel(server);
|
sc_adb_tunnel_close(tunnel, &server->intr, serial);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -594,8 +425,8 @@ run_server(void *data) {
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = enable_tunnel_any_port(server, params->port_range,
|
ok = sc_adb_tunnel_open(&server->tunnel, &server->intr, params->serial,
|
||||||
params->force_adb_forward);
|
params->port_range, params->force_adb_forward);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
@ -603,7 +434,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) {
|
||||||
disable_tunnel(server);
|
sc_adb_tunnel_close(&server->tunnel, &server->intr, params->serial);
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +446,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
|
||||||
disable_tunnel(server);
|
sc_adb_tunnel_close(&server->tunnel, &server->intr, params->serial);
|
||||||
goto error_connection_failed;
|
goto error_connection_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
|
#include "adb_tunnel.h"
|
||||||
#include "coords.h"
|
#include "coords.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "util/intr.h"
|
#include "util/intr.h"
|
||||||
|
@ -52,13 +53,10 @@ struct server {
|
||||||
bool stopped;
|
bool stopped;
|
||||||
|
|
||||||
struct sc_intr intr;
|
struct sc_intr intr;
|
||||||
|
struct sc_adb_tunnel tunnel;
|
||||||
|
|
||||||
sc_socket server_socket; // only used if !tunnel_forward
|
|
||||||
sc_socket video_socket;
|
sc_socket video_socket;
|
||||||
sc_socket control_socket;
|
sc_socket control_socket;
|
||||||
uint16_t local_port; // selected from port_range
|
|
||||||
bool tunnel_enabled;
|
|
||||||
bool tunnel_forward; // use "adb forward" instead of "adb reverse"
|
|
||||||
|
|
||||||
const struct server_callbacks *cbs;
|
const struct server_callbacks *cbs;
|
||||||
void *cbs_userdata;
|
void *cbs_userdata;
|
||||||
|
|
Loading…
Reference in a new issue