summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--src/command_function.c11
-rwxr-xr-xsrc/commandline.c16
-rw-r--r--src/common_modules.h18
-rw-r--r--src/listener.c120
-rw-r--r--src/listener.h4
-rwxr-xr-xsrc/sdb.c23
-rw-r--r--src/sdb_constants.c8
-rw-r--r--src/sdb_constants.h7
-rwxr-xr-xsrc/sockets.c249
-rw-r--r--src/sockets.h5
-rwxr-xr-xsrc/transport.c43
-rwxr-xr-xsrc/transport.h4
-rwxr-xr-xsrc/transport_local.c51
-rwxr-xr-xsrc/transport_usb.c30
15 files changed, 406 insertions, 186 deletions
diff --git a/Makefile b/Makefile
index 45c645e..5e89fbd 100644
--- a/Makefile
+++ b/Makefile
@@ -72,6 +72,9 @@ SDB_CFLAGS := -O2 -g -Wall -Wno-unused-parameter
SDB_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
SDB_CFLAGS += -Iinclude -Isrc
SDB_CFLAGS += $(LOCAL_CFLAGS)
+ifeq ($(MAKE_DEBUG),true)
+SDB_CFLAGS += -DMAKE_DEBUG
+endif
SDB_LFLAGS := $(LOCAL_LFLAGS)
STATIC_LFLAGS := $(LOCAL_STATIC_LFLAGS)
diff --git a/src/command_function.c b/src/command_function.c
index 0d5f994..b95a3d1 100644
--- a/src/command_function.c
+++ b/src/command_function.c
@@ -316,14 +316,11 @@ int device_con(int argc, char ** argv, void** extargv) {
}
int get_state_serialno(int argc, char ** argv, void** extargv) {
- char* serial = (char *)extargv[0];
- transport_type* ttype = (transport_type*)extargv[1];
- char *tmp;
- char full_cmd[PATH_MAX];
- format_host_command(full_cmd, sizeof full_cmd, argv[0], *ttype, serial);
- D(COMMANDLINE_MSG_FULL_CMD, argv[0], full_cmd);
- tmp = sdb_query(full_cmd, extargv);
+ char full_cmd[PATH_MAX];
+ format_host_command(full_cmd, sizeof full_cmd, argv[0], *(transport_type *)extargv[1], (char*)extargv[0]);
+ LOG_INFO(COMMANDLINE_MSG_FULL_CMD, argv[0], full_cmd);
+ char* tmp = sdb_query(full_cmd, extargv);
if(tmp) {
printf("%s\n", tmp);
return 0;
diff --git a/src/commandline.c b/src/commandline.c
index 46b8e1b..2558b45 100755
--- a/src/commandline.c
+++ b/src/commandline.c
@@ -303,6 +303,22 @@ static void create_cmd_list(LIST_NODE** cmd_list) {
COMMANDLINE_DEVICE_CON_DESC_SIZE, COMMANDLINE_DEVICE_CON_ARG_DESC, device_con, COMMANDLINE_DEVICE_CON_MAX_ARG, COMMANDLINE_DEVICE_CON_MIN_ARG);
prepend(cmd_list, device_con_cmd);
#endif
+
+ //hidden command for testing suspended mode
+#ifdef MAKE_DEBUG
+ COMMAND* send_packet_cmd = NULL;
+ create_command(&send_packet_cmd, "send-packet", NULL,
+ 0, NULL, get_state_serialno, 0, 0);
+ prepend(cmd_list, send_packet_cmd);
+
+ COMMAND* transport_close_cmd = NULL;
+ create_command(&transport_close_cmd, "transport-close", NULL,
+ 0, NULL, get_state_serialno, 0, 0);
+ prepend(cmd_list, transport_close_cmd);
+#endif
+
+
+
COMMAND* disconnect_cmd = NULL;
create_command(&disconnect_cmd, COMMANDLINE_DISCONNECT_NAME, COMMANDLINE_DISCONNECT_DESC,
COMMANDLINE_DISCONNECT_DESC_SIZE, COMMANDLINE_DISCONNECT_ARG_DESC, __disconnect, COMMANDLINE_DISCONNECT_MAX_ARG, COMMANDLINE_DISCONNECT_MIN_ARG);
diff --git a/src/common_modules.h b/src/common_modules.h
index 3fa5e02..1f2ed05 100644
--- a/src/common_modules.h
+++ b/src/common_modules.h
@@ -33,6 +33,7 @@
#define MAX_PAYLOAD 4096
#define CHUNK_SIZE (64*1024)
+#define DEFAULT_SDB_QEMU_PORT 26097
#define DEFAULT_SDB_PORT 26099
#define A_VERSION 0x0100000
@@ -69,6 +70,7 @@ typedef enum transport_type {
kTransportUsb,
kTransportLocal,
kTransportAny,
+ kTransportConnect,
kTransportRemoteDevCon
} transport_type;
@@ -85,12 +87,16 @@ struct transport
void (*kick)(TRANSPORT *t);
int connection_state;
+
+ //for checking emulator suspended mode
+ int suspended;
transport_type type;
usb_handle *usb;
int sfd;
char *serial;
+ char host[20];
int sdb_port;
char *device_name;
@@ -99,6 +105,12 @@ struct transport
unsigned res;
};
+typedef enum listener_type {
+ serverListener,
+ qemuListener,
+ forwardListener
+} LISTENER_TYPE;
+
typedef struct listener LISTENER;
struct listener
{
@@ -107,9 +119,10 @@ struct listener
FD_EVENT fde;
int fd;
- const char *local_name;
- const char *connect_to;
+ int local_port;
+ int connect_port;
TRANSPORT *transport;
+ LISTENER_TYPE type;
};
typedef struct t_packet T_PACKET;
@@ -142,5 +155,6 @@ struct socket {
int readx(int fd, void *ptr, size_t len);
int writex(int fd, const void *ptr, size_t len);
+int notify_qemu(char* host, int port, char* serial);
#endif /* SDB_TYPES_H_ */
diff --git a/src/listener.c b/src/listener.c
index c6ce208..0ab08b5 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -37,64 +37,58 @@
LIST_NODE* listener_list = NULL;
static void listener_event_func(int _fd, unsigned ev, void *_l);
-static LISTENER* find_listener(const char *local_name);
+static LISTENER* find_listener(int local_port);
void free_listener(void* data)
{
LISTENER* listener = data;
fdevent_remove(&(listener->fde));
- free((void*)listener->local_name);
- free((void*)listener->connect_to);
free(listener);
}
-int install_listener(const char *local_name, const char *connect_to, TRANSPORT* transport)
+int install_listener(int local_port, int connect_port, TRANSPORT* transport, LISTENER_TYPE ltype)
{
- D("LN(%s)\n", local_name);
+ D("LN(%d)\n", local_port);
- LISTENER* listener = find_listener(local_name);
+ LISTENER* listener = find_listener(local_port);
if(listener != NULL) {
- char *cto;
-
- /* can't repurpose a smartsocket */
- if(listener->connect_to[0] == '*') {
- return -1;
- }
-
- cto = strdup(connect_to);
- if(cto == 0) {
+ if(listener->type != forwardListener) {
+ LOG_ERROR("can not repurpose if it is not forward listener");
return -1;
}
- //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
- free((void*) listener->connect_to);
- listener->connect_to = cto;
- if (listener->transport != transport) {
- listener->transport = transport;
- }
+ listener->type = ltype;
+ listener->connect_port = connect_port;
+ listener->transport = transport;
return 0;
}
- if(strncmp("tcp:", local_name, 4)){
- LOG_FATAL("LN(%s) unknown local portname\n", local_name);
- return -2;
- }
-
- int port = atoi(local_name + 4);
-
//TODO REMOTE_DEVICE_CONNECT block remote connect until security issue is cleard
// int fd = sdb_port_listen(INADDR_ANY, port, SOCK_STREAM);
- int fd = sdb_port_listen(INADDR_LOOPBACK, port, SOCK_STREAM);
+
+ int fd = -1;
+ if(ltype == qemuListener) {
+ fd = sdb_port_listen(INADDR_ANY, local_port, SOCK_STREAM);
+ }
+ else {
+ fd = sdb_port_listen(INADDR_LOOPBACK, local_port, SOCK_STREAM);
+ }
if(fd < 0) {
- LOG_ERROR("LN(%s) cannot bind\n", local_name);
+ if(ltype == serverListener) {
+ LOG_FATAL("server LN(%d) cannot bind \n", local_port);
+ }
+ else {
+ LOG_ERROR("LN(%d) cannot bind \n", local_port);
+ }
return -2;
}
listener = calloc(1, sizeof(LISTENER));
- listener->local_name = strdup(local_name);
- listener->connect_to = strdup(connect_to);
+ listener->type = ltype;
+ listener->local_port = local_port;
+ listener->connect_port = connect_port;
listener->fd = fd;
listener->node = prepend(&listener_list, listener);
listener->transport = transport;
@@ -104,77 +98,75 @@ int install_listener(const char *local_name, const char *connect_to, TRANSPORT*
return 0;
}
-int remove_listener(const char *local_name, const char *connect_to, TRANSPORT* transport)
+int remove_listener(int local_port, int connect_port, TRANSPORT* transport)
{
- D("LN(%s)\n", local_name);
- LISTENER* listener = find_listener(local_name);
+ LOG_INFO("LN(%d)\n", local_port);
+ LISTENER* listener = find_listener(local_port);
if(listener != NULL &&
- !strcmp(connect_to, listener->connect_to) &&
+ connect_port == listener->connect_port &&
listener->transport != NULL &&
listener->transport == transport) {
remove_node(&listener_list, listener->node, free_listener);
- D("LN(%s) removed\n", local_name);
+ LOG_INFO("LN(%d) removed\n", local_port);
return 0;
}
- D("LN(%s) could not find\n", local_name);
+ LOG_ERROR("LN(%d) could not find\n", local_port);
return -1;
}
static void listener_event_func(int _fd, unsigned ev, void *_l)
{
LISTENER *l = _l;
- D("LN(%s)\n", l->local_name);
+ LOG_INFO("LN(%d)\n", l->local_port);
if(ev & FDE_READ) {
int fd = sdb_socket_accept(_fd);
if(fd < 0) {
- D("LN(%s) fail to create\n", l->local_name);
+ LOG_ERROR("LN(%d) fail to create socket\n", l->local_port);
return;
}
SDB_SOCKET *s = create_local_socket(fd);
- int ss = 0;
- if(!strcmp(l->connect_to, "*smartsocket*")) {
- ss = 1;
+ if(l->type == serverListener) {
+ sdb_socket_setbufsize(fd, CHUNK_SIZE);
+ local_socket_ready(s);
}
-
- if(ss) {
+ else if(l->type == qemuListener) {
sdb_socket_setbufsize(fd, CHUNK_SIZE);
+ SET_SOCKET_STATUS(s, QEMU_SOCKET);
+ local_socket_ready(s);
}
- if(s) {
-
- if(ss) {
- local_socket_ready(s);
+ else {
+
+//TODO REMOTE_DEVICE_CONNECT
+#if 0
+ if(l->transport->type == kTransportRemoteDevCon) {
+ if(assign_remote_connect_socket_rid(s)) {
+ local_socket_close(s);
+ return;
+ }
}
- else {
+#endif
- if(l->transport->type == kTransportRemoteDevCon) {
- if(assign_remote_connect_socket_rid(s)) {
- local_socket_close(s);
- return;
- }
- }
+ s->transport = l->transport;
+ char connect_to[50];
+ snprintf(connect_to, sizeof connect_to, "tcp:%d", l->connect_port);
- s->transport = l->transport;
- connect_to_remote(s, l->connect_to);
- }
- return;
+ connect_to_remote(s, connect_to);
}
-
- sdb_close(fd);
}
}
-static LISTENER* find_listener(const char *local_name) {
+static LISTENER* find_listener(int local_port) {
LIST_NODE* currentptr = listener_list;
while(currentptr != NULL) {
LISTENER* l = currentptr->data;
currentptr = currentptr->next_ptr;
- if(!strcmp(local_name, l->local_name)) {
+ if(local_port == l->local_port) {
return l;
}
}
diff --git a/src/listener.h b/src/listener.h
index b2850cc..ee59810 100644
--- a/src/listener.h
+++ b/src/listener.h
@@ -30,8 +30,8 @@
#include "common_modules.h"
extern LIST_NODE* listener_list;
-int remove_listener(const char *local_name, const char *connect_to, TRANSPORT* transport);
-int install_listener(const char *local_name, const char *connect_to, TRANSPORT* transport);
+int remove_listener(int local_port, int connect_port, TRANSPORT* transport);
+int install_listener(int local_port, int connect_port, TRANSPORT* transport, LISTENER_TYPE ltype);
void free_listener(void* data);
#endif /* LISTENER_H_ */
diff --git a/src/sdb.c b/src/sdb.c
index e17c34f..bb7a08e 100755
--- a/src/sdb.c
+++ b/src/sdb.c
@@ -109,15 +109,6 @@ static void init_map() {
#endif
}
-/* Constructs a local name of form tcp:port.
- * target_str points to the target string, it's content will be overwritten.
- * target_size is the capacity of the target string.
- * server_port is the port number to use for the local name.
- */
-void build_local_name(char* target_str, size_t target_size, int server_port)
-{
- snprintf(target_str, target_size, "tcp:%d", server_port);
-}
int sdb_main(int is_daemon, int server_port)
{
@@ -130,17 +121,19 @@ int sdb_main(int is_daemon, int server_port)
init_wakeup_select_func();
- sdb_usb_init();
- local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
-
- char local_name[30];
- build_local_name(local_name, sizeof(local_name), server_port);
- if(install_listener(local_name, "*smartsocket*", NULL)) {
+ if(install_listener(server_port, 0, NULL, serverListener)) {
_exit(1);
}
if (is_daemon) {
start_logging();
}
+
+ //install listener for getting emulator information from qemu
+ install_listener(DEFAULT_SDB_QEMU_PORT, 0, NULL, qemuListener);
+
+ sdb_usb_init();
+ local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
+
LOG_INFO("Event loop starting\n");
FDEVENT_LOOP();
diff --git a/src/sdb_constants.c b/src/sdb_constants.c
index 57a9e63..0f88bd7 100644
--- a/src/sdb_constants.c
+++ b/src/sdb_constants.c
@@ -269,9 +269,17 @@
const char* STATE_NOPERM = "no permissions";
const char* STATE_LOCKED = "locked";
const char* STATE_UNKNOWN = "unknown";
+ const char* STATE_SUSPENDED = "suspended";
const char* TRANSPORT_ERR_MORE_THAN_ONE_TARGET = "more than one target";
const char* TRANSPORT_ERR_MORE_THAN_ONE_EMUL = "more than one emulator";
+ const char* TRANSPORT_ERR_MORE_THAN_ONE_CONNECT = "more than one connected emulator";
const char* TRANSPORT_ERR_MORE_THAN_ONE_DEV = "more than one device";
const char* TRANSPORT_ERR_TARGET_OFFLINE = "target offline";
+ const char* TRANSPORT_ERR_TARGET_SUSPENDED = "emulator is in suspended mode";
const char* TRANSPORT_ERR_TARGET_NOT_FOUND = "target not found";
+
+ const char* FORWARD_ERR_UNKNOWN_LOCAL_PORT = "wrong local port format";
+ const char* FORWARD_ERR_UNKNOWN_REMOTE_PORT = "wrong remote port format";
+ const char* FORWARD_ERR_INSTALL_FAIL = "cannot install listener";
+ const char* FORWARD_ERR_REMOVE_FAIL = "cannot remove listener";
diff --git a/src/sdb_constants.h b/src/sdb_constants.h
index d0dda55..030a87e 100644
--- a/src/sdb_constants.h
+++ b/src/sdb_constants.h
@@ -227,11 +227,18 @@ typedef enum host_type HOST_TYPE;
extern const char* STATE_NOPERM;
extern const char* STATE_LOCKED;
extern const char* STATE_UNKNOWN;
+ extern const char* STATE_SUSPENDED;
extern const char* TRANSPORT_ERR_MORE_THAN_ONE_TARGET;
extern const char* TRANSPORT_ERR_MORE_THAN_ONE_EMUL;
extern const char* TRANSPORT_ERR_MORE_THAN_ONE_DEV;
extern const char* TRANSPORT_ERR_TARGET_OFFLINE;
+ extern const char* TRANSPORT_ERR_TARGET_SUSPENDED;
extern const char* TRANSPORT_ERR_TARGET_NOT_FOUND;
+ extern const char* FORWARD_ERR_UNKNOWN_LOCAL_PORT;
+ extern const char* FORWARD_ERR_UNKNOWN_REMOTE_PORT;
+ extern const char* FORWARD_ERR_INSTALL_FAIL;
+ extern const char* FORWARD_ERR_REMOVE_FAIL;
+
#endif /* SDB_CONSTANTS_H_*/
diff --git a/src/sockets.c b/src/sockets.c
index 7d85837..1ef12c3 100755
--- a/src/sockets.c
+++ b/src/sockets.c
@@ -33,6 +33,8 @@
#define TRACE_TAG TRACE_SOCKETS
+static int qemu_socket_enqueue(SDB_SOCKET *s, PACKET *p);
+static int smart_socket_check(SDB_SOCKET *s, PACKET **p);
static int smart_socket_enqueue(SDB_SOCKET *s, PACKET *p);
static int local_enqueue(int fd, PACKET* p, SDB_SOCKET* s, int event_func);
static int peer_enqueue(SDB_SOCKET* socket, PACKET* p);
@@ -353,6 +355,10 @@ static int peer_enqueue(SDB_SOCKET* socket, PACKET* p) {
return -1;
}
+ if(HAS_SOCKET_STATUS(socket, QEMU_SOCKET)) {
+ return qemu_socket_enqueue(socket, p);
+ }
+
//packet can be queued, so do not free it here.
return smart_socket_enqueue(socket, p);
}
@@ -400,7 +406,7 @@ static void local_socket_event_func(int fd, unsigned ev, void *_s)
{
SDB_SOCKET *s = _s;
- D("LS(%X) FD(%d)\n", s->local_id, s->fd);
+ LOG_INFO("LS(%X) FD(%d)\n", s->local_id, s->fd);
/* put the FDE_WRITE processing before the FDE_READ
** in order to simplify the code.
@@ -523,7 +529,7 @@ void create_remote_connection_socket(SDB_SOCKET* socket) {
socket->read_packet->len = 0;
}
-void connect_to_remote(SDB_SOCKET *s, const char *destination)
+void connect_to_remote(SDB_SOCKET *s, const char* destination)
{
D("LS(%X)\n", s->local_id);
PACKET *p = get_apacket();
@@ -623,6 +629,7 @@ static int parse_host_service(char* host_str, char** service_ptr, TRANSPORT** t,
static int handle_request_with_t(SDB_SOCKET* socket, char* service, TRANSPORT* t, char* err_str) {
int forward = 0;
+
if(!strncmp(service,"forward:",8)) {
forward = 8;
}
@@ -652,22 +659,32 @@ static int handle_request_with_t(SDB_SOCKET* socket, char* service, TRANSPORT* t
}
*remote++ = 0;
+ if(strncmp("tcp:", local, 4)){
+ forward_err = (char*)FORWARD_ERR_UNKNOWN_LOCAL_PORT;
+ goto sendfail;
+ }
+
+ if(strncmp("tcp:", remote, 4)){
+ forward_err = (char*)FORWARD_ERR_UNKNOWN_REMOTE_PORT;
+ goto sendfail;
+ }
+
if (forward == 8) {
- if(!install_listener(local, remote, t)) {
+ if(!install_listener(atoi(local + 4), atoi(remote + 4), t, forwardListener)) {
writex(socket->fd, "OKAYOKAY", 8);
return 0;
}
else {
- LOG_INFO("LS(%X) T(%s) fail to install listener\n", socket->fd, t->serial);
- forward_err = "cannot install listener";
+ forward_err = (char*)FORWARD_ERR_INSTALL_FAIL;
+ goto sendfail;
}
} else {
- if(!remove_listener(local, remote, t)) {
+ if(!remove_listener(atoi(local + 4), atoi(remote + 4), t)) {
writex(socket->fd, "OKAYOKAY", 8);
return 0;
} else {
- LOG_INFO("LS(%X) T(%s) fail to remove listener\n", socket->fd, t->serial);
- forward_err = "cannot remove listener";
+ forward_err = (char*)FORWARD_ERR_REMOVE_FAIL;
+ goto sendfail;
}
}
sendfail:
@@ -688,6 +705,23 @@ sendfail:
sendokmsg(socket->fd, state);
return 0;
}
+#ifdef MAKE_DEBUG
+ else if(!strncmp(service, "send-packet", strlen("send-packet"))) {
+ char data[MAX_PAYLOAD] = {'1', };
+ send_cmd(0, 0, 0x00000000, data, t);
+ sendokmsg(socket->fd, "send_packet OK!");
+ return 0;
+ }
+ else if(!strncmp(service, "transport-close", strlen("transport-close"))) {
+ if(!sdb_close(t->sfd)) {
+ sendokmsg(socket->fd, "transport sfd closed!");
+ }
+ else {
+ sendfailmsg(socket->fd, "fail to close sfd!");
+ }
+ return 0;
+ }
+#endif
//TODO REMOTE_DEVICE_CONNECT block this code until security issue is cleared
#if 0
@@ -761,7 +795,7 @@ static void unregister_all_tcp_transports()
while(curptr != NULL) {
TRANSPORT* t = curptr->data;
curptr = curptr->next_ptr;
- if (t->type == kTransportLocal && t->sdb_port == 0) {
+ if (t->type == kTransportConnect) {
//just kick the transport. transport is destroied by transport thread.
if(!t->kicked) {
t->kicked = 1;
@@ -956,73 +990,162 @@ success:
return 0;
}
- if(!strcmp(service, "kill")) {
- LOG_INFO("sdb is being killed\n");
- sdb_cleanup();
- sdb_write(socket->fd, "OKAY", 4);
- exit(0);
- }
+ if(!strcmp(service, "kill")) {
+ LOG_INFO("sdb is being killed\n");
+ sdb_cleanup();
+ sdb_write(socket->fd, "OKAY", 4);
+ exit(0);
+ }
return -1;
}
-static int smart_socket_enqueue(SDB_SOCKET *s, PACKET *p)
-{
+static int smart_socket_check(SDB_SOCKET *s, PACKET **p) {
unsigned len;
- D("LS(%X)\n", s->local_id);
-
if(s->pkt_list == NULL) {
- prepend(&s->pkt_list, p);
+ prepend(&s->pkt_list, *p);
}
else {
PACKET* socket_packet = s->pkt_list->data;
- if((socket_packet->len + p->len) > MAX_PAYLOAD) {
- D("SS(%d): overflow\n", s->local_id);
- put_apacket(p);
- goto fail;
+ if((socket_packet->len + (*p)->len) > MAX_PAYLOAD) {
+ LOG_ERROR("LS(%x): overflow\n", s->local_id);
+ put_apacket(*p);
+ return -1;
}
memcpy(socket_packet->data + socket_packet->len,
- p->data, p->len);
- socket_packet->len += p->len;
- put_apacket(p);
+ (*p)->data, (*p)->len);
+ socket_packet->len += (*p)->len;
+ put_apacket(*p);
- p = socket_packet;
+ *p = socket_packet;
}
/* don't bother if we can't decode the length */
- if(p->len < 4) return 0;
+ if((*p)->len < 4) {
+ LOG_INFO("LS(%X): waiting for more bytes for getting the packet length\n", s->local_id);
+ return 1;
+ }
- len = unhex(p->data, 4);
+ len = unhex((*p)->data, 4);
if((len < 1) || (len > 1024)) {
- D("LS(%X): bad size (%d)\n", s->local_id, len);
- goto fail;
+ LOG_ERROR("LS(%X): bad size (%d)\n", s->local_id, len);
+ return -1;
}
/* can't do anything until we have the full header */
- if((len + 4) > p->len) {
- D("LS(%X): waiting for %d more bytes in smart socket\n", s->local_id, len+4 - p->len);
- return 0;
+ if((len + 4) > (*p)->len) {
+ LOG_INFO("LS(%X): waiting for %d more bytes in smart socket\n", s->local_id, len+4 - (*p)->len);
+ return 1;
+ }
+
+ (*p)->data[len + 4] = 0;
+ LOG_INFO("LS(%X) %s\n", s->local_id, (*p)->data + 4);
+ return 0;
+}
+
+static int qemu_socket_enqueue(SDB_SOCKET *s, PACKET *p)
+{
+ LOG_INFO("LS(%X) data %s\n", s->local_id, p->data);
+
+ //TODO sync command is not fully implemented.
+ int result = smart_socket_check(s, &p);
+
+ if(result == -1) {
+ goto fail;
+ }
+
+ if(result == 1) {
+ return result;
+ }
+
+ //TODO sync command is not fully implemented.
+ char* host_str = (char *)p->data + 4;
+
+ if(strncmp(host_str, "host:", strlen("host:"))) {
+ LOG_ERROR("unknown qemu protocol '%s'\n", host_str);
+ goto fail;
+ }
+
+ host_str = host_str + 5;
+
+ LOG_INFO("qemu request: '%s'\n", host_str);
+ if(!strncmp(host_str, "sync:", strlen("sync:"))) {
+ host_str += strlen("sync:");
+ char* suspend = strchr(host_str, ':');
+ if(suspend == NULL) {
+ LOG_ERROR("sync: does not contain suspended status!\n");
+ goto fail;
+ }
+ *(suspend++) = '\0';
+
+ TRANSPORT* t = acquire_one_transport(kTransportAny, host_str, NULL);
+
+ if(t == NULL) {
+ LOG_ERROR("sync: error. No Such serial name '%s'\n", host_str);
+ goto fail;
+ }
+
+ if(*suspend == '0') {
+ LOG_INFO("T(%s) exits suspended mode\n", t->serial);
+ if(t->suspended != 0) {
+ t->suspended = 0;
+ update_transports();
+ }
+ }
+ else if(*suspend == '1') {
+ LOG_INFO("T(%s) enters suspended mode\n", t->serial);
+ if(t->suspended != 1) {
+ t->suspended = 1;
+ run_transport_close(t);
+ update_transports();
+ }
+ }
+ else {
+ LOG_ERROR("sync: contains wrong suspended status '%c'!\n", suspend);
+ goto fail;
+ }
}
- p->data[len + 4] = 0;
- D("LS(%X) %s\n", s->local_id, p->data + 4);
+ fail:
+ free_list(s->pkt_list, put_apacket);
+ s->pkt_list = NULL;
+ local_socket_close(s);
+ return -1;
+}
+
+static int smart_socket_enqueue(SDB_SOCKET *s, PACKET *p)
+{
+ LOG_INFO("LS(%X)\n", s->local_id);
+ int result = smart_socket_check(s, &p);
+
+ if(result == -1) {
+ goto fail;
+ }
+
+ if(result == 1) {
+ return result;
+ }
char* host_str = (char *)p->data + 4;
char *service = NULL;
char* err_str = NULL;
TRANSPORT* t = NULL;
-
if(parse_host_service(host_str, &service, &t, &err_str) == 1) {
- if (t && t->connection_state != CS_OFFLINE) {
+ if (t && t->connection_state != CS_OFFLINE && t->suspended == 0) {
s->transport = t;
sdb_write(s->fd, "OKAY", 4);
D("LS(%X) get transport T(%s)", s->local_id, t->serial);
} else {
if(t != NULL) {
- err_str = (char*)TRANSPORT_ERR_TARGET_OFFLINE;
+ if(t->suspended) {
+ err_str =(char*)TRANSPORT_ERR_TARGET_SUSPENDED;
+ }
+ else {
+ err_str = (char*)TRANSPORT_ERR_TARGET_OFFLINE;
+ }
}
LOG_ERROR("LS(%X) get no transport", s->local_id);
sendfailmsg(s->fd, err_str);
@@ -1030,7 +1153,6 @@ static int smart_socket_enqueue(SDB_SOCKET *s, PACKET *p)
p->len = 0;
return 0;
}
-
if (service) {
if(handle_request_with_t(s, service, t, err_str) == 0) {
D( "LS(%X): handled host service with '%s'\n", s->local_id, service );
@@ -1063,7 +1185,6 @@ static int smart_socket_enqueue(SDB_SOCKET *s, PACKET *p)
goto fail;
}
}
-
if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
sendfailmsg(s->fd, "device offline (x)");
goto fail;
@@ -1074,6 +1195,8 @@ static int smart_socket_enqueue(SDB_SOCKET *s, PACKET *p)
goto fail;
}
+ //TODO REMOTE_DEVICE_CONNECT
+#if 0
if(s->transport->type == kTransportRemoteDevCon) {
if(assign_remote_connect_socket_rid(s)) {
sendfailmsg(s->fd, "remote connect socket exceeds limit. cannot create remote socket\n");
@@ -1081,8 +1204,10 @@ static int smart_socket_enqueue(SDB_SOCKET *s, PACKET *p)
return -1;
}
}
+#endif
SET_SOCKET_STATUS(s, NOTIFY);
+
connect_to_remote(s, (char*) (p->data + 4));
free_list(s->pkt_list, put_apacket);
s->pkt_list = NULL;
@@ -1093,10 +1218,10 @@ fail:
free_list(s->pkt_list, put_apacket);
s->pkt_list = NULL;
- if(!HAS_SOCKET_STATUS(s, REMOTE_CON)) {
- //do not close socket if it is remote connected socket
+#if 0 //REMOTE_DEVICE_CONNECT
+ if(!HAS_SOCKET_STATUS(s, REMOTE_CON))
+#endif
local_socket_close(s);
- }
return -1;
}
@@ -1147,6 +1272,34 @@ device_tracker_send( SDB_SOCKET* local_socket,
return local_socket_enqueue( local_socket, p );
}
+int notify_qemu(char* host, int port, char* serial) {
+ int fd = -1;
+ int qemu_port = port + 2;
+
+ fd = sdb_host_connect(host, qemu_port, SOCK_DGRAM);
+
+ if (fd < 0) {
+ LOG_ERROR("failed to create socket to localhost(%d)\n", qemu_port);
+ return -1;
+ }
+
+ char request[255];
+ snprintf(request, sizeof request, "5\n%s\n", serial);
+
+ // send to sensord with udp
+
+ LOG_INFO("notify qemu: %s\n", request);
+
+ if (sdb_write(fd, request, strlen(request)) < 0) {
+ LOG_ERROR("could not send sensord request\n");
+ sdb_close(fd);
+ return -1;
+ }
+
+ sdb_close(fd);
+ return 0;
+}
+
static void connect_emulator(char* host, int port, char* buf, int buf_len) {
if(port < 0) {
port = DEFAULT_SDB_LOCAL_TRANSPORT_PORT;
@@ -1170,6 +1323,10 @@ static void connect_emulator(char* host, int port, char* buf, int buf_len) {
return;
}
- register_socket_transport(fd, serial, port, 0, NULL);
+ if(notify_qemu(host, port, serial)) {
+ return;
+ }
+ register_socket_transport(fd, serial, host, port, kTransportConnect, NULL);
+
snprintf(buf, buf_len, "connected to %s", serial);
}
diff --git a/src/sockets.h b/src/sockets.h
index 51fe875..363e617 100644
--- a/src/sockets.h
+++ b/src/sockets.h
@@ -46,7 +46,8 @@ typedef enum {
NOTIFY = 0,
DEVICE_TRACKER,
REMOTE_SOCKET,
- REMOTE_CON
+ REMOTE_CON,
+ QEMU_SOCKET
} SOCKET_STATUS;
extern LIST_NODE* local_socket_list;
@@ -56,7 +57,7 @@ int local_socket_enqueue(SDB_SOCKET *s, PACKET *p);
void local_socket_ready(SDB_SOCKET *s);
void local_socket_close(SDB_SOCKET *s);
SDB_SOCKET *create_local_socket(int fd);
-void connect_to_remote(SDB_SOCKET *s, const char *destination);
+void connect_to_remote(SDB_SOCKET *s, const char* destination);
int assign_remote_connect_socket_rid (SDB_SOCKET* s);
int device_tracker_send( SDB_SOCKET* local_socket, const char* buffer, int len );
#endif /* SOCKETS_H_ */
diff --git a/src/transport.c b/src/transport.c
index 309291a..8c444ae 100755
--- a/src/transport.c
+++ b/src/transport.c
@@ -35,8 +35,6 @@ static void transport_unref(TRANSPORT *t);
static void handle_packet(PACKET *p, TRANSPORT *t);
static void parse_banner(char *banner, TRANSPORT *t);
static void wakeup_select(T_PACKET* t_packet);
-static void update_transports(void);
-static void run_transport_close(TRANSPORT* t);
static void encoding_packet(PACKET* p);
static int check_header(PACKET *p);
static int check_data(PACKET *p);
@@ -127,7 +125,7 @@ kick_transport(TRANSPORT* t)
}
}
-static void run_transport_close(TRANSPORT* t)
+void run_transport_close(TRANSPORT* t)
{
D("T(%s)\n", t->serial);
LIST_NODE* curptr = listener_list;
@@ -137,7 +135,7 @@ static void run_transport_close(TRANSPORT* t)
curptr = curptr->next_ptr;
if(l->transport == t) {
- D("LN(%s) being closed by T(%s)\n", l->local_name, t->serial);
+ D("LN(%d) being closed by T(%s)\n", l->local_port, t->serial);
remove_node(&listener_list, l->node, free_listener);
}
}
@@ -323,7 +321,7 @@ int list_transports_msg(char* buffer, size_t bufferlen)
return len;
}
-static void update_transports(void)
+void update_transports(void)
{
D("update transports\n");
char buffer[1024];
@@ -361,6 +359,7 @@ static void *transport_thread(void *_t)
{
TRANSPORT *t = _t;
PACKET *p;
+read_loop:
D("T(%s), FD(%d)\n", t->serial, t->sfd);
t->connection_state = CS_WAITCNXN;
@@ -368,7 +367,6 @@ static void *transport_thread(void *_t)
t->connection_state = CS_OFFLINE;
// allow the device some time to respond to the connect message
sdb_sleep_ms(1000);
-
D("%s: data dump started\n", t->serial);
while(1) {
p = get_apacket();
@@ -396,6 +394,32 @@ static void *transport_thread(void *_t)
LOG_INFO("T(%s) remote read fail. terminate transport\n", t->serial);
put_apacket(p);
+ if(t->suspended == 1) {
+ LOG_INFO("T(%s) connection is closed in suspended mode\n");
+ sdb_close(t->sfd);
+ while(1) {
+
+ t->sfd = sdb_host_connect(t->host, t->sdb_port, SOCK_STREAM);
+
+ if( t->sfd < 0) {
+ LOG_INFO("T(%s) dies during suspended mode\n");
+ break;
+ }
+
+ close_on_exec(t->sfd);
+ disable_tcp_nagle(t->sfd);
+
+ if(t->suspended == 0) {
+ LOG_INFO("T(%s) exits suspended mode\n");
+ goto read_loop;
+ }
+ sdb_close(t->sfd);
+ LOG_INFO("T(%s) still in suspended mode, sleep 2 sec\n");
+ sdb_sleep_ms(2000);
+ }
+ }
+
+
t->connection_state = CS_OFFLINE;
do {
if(t->req == t->res) {
@@ -520,7 +544,8 @@ TRANSPORT *acquire_one_transport(transport_type ttype, const char* serial, char*
}
result = transport_;
}
- if (ttype == transport_->type) {
+ else if (ttype == transport_->type ||
+ (ttype == kTransportLocal && transport_->type == kTransportConnect)) {
if (result) {
if(ttype == kTransportUsb) {
*error_out = (char*)TRANSPORT_ERR_MORE_THAN_ONE_DEV;
@@ -832,6 +857,10 @@ endup:
const char *connection_state_name(TRANSPORT *t)
{
if(t != NULL) {
+ if(t->suspended) {
+ return STATE_SUSPENDED;
+ }
+
int state = t->connection_state;
if(state == CS_OFFLINE) {
diff --git a/src/transport.h b/src/transport.h
index d7c18af..eaebeb8 100755
--- a/src/transport.h
+++ b/src/transport.h
@@ -57,7 +57,7 @@ void send_packet(PACKET *p, TRANSPORT *t);
const char *connection_state_name(TRANSPORT *t);
PACKET *get_apacket(void);
void put_apacket(void *p);
-void register_socket_transport(int s, const char *serial, int port, int local, const char *device_name);
+void register_socket_transport(int s, const char *serial, char* host, int port, transport_type ttype, const char *device_name);
void register_usb_transport(usb_handle *usb, const char *serial);
int register_device_con_transport(int s, const char *serial);
void send_cmd(unsigned arg0, unsigned arg1, unsigned cmd, char* data, TRANSPORT* t);
@@ -68,4 +68,6 @@ int local_connect(int port, const char *device_name);
TRANSPORT *acquire_one_transport(transport_type ttype, const char* serial, char **error_out);
void kick_transport( TRANSPORT* t );
void register_transport(TRANSPORT *t);
+void run_transport_close(TRANSPORT* t);
+void update_transports(void);
#endif /* __TRANSPORT_H */
diff --git a/src/transport_local.c b/src/transport_local.c
index a58542a..61ddc28 100755
--- a/src/transport_local.c
+++ b/src/transport_local.c
@@ -92,7 +92,8 @@ int local_connect(int sdb_port, const char *device_name) {
}
#endif
- int fd = sdb_host_connect("127.0.0.1", sdb_port, SOCK_STREAM);
+ char* host = "127.0.0.1";
+ int fd = sdb_host_connect(host, sdb_port, SOCK_STREAM);
if (fd >= 0) {
D("connected on remote on fd '%d', port '%d'\n", fd, sdb_port);
@@ -101,7 +102,12 @@ int local_connect(int sdb_port, const char *device_name) {
snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, sdb_port);
- register_socket_transport(fd, buf, sdb_port, 1, device_name);
+
+ if(notify_qemu(host, sdb_port, buf)) {
+ return -1;
+ }
+
+ register_socket_transport(fd, buf, host, sdb_port, kTransportLocal, device_name);
// noti to sensord port to enable shell context menu on
notify_sensord(sdb_port);
@@ -205,22 +211,7 @@ static void remote_close(TRANSPORT *t)
D("close remote socket. T(%s), device name: '%s'\n", t->serial, t->device_name);
}
-static void init_socket_transport(TRANSPORT *t, int s, int sdb_port)
-{
- t->kick = remote_kick;
- t->close = remote_close;
- t->read_from_remote = remote_read;
- t->write_to_remote = remote_write;
- t->sfd = s;
- t->connection_state = CS_OFFLINE;
- t->type = kTransportLocal;
- t->node = NULL;
- t->req = 0;
- t->res = 0;
- t->sdb_port = sdb_port;
-}
-
-void register_socket_transport(int s, const char *serial, int port, int local, const char *device_name)
+void register_socket_transport(int s, const char *serial, char* host, int port, transport_type ttype, const char *device_name)
{
if(current_local_transports >= SDB_LOCAL_TRANSPORT_MAX) {
D("Too many emulators\n");
@@ -236,18 +227,32 @@ void register_socket_transport(int s, const char *serial, int port, int local, c
serial = buff;
}
D("transport: %s init'ing for socket %d, on port %d (%s)\n", serial, s, port, device_name);
- int _port = port;
- if(!local) {
- _port = 0;
- }
- init_socket_transport(t, s, _port);
TRANSPORT* old_t = acquire_one_transport(kTransportAny, serial, NULL);
if(old_t != NULL) {
D("old transport '%s' is found. Unregister it\n", old_t->serial);
kick_transport(old_t);
}
+ t->kick = remote_kick;
+ t->close = remote_close;
+ t->read_from_remote = remote_read;
+ t->write_to_remote = remote_write;
+ t->sfd = s;
+ t->connection_state = CS_OFFLINE;
+ t->node = NULL;
+ t->req = 0;
+ t->res = 0;
+ t->sdb_port = port;
+ t->suspended = 0;
+ t->type = ttype;
t->remote_cnxn_socket = NULL;
+
+ if(host) {
+ snprintf(t->host, 20, "%s", host);
+ }
+ else {
+ snprintf(t->host, 20, "%s", "127.0.0.1");
+ }
if(serial) {
t->serial = strdup(serial);
}
diff --git a/src/transport_usb.c b/src/transport_usb.c
index 270bddd..b364e87 100755
--- a/src/transport_usb.c
+++ b/src/transport_usb.c
@@ -25,7 +25,6 @@
#include "sdb_usb.h"
#include "transport.h"
-static void init_usb_transport(TRANSPORT *t, usb_handle *h, int state);
static int remote_read(TRANSPORT* t, void* data, int len)
{
@@ -61,21 +60,6 @@ static void remote_kick(TRANSPORT *t)
sdb_usb_kick(t->usb);
}
-static void init_usb_transport(TRANSPORT *t, usb_handle *h, int state)
-{
- D("transport: usb\n");
- t->close = remote_close;
- t->kick = remote_kick;
- t->read_from_remote = remote_read;
- t->write_to_remote = remote_write;
- t->connection_state = state;
- t->type = kTransportUsb;
- t->usb = h;
- t->sdb_port = -1;
- t->req = 0;
- t->res = 0;
-}
-
static int get_connected_device_count(transport_type type)
{
int cnt = 0;
@@ -102,7 +86,19 @@ void register_usb_transport(usb_handle *usb, const char *serial)
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
serial ? serial : "");
- init_usb_transport(t, usb, CS_OFFLINE);
+
+ t->close = remote_close;
+ t->kick = remote_kick;
+ t->read_from_remote = remote_read;
+ t->write_to_remote = remote_write;
+ t->connection_state = CS_OFFLINE;
+ t->type = kTransportUsb;
+ t->usb = usb;
+ t->sdb_port = -1;
+ t->req = 0;
+ t->res = 0;
+ t->suspended = 0;
+
if(serial) {
t->serial = strdup(serial);
}