diff --git a/src/devtools/adb_tcp/adb.c b/src/devtools/adb_tcp/adb.c
new file mode 100644
index 0000000..f418db1
--- /dev/null
+++ b/src/devtools/adb_tcp/adb.c
@@ -0,0 +1,1824 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define  TRACE_TAG   TRACE_ADB
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <grp.h> //For setgroups
+
+#include "sysdeps.h"
+#include "adb.h"
+#include "adb_auth.h"
+#include "transport_pcie.h"
+#include <log/log.h>
+#include <include/lynq_uci.h>
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+#if !ADB_HOST
+#include <cutils/properties.h>
+#include <private/android_filesystem_config.h>
+//#include <sys/capability.h>
+#include <sys/mount.h>
+#include <sys/prctl.h>
+#include <getopt.h>
+//#include <selinux/selinux.h>
+#endif
+
+#if ADB_TRACE
+ADB_MUTEX_DEFINE( D_lock );
+#endif
+
+int HOST = 0;
+int gListenAll = 0;
+
+static int auth_enabled = 0;
+
+#if !ADB_HOST
+static const char *adb_device_banner = "device";
+static const char *root_seclabel = NULL;
+#endif
+
+void fatal(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    fprintf(stderr, "error: ");
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    va_end(ap);
+    exit(-1);
+}
+
+void fatal_errno(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    fprintf(stderr, "error: %s: ", strerror(errno));
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    va_end(ap);
+    exit(-1);
+}
+
+int   adb_trace_mask;
+
+/* read a comma/space/colum/semi-column separated list of tags
+ * from the ADB_TRACE environment variable and build the trace
+ * mask from it. note that '1' and 'all' are special cases to
+ * enable all tracing
+ */
+void  adb_trace_init(void)
+{
+    const char*  p = getenv("ADB_TRACE");
+    const char*  q;
+
+    static const struct {
+        const char*  tag;
+        int           flag;
+    } tags[] = {
+        { "1", 0 },
+        { "all", 0 },
+        { "adb", TRACE_ADB },
+        { "sockets", TRACE_SOCKETS },
+        { "packets", TRACE_PACKETS },
+        { "rwx", TRACE_RWX },
+        { "usb", TRACE_USB },
+        { "sync", TRACE_SYNC },
+        { "sysdeps", TRACE_SYSDEPS },
+        { "transport", TRACE_TRANSPORT },
+        { "jdwp", TRACE_JDWP },
+        { "services", TRACE_SERVICES },
+        { "auth", TRACE_AUTH },
+        { NULL, 0 }
+    };
+
+    if (p == NULL)
+            return;
+
+    /* use a comma/column/semi-colum/space separated list */
+    while (*p) {
+        int  len, tagn;
+
+        q = strpbrk(p, " ,:;");
+        if (q == NULL) {
+            q = p + strlen(p);
+        }
+        len = q - p;
+
+        for (tagn = 0; tags[tagn].tag != NULL; tagn++)
+        {
+            int  taglen = strlen(tags[tagn].tag);
+
+            if (len == taglen && !memcmp(tags[tagn].tag, p, len) )
+            {
+                int  flag = tags[tagn].flag;
+                if (flag == 0) {
+                    adb_trace_mask = ~0;
+                    return;
+                }
+                adb_trace_mask |= (1 << flag);
+                break;
+            }
+        }
+        p = q;
+        if (*p)
+            p++;
+    }
+}
+
+#if !ADB_HOST && !ADB_NON_ANDROID
+/*
+ * Implements ADB tracing inside the emulator.
+ */
+
+#include <stdarg.h>
+
+/*
+ * Redefine open and write for qemu_pipe.h that contains inlined references
+ * to those routines. We will redifine them back after qemu_pipe.h inclusion.
+ */
+
+#undef open
+#undef write
+#define open    adb_open
+#define write   adb_write
+#include <hardware/qemu_pipe.h>
+#undef open
+#undef write
+#define open    ___xxx_open
+#define write   ___xxx_write
+
+/* A handle to adb-debug qemud service in the emulator. */
+int   adb_debug_qemu = -1;
+
+/* Initializes connection with the adb-debug qemud service in the emulator. */
+static int adb_qemu_trace_init(void)
+{
+    char con_name[32];
+
+    if (adb_debug_qemu >= 0) {
+        return 0;
+    }
+
+    /* adb debugging QEMUD service connection request. */
+    snprintf(con_name, sizeof(con_name), "qemud:adb-debug");
+    adb_debug_qemu = qemu_pipe_open(con_name);
+    return (adb_debug_qemu >= 0) ? 0 : -1;
+}
+
+void adb_qemu_trace(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    char msg[1024];
+
+    if (adb_debug_qemu >= 0) {
+        vsnprintf(msg, sizeof(msg), fmt, args);
+        adb_write(adb_debug_qemu, msg, strlen(msg));
+    }
+}
+#endif  /* !ADB_HOST */
+
+apacket *get_apacket(void)
+{
+    apacket *p = malloc(sizeof(apacket));
+    if(p == 0) fatal("failed to allocate an apacket");
+    memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
+    return p;
+}
+
+void put_apacket(apacket *p)
+{
+    free(p);
+}
+
+void handle_online(atransport *t)
+{
+    D("adb: online\n");
+    t->online = 1;
+#if ADB_HOST && ADB_OVER_PCIE
+#endif
+}
+
+void handle_offline(atransport *t)
+{
+    D("adb: offline\n");
+    //Close the associated usb
+    t->online = 0;
+    run_transport_disconnects(t);
+}
+
+#if DEBUG_PACKETS
+#define DUMPMAX 32
+void print_packet(const char *label, apacket *p)
+{
+    char *tag;
+    char *x;
+    unsigned count;
+
+    switch(p->msg.command){
+    case A_SYNC: tag = "SYNC"; break;
+    case A_CNXN: tag = "CNXN" ; break;
+    case A_OPEN: tag = "OPEN"; break;
+    case A_OKAY: tag = "OKAY"; break;
+    case A_CLSE: tag = "CLSE"; break;
+    case A_WRTE: tag = "WRTE"; break;
+    case A_AUTH: tag = "AUTH"; break;
+    default: tag = "????"; break;
+    }
+
+    fprintf(stderr, "%s: %s %08x %08x %04x \"",
+            label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
+    count = p->msg.data_length;
+    x = (char*) p->data;
+    if(count > DUMPMAX) {
+        count = DUMPMAX;
+        tag = "\n";
+    } else {
+        tag = "\"\n";
+    }
+    while(count-- > 0){
+        if((*x >= ' ') && (*x < 127)) {
+            fputc(*x, stderr);
+        } else {
+            fputc('.', stderr);
+        }
+        x++;
+    }
+    fputs(tag, stderr);
+}
+#endif
+
+static void send_ready(unsigned local, unsigned remote, atransport *t)
+{
+    D("Calling send_ready \n");
+    apacket *p = get_apacket();
+    p->msg.command = A_OKAY;
+    p->msg.arg0 = local;
+    p->msg.arg1 = remote;
+    send_packet(p, t);
+}
+
+static void send_close(unsigned local, unsigned remote, atransport *t)
+{
+    D("Calling send_close \n");
+    apacket *p = get_apacket();
+    p->msg.command = A_CLSE;
+    p->msg.arg0 = local;
+    p->msg.arg1 = remote;
+    send_packet(p, t);
+}
+
+#if (!ADB_HOST && ADB_OVER_PCIE)
+static size_t fill_connect_data(atransport *t, char *buf, size_t bufsize)
+{
+    struct pcie_info *info;
+    size_t remaining = bufsize;
+    size_t len;
+
+    len = snprintf(buf, remaining, "%s::", adb_device_banner);
+    remaining -= len;
+    buf += len;
+
+    if (t->pcie && t->pcie->info) {
+	info = t->pcie->info;
+	D("device: 0x%x\n", info->device);
+	D("vendor: 0x%x\n", info->vendor);
+	D("class: 0x%x\n", info->class);
+
+	len = snprintf(buf, remaining, "device=%x;vendor=%x;class=%x;",
+		       info->device, info->vendor, info->class);
+	remaining -= len;
+	buf += len;
+    }
+
+    return bufsize - remaining + 1;
+}
+#else
+
+#if !ADB_HOST
+static const char *cnxn_props[] = {
+    "ro.product.name",
+    "ro.product.model",
+    "ro.product.device",
+};
+#endif
+
+static size_t fill_connect_data(char *buf, size_t bufsize)
+{
+#if ADB_HOST
+    return snprintf(buf, bufsize, "host::") + 1;
+#else
+    static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
+    int i;
+    size_t remaining = bufsize;
+    size_t len;
+
+    len = snprintf(buf, remaining, "%s::", adb_device_banner);
+    remaining -= len;
+    buf += len;
+    for (i = 0; i < num_cnxn_props; i++) {
+        char value[PROPERTY_VALUE_MAX];
+        property_get(cnxn_props[i], value, "");
+        len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
+        remaining -= len;
+        buf += len;
+    }
+
+    return bufsize - remaining + 1;
+#endif
+}
+#endif /* ADB_OVER_PCIE */
+
+#if !ADB_HOST
+static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
+    char header[5];
+    if (msglen > 0xffff)
+        msglen = 0xffff;
+    snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
+    writex(fd, header, 4);
+    writex(fd, msg, msglen);
+}
+#endif
+
+#if ADB_HOST
+static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
+    char header[9];
+    if (msglen > 0xffff)
+        msglen = 0xffff;
+    snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen);
+    writex(fd, header, 8);
+    writex(fd, msg, msglen);
+}
+#endif // ADB_HOST
+
+static void send_connect(atransport *t)
+{
+    D("Calling send_connect \n");
+    apacket *cp = get_apacket();
+    cp->msg.command = A_CNXN;
+    cp->msg.arg0 = A_VERSION;
+    cp->msg.arg1 = MAX_PAYLOAD;
+#if (!ADB_HOST && ADB_OVER_PCIE)
+    cp->msg.data_length = fill_connect_data(t, (char *)cp->data,
+                                            sizeof(cp->data));
+#else
+    cp->msg.data_length = fill_connect_data((char *)cp->data,
+                                            sizeof(cp->data));
+#endif
+    send_packet(cp, t);
+}
+
+void send_auth_request(atransport *t)
+{
+    D("Calling send_auth_request\n");
+    apacket *p;
+    int ret;
+
+    ret = adb_auth_generate_token(t->token, sizeof(t->token));
+    if (ret != sizeof(t->token)) {
+        D("Error generating token ret=%d\n", ret);
+        return;
+    }
+
+    p = get_apacket();
+    memcpy(p->data, t->token, ret);
+    p->msg.command = A_AUTH;
+    p->msg.arg0 = ADB_AUTH_TOKEN;
+    p->msg.data_length = ret;
+    send_packet(p, t);
+}
+
+static void send_auth_response(uint8_t *token, size_t token_size, atransport *t)
+{
+    D("Calling send_auth_response\n");
+    apacket *p = get_apacket();
+    int ret;
+
+    ret = adb_auth_sign(t->key, token, token_size, p->data);
+    if (!ret) {
+        D("Error signing the token\n");
+        put_apacket(p);
+        return;
+    }
+
+    p->msg.command = A_AUTH;
+    p->msg.arg0 = ADB_AUTH_SIGNATURE;
+    p->msg.data_length = ret;
+    send_packet(p, t);
+}
+
+static void send_auth_publickey(atransport *t)
+{
+    D("Calling send_auth_publickey\n");
+    apacket *p = get_apacket();
+    int ret;
+
+    ret = adb_auth_get_userkey(p->data, sizeof(p->data));
+    if (!ret) {
+        D("Failed to get user public key\n");
+        put_apacket(p);
+        return;
+    }
+
+    p->msg.command = A_AUTH;
+    p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
+    p->msg.data_length = ret;
+    send_packet(p, t);
+}
+
+void adb_auth_verified(atransport *t)
+{
+    handle_online(t);
+    send_connect(t);
+}
+
+#if ADB_HOST
+static char *connection_state_name(atransport *t)
+{
+    if (t == NULL) {
+        return "unknown";
+    }
+
+    switch(t->connection_state) {
+    case CS_BOOTLOADER:
+        return "bootloader";
+    case CS_DEVICE:
+        return "device";
+    case CS_RECOVERY:
+        return "recovery";
+    case CS_SIDELOAD:
+        return "sideload";
+    case CS_OFFLINE:
+        return "offline";
+    case CS_UNAUTHORIZED:
+        return "unauthorized";
+    default:
+        return "unknown";
+    }
+}
+#endif // ADB_HOST
+
+/* qual_overwrite is used to overwrite a qualifier string.  dst is a
+ * pointer to a char pointer.  It is assumed that if *dst is non-NULL, it
+ * was malloc'ed and needs to freed.  *dst will be set to a dup of src.
+ */
+static void qual_overwrite(char **dst, const char *src)
+{
+    if (!dst)
+        return;
+
+    free(*dst);
+    *dst = NULL;
+
+    if (!src || !*src)
+        return;
+
+    *dst = strdup(src);
+}
+
+void parse_banner(char *banner, atransport *t)
+{
+    static const char *prop_seps = ";";
+    static const char key_val_sep = '=';
+    char *cp;
+    char *type;
+
+    D("parse_banner: %s\n", banner);
+    type = banner;
+    cp = strchr(type, ':');
+    if (cp) {
+        *cp++ = 0;
+        /* Nothing is done with second field. */
+        cp = strchr(cp, ':');
+        if (cp) {
+#if ADB_OVER_PCIE
+	    static const char *dev_info[] = {
+	    	"device",
+		"vendor",
+		"class",
+	    };
+
+            char *save;
+            char *key;
+            key = adb_strtok_r(cp + 1, prop_seps, &save);
+            while (key) {
+                cp = strchr(key, key_val_sep);
+                if (cp) {
+                    *cp++ = '\0';
+                    if (!strcmp(key, dev_info[0]))
+			t->device = cp;
+                    else if (!strcmp(key, dev_info[1]))
+			t->product = cp;
+                    else if (!strcmp(key, dev_info[2]))
+			t->serial = cp;
+                }
+                key = adb_strtok_r(NULL, prop_seps, &save);
+            }
+#else
+	    static const char **dev_info = cnxn_props;
+            char *save;
+            char *key;
+            key = adb_strtok_r(cp + 1, prop_seps, &save);
+            while (key) {
+                cp = strchr(key, key_val_sep);
+                if (cp) {
+                    *cp++ = '\0';
+                    if (!strcmp(key, dev_info[0]))
+                        qual_overwrite(&t->product, cp);
+                    else if (!strcmp(key, dev_info[1]))
+                        qual_overwrite(&t->model, cp);
+                    else if (!strcmp(key, dev_info[2]))
+                        qual_overwrite(&t->device, cp);
+                }
+                key = adb_strtok_r(NULL, prop_seps, &save);
+            }
+#endif
+        }
+    }
+
+    if(!strcmp(type, "bootloader")){
+        D("setting connection_state to CS_BOOTLOADER\n");
+        t->connection_state = CS_BOOTLOADER;
+        update_transports();
+        return;
+    }
+
+    if(!strcmp(type, "device")) {
+        D("setting connection_state to CS_DEVICE\n");
+        t->connection_state = CS_DEVICE;
+        update_transports();
+        return;
+    }
+
+    if(!strcmp(type, "recovery")) {
+        D("setting connection_state to CS_RECOVERY\n");
+        t->connection_state = CS_RECOVERY;
+        update_transports();
+        return;
+    }
+
+    if(!strcmp(type, "sideload")) {
+        D("setting connection_state to CS_SIDELOAD\n");
+        t->connection_state = CS_SIDELOAD;
+        update_transports();
+        return;
+    }
+
+    t->connection_state = CS_HOST;
+}
+
+void handle_packet(apacket *p, atransport *t)
+{
+    asocket *s;
+
+    D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
+            ((char*) (&(p->msg.command)))[1],
+            ((char*) (&(p->msg.command)))[2],
+            ((char*) (&(p->msg.command)))[3]);
+    print_packet("recv", p);
+
+    switch(p->msg.command){
+    case A_SYNC:
+        if(p->msg.arg0){
+            send_packet(p, t);
+            if(HOST) send_connect(t);
+        } else {
+            t->connection_state = CS_OFFLINE;
+            handle_offline(t);
+            send_packet(p, t);
+        }
+        return;
+
+    case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
+            /* XXX verify version, etc */
+        if(t->connection_state != CS_OFFLINE) {
+            t->connection_state = CS_OFFLINE;
+            handle_offline(t);
+        }
+
+        parse_banner((char*) p->data, t);
+
+        if (HOST || !auth_enabled) {
+            handle_online(t);
+            if(!HOST) send_connect(t);
+        } else {
+            send_auth_request(t);
+        }
+        break;
+
+    case A_AUTH:
+        if (p->msg.arg0 == ADB_AUTH_TOKEN) {
+            t->connection_state = CS_UNAUTHORIZED;
+            t->key = adb_auth_nextkey(t->key);
+            if (t->key) {
+                send_auth_response(p->data, p->msg.data_length, t);
+            } else {
+                /* No more private keys to try, send the public key */
+                send_auth_publickey(t);
+            }
+        } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
+            if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
+                adb_auth_verified(t);
+                t->failed_auth_attempts = 0;
+            } else {
+                if (t->failed_auth_attempts++ > 10)
+                    adb_sleep_ms(1000);
+                send_auth_request(t);
+            }
+        } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
+            adb_auth_confirm_key(p->data, p->msg.data_length, t);
+        }
+        break;
+
+    case A_OPEN: /* OPEN(local-id, 0, "destination") */
+        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
+            char *name = (char*) p->data;
+            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
+            s = create_local_service_socket(name);
+            if(s == 0) {
+                send_close(0, p->msg.arg0, t);
+            } else {
+                s->peer = create_remote_socket(p->msg.arg0, t);
+                s->peer->peer = s;
+                send_ready(s->id, s->peer->id, t);
+                s->ready(s);
+            }
+        }
+        break;
+
+    case A_OKAY: /* READY(local-id, remote-id, "") */
+        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
+            if((s = find_local_socket(p->msg.arg1, 0))) {
+                if(s->peer == 0) {
+                    /* On first READY message, create the connection. */
+                    s->peer = create_remote_socket(p->msg.arg0, t);
+                    s->peer->peer = s;
+                    s->ready(s);
+                } else if (s->peer->id == p->msg.arg0) {
+                    /* Other READY messages must use the same local-id */
+                    s->ready(s);
+                } else {
+                    D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
+                      p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
+                }
+            }
+        }
+        break;
+
+    case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
+        if (t->online && p->msg.arg1 != 0) {
+            if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
+                /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
+                 * a failed OPEN only. However, due to a bug in previous ADB
+                 * versions, CLOSE(0, remote-id, "") was also used for normal
+                 * CLOSE() operations.
+                 *
+                 * This is bad because it means a compromised adbd could
+                 * send packets to close connections between the host and
+                 * other devices. To avoid this, only allow this if the local
+                 * socket has a peer on the same transport.
+                 */
+                if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
+                    D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
+                      p->msg.arg1, t->serial, s->peer->transport->serial);
+                } else {
+                    s->close(s);
+                }
+            }
+        }
+        break;
+
+    case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
+        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
+            if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
+                unsigned rid = p->msg.arg0;
+                p->len = p->msg.data_length;
+
+                if(s->enqueue(s, p) == 0) {
+                    D("Enqueue the socket\n");
+                    send_ready(s->id, rid, t);
+                }
+                return;
+            }
+        }
+        break;
+
+    default:
+        printf("handle_packet: what is %08x?!\n", p->msg.command);
+    }
+
+    put_apacket(p);
+}
+
+alistener listener_list = {
+    .next = &listener_list,
+    .prev = &listener_list,
+};
+
+static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
+{
+    asocket *s;
+
+    if(ev & FDE_READ) {
+        struct sockaddr addr;
+        socklen_t alen;
+        int fd;
+
+        alen = sizeof(addr);
+        fd = adb_socket_accept(_fd, &addr, &alen);
+        if(fd < 0) return;
+
+        adb_socket_setbufsize(fd, CHUNK_SIZE);
+
+        s = create_local_socket(fd);
+        if(s) {
+            connect_to_smartsocket(s);
+            return;
+        }
+
+        adb_close(fd);
+    }
+}
+
+static void listener_event_func(int _fd, unsigned ev, void *_l)
+{
+    alistener *l = _l;
+    asocket *s;
+
+    if(ev & FDE_READ) {
+        struct sockaddr addr;
+        socklen_t alen;
+        int fd;
+
+        alen = sizeof(addr);
+        fd = adb_socket_accept(_fd, &addr, &alen);
+        if(fd < 0) return;
+
+        s = create_local_socket(fd);
+        if(s) {
+            s->transport = l->transport;
+            connect_to_remote(s, l->connect_to);
+            return;
+        }
+
+        adb_close(fd);
+    }
+}
+
+static void  free_listener(alistener*  l)
+{
+    if (l->next) {
+        l->next->prev = l->prev;
+        l->prev->next = l->next;
+        l->next = l->prev = l;
+    }
+
+    // closes the corresponding fd
+    fdevent_remove(&l->fde);
+
+    if (l->local_name)
+        free((char*)l->local_name);
+
+    if (l->connect_to)
+        free((char*)l->connect_to);
+
+    if (l->transport) {
+        remove_transport_disconnect(l->transport, &l->disconnect);
+    }
+    free(l);
+}
+
+static void listener_disconnect(void*  _l, atransport*  t)
+{
+    alistener*  l = _l;
+
+    free_listener(l);
+}
+
+int local_name_to_fd(const char *name)
+{
+    int port;
+
+    if(!strncmp("tcp:", name, 4)){
+        int  ret;
+        port = atoi(name + 4);
+
+        if (gListenAll > 0) {
+            ret = socket_inaddr_any_server(port, SOCK_STREAM);
+        } else {
+            ret = socket_loopback_server(port, SOCK_STREAM);
+        }
+
+        return ret;
+    }
+#ifndef HAVE_WIN32_IPC  /* no Unix-domain sockets on Win32 */
+    // It's non-sensical to support the "reserved" space on the adb host side
+    if(!strncmp(name, "local:", 6)) {
+        return socket_local_server(name + 6,
+                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
+    } else if(!strncmp(name, "localabstract:", 14)) {
+        return socket_local_server(name + 14,
+                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
+    } else if(!strncmp(name, "localfilesystem:", 16)) {
+        return socket_local_server(name + 16,
+                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+    }
+
+#endif
+    printf("unknown local portname '%s'\n", name);
+    return -1;
+}
+
+// Write a single line describing a listener to a user-provided buffer.
+// Appends a trailing zero, even in case of truncation, but the function
+// returns the full line length.
+// If |buffer| is NULL, does not write but returns required size.
+static int format_listener(alistener* l, char* buffer, size_t buffer_len) {
+    // Format is simply:
+    //
+    //  <device-serial> " " <local-name> " " <remote-name> "\n"
+    //
+    int local_len = strlen(l->local_name);
+    int connect_len = strlen(l->connect_to);
+    int serial_len = strlen(l->transport->serial);
+
+    if (buffer != NULL) {
+        snprintf(buffer, buffer_len, "%s %s %s\n",
+                l->transport->serial, l->local_name, l->connect_to);
+    }
+    // NOTE: snprintf() on Windows returns -1 in case of truncation, so
+    // return the computed line length instead.
+    return local_len + connect_len + serial_len + 3;
+}
+
+// Write the list of current listeners (network redirections) into a
+// user-provided buffer. Appends a trailing zero, even in case of
+// trunctaion, but return the full size in bytes.
+// If |buffer| is NULL, does not write but returns required size.
+static int format_listeners(char* buf, size_t buflen)
+{
+    alistener* l;
+    int result = 0;
+    for (l = listener_list.next; l != &listener_list; l = l->next) {
+        // Ignore special listeners like those for *smartsocket*
+        if (l->connect_to[0] == '*')
+          continue;
+        int len = format_listener(l, buf, buflen);
+        // Ensure there is space for the trailing zero.
+        result += len;
+        if (buf != NULL) {
+          buf += len;
+          buflen -= len;
+          if (buflen <= 0)
+              break;
+        }
+    }
+    return result;
+}
+
+static int remove_listener(const char *local_name, atransport* transport)
+{
+    alistener *l;
+
+    for (l = listener_list.next; l != &listener_list; l = l->next) {
+        if (!strcmp(local_name, l->local_name)) {
+            listener_disconnect(l, l->transport);
+            return 0;
+        }
+    }
+    return -1;
+}
+
+static void remove_all_listeners(void)
+{
+    alistener *l, *l_next;
+    for (l = listener_list.next; l != &listener_list; l = l_next) {
+        l_next = l->next;
+        // Never remove smart sockets.
+        if (l->connect_to[0] == '*')
+            continue;
+        listener_disconnect(l, l->transport);
+    }
+}
+
+// error/status codes for install_listener.
+typedef enum {
+  INSTALL_STATUS_OK = 0,
+  INSTALL_STATUS_INTERNAL_ERROR = -1,
+  INSTALL_STATUS_CANNOT_BIND = -2,
+  INSTALL_STATUS_CANNOT_REBIND = -3,
+} install_status_t;
+
+static install_status_t install_listener(const char *local_name,
+                                         const char *connect_to,
+                                         atransport* transport,
+                                         int no_rebind)
+{
+    alistener *l;
+
+    //printf("install_listener('%s','%s')\n", local_name, connect_to);
+
+    for(l = listener_list.next; l != &listener_list; l = l->next){
+        if(strcmp(local_name, l->local_name) == 0) {
+            char *cto;
+
+                /* can't repurpose a smartsocket */
+            if(l->connect_to[0] == '*') {
+                return INSTALL_STATUS_INTERNAL_ERROR;
+            }
+
+                /* can't repurpose a listener if 'no_rebind' is true */
+            if (no_rebind) {
+                return INSTALL_STATUS_CANNOT_REBIND;
+            }
+
+            cto = strdup(connect_to);
+            if(cto == 0) {
+                return INSTALL_STATUS_INTERNAL_ERROR;
+            }
+
+            //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
+            free((void*) l->connect_to);
+            l->connect_to = cto;
+            if (l->transport != transport) {
+                remove_transport_disconnect(l->transport, &l->disconnect);
+                l->transport = transport;
+                add_transport_disconnect(l->transport, &l->disconnect);
+            }
+            return INSTALL_STATUS_OK;
+        }
+    }
+
+    if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
+    if((l->local_name = strdup(local_name)) == 0) goto nomem;
+    if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
+
+
+    l->fd = local_name_to_fd(local_name);
+    if(l->fd < 0) {
+        free((void*) l->local_name);
+        free((void*) l->connect_to);
+        free(l);
+        printf("cannot bind '%s'\n", local_name);
+        return -2;
+    }
+
+    close_on_exec(l->fd);
+    if(!strcmp(l->connect_to, "*smartsocket*")) {
+        fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
+    } else {
+        fdevent_install(&l->fde, l->fd, listener_event_func, l);
+    }
+    fdevent_set(&l->fde, FDE_READ);
+
+    l->next = &listener_list;
+    l->prev = listener_list.prev;
+    l->next->prev = l;
+    l->prev->next = l;
+    l->transport = transport;
+
+    if (transport) {
+        l->disconnect.opaque = l;
+        l->disconnect.func   = listener_disconnect;
+        add_transport_disconnect(transport, &l->disconnect);
+    }
+    return INSTALL_STATUS_OK;
+
+nomem:
+    fatal("cannot allocate listener");
+    return INSTALL_STATUS_INTERNAL_ERROR;
+}
+
+#if defined(_WIN32)
+static BOOL WINAPI ctrlc_handler(DWORD type)
+{
+    exit(STATUS_CONTROL_C_EXIT);
+    return TRUE;
+}
+#endif
+
+static void adb_cleanup(void)
+{
+#ifndef ADB_OVER_PCIE
+    usb_cleanup();
+#endif
+}
+
+void start_logging(void)
+{
+#if defined(_WIN32)
+    char    temp[ MAX_PATH ];
+    FILE*   fnul;
+    FILE*   flog;
+
+    GetTempPath( sizeof(temp) - 8, temp );
+    strcat( temp, "adb.log" );
+
+    /* Win32 specific redirections */
+    fnul = fopen( "NUL", "rt" );
+    if (fnul != NULL)
+        stdin[0] = fnul[0];
+
+    flog = fopen( temp, "at" );
+    if (flog == NULL)
+        flog = fnul;
+
+    setvbuf( flog, NULL, _IONBF, 0 );
+
+    stdout[0] = flog[0];
+    stderr[0] = flog[0];
+    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
+#else
+    int fd;
+
+    fd = unix_open("/dev/null", O_RDONLY);
+    dup2(fd, 0);
+    adb_close(fd);
+
+    fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);
+    if(fd < 0) {
+        fd = unix_open("/dev/null", O_WRONLY);
+    }
+    dup2(fd, 1);
+    dup2(fd, 2);
+    adb_close(fd);
+    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
+#endif
+}
+
+#if !ADB_HOST
+void start_device_log(void)
+{
+    int fd;
+    char    path[PATH_MAX];
+    struct tm now;
+    time_t t;
+    char value[PROPERTY_VALUE_MAX];
+
+    // read the trace mask from persistent property persist.adb.trace_mask
+    // give up if the property is not set or cannot be parsed
+    property_get("persist.adb.trace_mask", value, "");
+    if (sscanf(value, "%x", &adb_trace_mask) != 1)
+        return;
+
+    adb_mkdir("/tmp/adb", 0775);
+    tzset();
+    time(&t);
+    localtime_r(&t, &now);
+    strftime(path, sizeof(path),
+                "/tmp/adb/adb-%Y-%m-%d-%H-%M-%S.txt",
+                &now);
+    fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640);
+    if (fd < 0)
+        return;
+
+    // redirect stdout and stderr to the log file
+    dup2(fd, 1);
+    dup2(fd, 2);
+    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
+    adb_close(fd);
+
+    fd = unix_open("/dev/null", O_RDONLY);
+    dup2(fd, 0);
+    adb_close(fd);
+}
+#endif
+
+#if ADB_HOST
+
+#ifdef WORKAROUND_BUG6558362
+#include <sched.h>
+#define AFFINITY_ENVVAR "ADB_CPU_AFFINITY_BUG6558362"
+void adb_set_affinity(void)
+{
+   cpu_set_t cpu_set;
+   const char* cpunum_str = getenv(AFFINITY_ENVVAR);
+   char* strtol_res;
+   int cpu_num;
+
+   if (!cpunum_str || !*cpunum_str)
+       return;
+   cpu_num = strtol(cpunum_str, &strtol_res, 0);
+   if (*strtol_res != '\0')
+     fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, AFFINITY_ENVVAR);
+
+   sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+   D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+   CPU_ZERO(&cpu_set);
+   CPU_SET(cpu_num, &cpu_set);
+   sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
+   sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+   D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+}
+#endif
+
+int launch_server(int server_port)
+{
+#if defined(_WIN32)
+    /* we need to start the server in the background                    */
+    /* we create a PIPE that will be used to wait for the server's "OK" */
+    /* message since the pipe handles must be inheritable, we use a     */
+    /* security attribute                                               */
+    HANDLE                pipe_read, pipe_write;
+    HANDLE                stdout_handle, stderr_handle;
+    SECURITY_ATTRIBUTES   sa;
+    STARTUPINFO           startup;
+    PROCESS_INFORMATION   pinfo;
+    char                  program_path[ MAX_PATH ];
+    int                   ret;
+
+    sa.nLength = sizeof(sa);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle = TRUE;
+
+    /* create pipe, and ensure its read handle isn't inheritable */
+    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
+    if (!ret) {
+        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
+        return -1;
+    }
+
+    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
+
+    /* Some programs want to launch an adb command and collect its output by
+     * calling CreateProcess with inheritable stdout/stderr handles, then
+     * using read() to get its output. When this happens, the stdout/stderr
+     * handles passed to the adb client process will also be inheritable.
+     * When starting the adb server here, care must be taken to reset them
+     * to non-inheritable.
+     * Otherwise, something bad happens: even if the adb command completes,
+     * the calling process is stuck while read()-ing from the stdout/stderr
+     * descriptors, because they're connected to corresponding handles in the
+     * adb server process (even if the latter never uses/writes to them).
+     */
+    stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
+    stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
+    if (stdout_handle != INVALID_HANDLE_VALUE) {
+        SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
+    }
+    if (stderr_handle != INVALID_HANDLE_VALUE) {
+        SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
+    }
+
+    ZeroMemory( &startup, sizeof(startup) );
+    startup.cb = sizeof(startup);
+    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
+    startup.hStdOutput = pipe_write;
+    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
+    startup.dwFlags    = STARTF_USESTDHANDLES;
+
+    ZeroMemory( &pinfo, sizeof(pinfo) );
+
+    /* get path of current program */
+    GetModuleFileName( NULL, program_path, sizeof(program_path) );
+
+    ret = CreateProcess(
+            program_path,                              /* program path  */
+            "adb fork-server server",
+                                    /* the fork-server argument will set the
+                                       debug = 2 in the child           */
+            NULL,                   /* process handle is not inheritable */
+            NULL,                    /* thread handle is not inheritable */
+            TRUE,                          /* yes, inherit some handles */
+            DETACHED_PROCESS, /* the new process doesn't have a console */
+            NULL,                     /* use parent's environment block */
+            NULL,                    /* use parent's starting directory */
+            &startup,                 /* startup info, i.e. std handles */
+            &pinfo );
+
+    CloseHandle( pipe_write );
+
+    if (!ret) {
+        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
+        CloseHandle( pipe_read );
+        return -1;
+    }
+
+    CloseHandle( pinfo.hProcess );
+    CloseHandle( pinfo.hThread );
+
+    /* wait for the "OK\n" message */
+    {
+        char  temp[3];
+        DWORD  count;
+
+        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
+        CloseHandle( pipe_read );
+        if ( !ret ) {
+            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
+            return -1;
+        }
+        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
+            fprintf(stderr, "ADB server didn't ACK\n" );
+            return -1;
+        }
+    }
+#else /* !defined(_WIN32) */
+    char    path[PATH_MAX];
+    int     fd[2];
+
+    // set up a pipe so the child can tell us when it is ready.
+    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
+    if (pipe(fd)) {
+        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
+        return -1;
+    }
+    get_my_path(path, PATH_MAX);
+    pid_t pid = fork();
+    if(pid < 0) return -1;
+
+    if (pid == 0) {
+        // child side of the fork
+
+        // redirect stderr to the pipe
+        // we use stderr instead of stdout due to stdout's buffering behavior.
+        adb_close(fd[0]);
+        dup2(fd[1], STDERR_FILENO);
+        adb_close(fd[1]);
+
+        char str_port[30];
+        snprintf(str_port, sizeof(str_port), "%d",  server_port);
+        // child process
+        int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
+        // this should not return
+        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
+    } else  {
+        // parent side of the fork
+
+        char  temp[3];
+
+        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
+        // wait for the "OK\n" message
+        adb_close(fd[1]);
+        int ret = adb_read(fd[0], temp, 3);
+        int saved_errno = errno;
+        adb_close(fd[0]);
+        if (ret < 0) {
+            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
+            return -1;
+        }
+        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
+            fprintf(stderr, "ADB server didn't ACK\n" );
+            return -1;
+        }
+
+        setsid();
+    }
+#endif /* !defined(_WIN32) */
+    return 0;
+}
+#endif /* ADB_HOST */
+
+/* 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);
+}
+
+#if !ADB_HOST
+
+static void drop_capabilities_bounding_set_if_needed() {
+#ifdef ALLOW_ADBD_ROOT
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.debuggable", value, "");
+    if (strcmp(value, "1") == 0) {
+        return;
+    }
+#endif
+    int i;
+    for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
+        if (i == CAP_SETUID || i == CAP_SETGID) {
+            // CAP_SETUID CAP_SETGID needed by /system/bin/run-as
+            continue;
+        }
+        int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
+
+        // Some kernels don't have file capabilities compiled in, and
+        // prctl(PR_CAPBSET_DROP) returns EINVAL. Don't automatically
+        // die when we see such misconfigured kernels.
+        if ((err < 0) && (errno != EINVAL)) {
+            exit(1);
+        }
+    }
+}
+
+static int should_drop_privileges() {
+#ifndef ALLOW_ADBD_ROOT
+    return 1;
+#else /* ALLOW_ADBD_ROOT */
+#ifdef ADB_NON_ANDROID
+    return 0;
+#endif /* ADB_NON_ANDROID */
+    int secure = 0;
+    char value[PROPERTY_VALUE_MAX];
+
+   /* run adbd in secure mode if ro.secure is set and
+    ** we are not in the emulator
+    */
+    property_get("ro.kernel.qemu", value, "");
+    if (strcmp(value, "1") != 0) {
+        property_get("ro.secure", value, "1");
+        if (strcmp(value, "1") == 0) {
+            // don't run as root if ro.secure is set...
+            secure = 1;
+
+            // ... except we allow running as root in userdebug builds if the
+            // service.adb.root property has been set by the "adb root" command
+            property_get("ro.debuggable", value, "");
+            if (strcmp(value, "1") == 0) {
+                property_get("service.adb.root", value, "");
+                if (strcmp(value, "1") == 0) {
+                    secure = 0;
+                }
+            }
+        }
+    }
+    return secure;
+#endif /* ALLOW_ADBD_ROOT */
+}
+#endif /* !ADB_HOST */
+
+int adb_main(int is_daemon, int server_port)
+{
+    char tmp[20];
+#if !ADB_HOST
+    int port;
+    char value[PROPERTY_VALUE_MAX];
+
+    umask(000);
+#endif
+
+    atexit(adb_cleanup);
+#if defined(_WIN32)
+    SetConsoleCtrlHandler( ctrlc_handler, TRUE );
+#else
+    // No SIGCHLD. Let the service subproc handle its children.
+    signal(SIGPIPE, SIG_IGN);
+#endif
+
+    init_transport_registration();
+
+#if ADB_HOST
+    HOST = 1;
+
+#ifdef WORKAROUND_BUG6558362
+    if(is_daemon) adb_set_affinity();
+#endif
+
+#if ADB_OVER_PCIE
+    fprintf(stderr, "adb path: %s\n", PCIE_ADB_PATH);
+    pcie_host_init();
+#else
+    usb_init();
+#endif
+    local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
+    adb_auth_init();
+
+    char local_name[30];
+    build_local_name(local_name, sizeof(local_name), server_port);
+    if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
+        exit(1);
+    }
+#else
+    property_get("ro.adb.secure", value, "0");
+    auth_enabled = !strcmp(value, "1");
+    if (auth_enabled)
+        adb_auth_init();
+
+    // Our external storage path may be different than apps, since
+    // we aren't able to bind mount after dropping root.
+    const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
+    if (NULL != adb_external_storage) {
+        setenv("EXTERNAL_STORAGE", adb_external_storage, 1);
+    } else {
+        D("Warning: ADB_EXTERNAL_STORAGE is not set.  Leaving EXTERNAL_STORAGE"
+          " unchanged.\n");
+    }
+
+    /* add extra groups:
+    ** AID_ADB to access the USB driver
+    ** AID_LOG to read system logs (adb logcat)
+    ** AID_INPUT to diagnose input issues (getevent)
+    ** AID_INET to diagnose network issues (netcfg, ping)
+    ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
+    ** AID_SDCARD_R to allow reading from the SD card
+    ** AID_SDCARD_RW to allow writing to the SD card
+    ** AID_NET_BW_STATS to read out qtaguid statistics
+    */
+    gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_NET_BT,
+                       AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
+                       AID_NET_BW_STATS };
+    if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
+        exit(1);
+    }
+
+    /* don't listen on a port (default 5037) if running in secure mode */
+    /* don't run as root if we are running in secure mode */
+    if (should_drop_privileges()) {
+        drop_capabilities_bounding_set_if_needed();
+
+        /* then switch user and group to "shell" */
+        if (setgid(AID_SHELL) != 0) {
+            exit(1);
+        }
+        if (setuid(AID_SHELL) != 0) {
+            exit(1);
+        }
+
+        D("Local port disabled\n");
+    } else {
+#ifndef ADB_NON_ANDROID
+        char local_name[30];
+        if ((root_seclabel != NULL) && (is_selinux_enabled() > 0)) {
+            // b/12587913: fix setcon to allow const pointers
+            if (setcon((char *)root_seclabel) < 0) {
+                exit(1);
+            }
+        }
+        build_local_name(local_name, sizeof(local_name), server_port);
+        if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
+            exit(1);
+        }
+#endif
+    }
+
+    int usb = 0;
+#ifdef ADB_OVER_PCIE
+    fprintf(stderr, "adbd path: %s\n", PCIE_ADB_PATH);
+    if (access(PCIE_ADB_PATH, F_OK) == 0) {
+	pcie_init();
+	usb = 1;
+    }
+#else
+  /*  if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {
+        // listen on USB
+        usb_init();
+        usb = 1;
+    }
+  */
+#endif
+
+    // If one of these properties is set, also listen on that port
+    // If one of the properties isn't set and we couldn't listen on usb,
+    // listen on the default port.
+    //FILE *f=fopen("/data/adbd.log","rb");
+#define LOG_UCI_MODULE "tcp"
+#define LOG_UCI_FILE "lynq_uci"
+
+    lynq_get_value(LOG_UCI_FILE, LOG_UCI_MODULE, "port", value); // 即获取系统层面的环境变量
+   
+    printf("ADB Daemon. port %s\n",value);
+    //fprintf(f,"usb.tcp.port=%d\n", value);
+    if (!value[0]) {
+        property_get("persist.adb.tcp.port", value, "");
+    }
+    if (sscanf(value, "%d", &port) == 1 && port > 0) {
+        printf("using port=%d\n", port);
+        // listen on TCP port specified by service.adb.tcp.port property
+        local_init(port);
+    } else if (!usb) {
+        // listen on default port
+        local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
+    }
+    //fprintf(f,"usb.tcp.port=5555\n");
+    D("adb_main(): pre init_jdwp()\n");
+    init_jdwp();
+    D("adb_main(): post init_jdwp()\n");
+#endif
+
+    if (is_daemon)
+    {
+        // inform our parent that we are up and running.
+#if defined(_WIN32)
+        DWORD  count;
+        WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );
+#else
+        fprintf(stderr, "OK\n");
+#endif
+        start_logging();
+    }
+    D("Event loop starting\n");
+
+    fdevent_loop();
+
+#ifndef ADB_OVER_PCIE
+    usb_cleanup();
+#endif
+
+    return 0;
+}
+
+// Try to handle a network forwarding request.
+// This returns 1 on success, 0 on failure, and -1 to indicate this is not
+// a forwarding-related request.
+int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
+{
+    if (!strcmp(service, "list-forward")) {
+        // Create the list of forward redirections.
+        int buffer_size = format_listeners(NULL, 0);
+        // Add one byte for the trailing zero.
+        char* buffer = malloc(buffer_size + 1);
+        if (buffer == NULL) {
+            sendfailmsg(reply_fd, "not enough memory");
+            return 1;
+        }
+        (void) format_listeners(buffer, buffer_size + 1);
+#if ADB_HOST
+        send_msg_with_okay(reply_fd, buffer, buffer_size);
+#else
+        send_msg_with_header(reply_fd, buffer, buffer_size);
+#endif
+        free(buffer);
+        return 1;
+    }
+
+    if (!strcmp(service, "killforward-all")) {
+        remove_all_listeners();
+#if ADB_HOST
+        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
+        adb_write(reply_fd, "OKAY", 4);
+#endif
+        adb_write(reply_fd, "OKAY", 4);
+        return 1;
+    }
+
+    if (!strncmp(service, "forward:",8) ||
+        !strncmp(service, "killforward:",12)) {
+        char *local, *remote, *err;
+        int r;
+        atransport *transport;
+
+        int createForward = strncmp(service, "kill", 4);
+        int no_rebind = 0;
+
+        local = strchr(service, ':') + 1;
+
+        // Handle forward:norebind:<local>... here
+        if (createForward && !strncmp(local, "norebind:", 9)) {
+            no_rebind = 1;
+            local = strchr(local, ':') + 1;
+        }
+
+        remote = strchr(local,';');
+
+        if (createForward) {
+            // Check forward: parameter format: '<local>;<remote>'
+            if(remote == 0) {
+                sendfailmsg(reply_fd, "malformed forward spec");
+                return 1;
+            }
+
+            *remote++ = 0;
+            if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
+                sendfailmsg(reply_fd, "malformed forward spec");
+                return 1;
+            }
+        } else {
+            // Check killforward: parameter format: '<local>'
+            if (local[0] == 0) {
+                sendfailmsg(reply_fd, "malformed forward spec");
+                return 1;
+            }
+        }
+
+        transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
+        if (!transport) {
+            sendfailmsg(reply_fd, err);
+            return 1;
+        }
+
+        if (createForward) {
+            r = install_listener(local, remote, transport, no_rebind);
+        } else {
+            r = remove_listener(local, transport);
+        }
+        if(r == 0) {
+#if ADB_HOST
+            /* On the host: 1st OKAY is connect, 2nd OKAY is status */
+            writex(reply_fd, "OKAY", 4);
+#endif
+            writex(reply_fd, "OKAY", 4);
+            return 1;
+        }
+
+        if (createForward) {
+            const char* message;
+            switch (r) {
+              case INSTALL_STATUS_CANNOT_BIND:
+                message = "cannot bind to socket";
+                break;
+              case INSTALL_STATUS_CANNOT_REBIND:
+                message = "cannot rebind existing socket";
+                break;
+              default:
+                message = "internal error";
+            }
+            sendfailmsg(reply_fd, message);
+        } else {
+            sendfailmsg(reply_fd, "cannot remove listener");
+        }
+        return 1;
+    }
+    return 0;
+}
+
+int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
+{
+    if(!strcmp(service, "kill")) {
+        fprintf(stderr,"adb server killed by remote request\n");
+        fflush(stdout);
+        adb_write(reply_fd, "OKAY", 4);
+#ifndef ADB_OVER_PCIE
+        usb_cleanup();
+#endif
+        exit(0);
+    }
+
+#if ADB_HOST
+    atransport *transport = NULL;
+    // "transport:" is used for switching transport with a specified serial number
+    // "transport-usb:" is used for switching transport to the only USB transport
+    // "transport-local:" is used for switching transport to the only local transport
+    // "transport-any:" is used for switching transport to the only transport
+    if (!strncmp(service, "transport", strlen("transport"))) {
+        char* error_string = "unknown failure";
+        transport_type type = kTransportAny;
+
+        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
+            type = kTransportUsb;
+        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
+            type = kTransportLocal;
+        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
+            type = kTransportAny;
+        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
+            service += strlen("transport:");
+            serial = service;
+        }
+
+        transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
+
+        if (transport) {
+            s->transport = transport;
+            adb_write(reply_fd, "OKAY", 4);
+        } else {
+            sendfailmsg(reply_fd, error_string);
+        }
+        return 1;
+    }
+
+    // return a list of all connected devices
+    if (!strncmp(service, "devices", 7)) {
+        char buffer[4096];
+        int use_long = !strcmp(service+7, "-l");
+        if (use_long || service[7] == 0) {
+            memset(buffer, 0, sizeof(buffer));
+            D("Getting device list \n");
+            list_transports(buffer, sizeof(buffer), use_long);
+            D("Wrote device list \n");
+            send_msg_with_okay(reply_fd, buffer, strlen(buffer));
+            return 0;
+        }
+    }
+
+    // remove TCP transport
+    if (!strncmp(service, "disconnect:", 11)) {
+        char buffer[4096];
+        memset(buffer, 0, sizeof(buffer));
+        char* serial = service + 11;
+        if (serial[0] == 0) {
+            // disconnect from all TCP devices
+            unregister_all_tcp_transports();
+        } else {
+            char hostbuf[100];
+            // assume port 5555 if no port is specified
+            if (!strchr(serial, ':')) {
+                snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
+                serial = hostbuf;
+            }
+            atransport *t = find_transport(serial);
+
+            if (t) {
+                unregister_transport(t);
+            } else {
+                snprintf(buffer, sizeof(buffer), "No such device %s", serial);
+            }
+        }
+
+        send_msg_with_okay(reply_fd, buffer, strlen(buffer));
+        return 0;
+    }
+
+    // returns our value for ADB_SERVER_VERSION
+    if (!strcmp(service, "version")) {
+        char version[12];
+        snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
+        send_msg_with_okay(reply_fd, version, strlen(version));
+        return 0;
+    }
+
+    if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
+        char *out = "unknown";
+         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
+       if (transport && transport->serial) {
+            out = transport->serial;
+        }
+        send_msg_with_okay(reply_fd, out, strlen(out));
+        return 0;
+    }
+    if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
+        char *out = "unknown";
+         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
+       if (transport && transport->devpath) {
+            out = transport->devpath;
+        }
+        send_msg_with_okay(reply_fd, out, strlen(out));
+        return 0;
+    }
+    // indicates a new emulator instance has started
+    if (!strncmp(service,"emulator:",9)) {
+        int  port = atoi(service+9);
+        local_connect(port);
+        /* we don't even need to send a reply */
+        return 0;
+    }
+
+    if(!strncmp(service,"get-state",strlen("get-state"))) {
+        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
+        char *state = connection_state_name(transport);
+        send_msg_with_okay(reply_fd, state, strlen(state));
+        return 0;
+    }
+#endif // ADB_HOST
+
+    int ret = handle_forward_request(service, ttype, serial, reply_fd);
+    if (ret >= 0)
+      return ret - 1;
+    return -1;
+}
+
+int main(int argc, char **argv)
+{
+#if ADB_HOST
+    adb_sysdeps_init();
+    adb_trace_init();
+    D("Handling commandline()\n");
+    return adb_commandline(argc - 1, argv + 1);
+#else
+    /* If adbd runs inside the emulator this will enable adb tracing via
+     * adb-debug qemud service in the emulator. */
+    //adb_qemu_trace_init();
+    D("main()\n");
+    while(1) {
+        int c;
+        int option_index = 0;
+        static struct option opts[] = {
+            {"root_seclabel", required_argument, 0, 's' },
+            {"device_banner", required_argument, 0, 'b' }
+        };
+        c = getopt_long(argc, argv, "", opts, &option_index);
+        if (c == -1)
+            break;
+        switch (c) {
+        case 's':
+            root_seclabel = optarg;
+            break;
+        case 'b':
+            adb_device_banner = optarg;
+            break;
+        default:
+            break;
+        }
+    }
+
+    start_device_log();
+    D("Handling main()\n");
+    return adb_main(0, DEFAULT_ADB_PORT);
+#endif
+}
