Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e67f1f87 authored by Elliott Hughes's avatar Elliott Hughes
Browse files

More adb buffer fixes.

This patch factors out a lot of the basic protocol code: sending OKAY,
sending FAIL, and sending a length-prefixed string.

ADB_TRACE has been non-optional for a long time, so let's just remove
the #ifs.

Also actually build the device tracker test tool (and remove its duplicate).

Bug: http://b/20666660
Change-Id: I6c7d59f18707bdc62ca69dea45547617f9f31fc6
parent bacac0f7
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -124,6 +124,21 @@ endif


include $(BUILD_HOST_NATIVE_TEST)
include $(BUILD_HOST_NATIVE_TEST)


# adb device tracker (used by ddms) test tool
# =========================================================

ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
LOCAL_CLANG := $(adb_host_clang)
LOCAL_MODULE := adb_device_tracker_test
LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := test_track_devices.cpp
LOCAL_SHARED_LIBRARIES := liblog libbase
LOCAL_STATIC_LIBRARIES := libadb libcrypto_static libcutils
LOCAL_LDLIBS += -lrt -ldl -lpthread
include $(BUILD_HOST_EXECUTABLE)
endif

# adb host tool
# adb host tool
# =========================================================
# =========================================================
include $(CLEAR_VARS)
include $(CLEAR_VARS)
+33 −90
Original line number Original line Diff line number Diff line
@@ -48,9 +48,7 @@
#include <sys/mount.h>
#include <sys/mount.h>
#endif
#endif


#if ADB_TRACE
ADB_MUTEX_DEFINE( D_lock );
ADB_MUTEX_DEFINE( D_lock );
#endif


int HOST = 0;
int HOST = 0;


@@ -322,28 +320,6 @@ static size_t fill_connect_data(char *buf, size_t bufsize)
#endif
#endif
}
}


#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);
    WriteFdExactly(fd, header, 4);
    WriteFdExactly(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);
    WriteFdExactly(fd, header, 8);
    WriteFdExactly(fd, msg, msglen);
}
#endif // ADB_HOST

void send_connect(atransport *t)
void send_connect(atransport *t)
{
{
    D("Calling send_connect \n");
    D("Calling send_connect \n");
@@ -356,32 +332,6 @@ void send_connect(atransport *t)
    send_packet(cp, t);
    send_packet(cp, t);
}
}


#if ADB_HOST
static const 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
// 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
// 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.
// was malloc'ed and needs to freed.  *dst will be set to a dup of src.
@@ -752,20 +702,11 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
{
{
    if (!strcmp(service, "list-forward")) {
    if (!strcmp(service, "list-forward")) {
        // Create the list of forward redirections.
        // Create the list of forward redirections.
        int buffer_size = format_listeners(NULL, 0);
        std::string listeners = format_listeners();
        // Add one byte for the trailing zero.
        char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1));
        if (buffer == nullptr) {
            sendfailmsg(reply_fd, "not enough memory");
            return 1;
        }
        (void) format_listeners(buffer, buffer_size + 1);
#if ADB_HOST
#if ADB_HOST
        send_msg_with_okay(reply_fd, buffer, buffer_size);
        SendOkay(reply_fd);
#else
        send_msg_with_header(reply_fd, buffer, buffer_size);
#endif
#endif
        free(buffer);
        SendProtocolString(reply_fd, listeners);
        return 1;
        return 1;
    }
    }


@@ -773,9 +714,9 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
        remove_all_listeners();
        remove_all_listeners();
#if ADB_HOST
#if ADB_HOST
        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
        adb_write(reply_fd, "OKAY", 4);
        SendOkay(reply_fd);
#endif
#endif
        adb_write(reply_fd, "OKAY", 4);
        SendOkay(reply_fd);
        return 1;
        return 1;
    }
    }


@@ -800,19 +741,19 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
        if (createForward) {
        if (createForward) {
            // Check forward: parameter format: '<local>;<remote>'
            // Check forward: parameter format: '<local>;<remote>'
            if(remote == 0) {
            if(remote == 0) {
                sendfailmsg(reply_fd, "malformed forward spec");
                SendFail(reply_fd, "malformed forward spec");
                return 1;
                return 1;
            }
            }


            *remote++ = 0;
            *remote++ = 0;
            if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
            if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
                sendfailmsg(reply_fd, "malformed forward spec");
                SendFail(reply_fd, "malformed forward spec");
                return 1;
                return 1;
            }
            }
        } else {
        } else {
            // Check killforward: parameter format: '<local>'
            // Check killforward: parameter format: '<local>'
            if (local[0] == 0) {
            if (local[0] == 0) {
                sendfailmsg(reply_fd, "malformed forward spec");
                SendFail(reply_fd, "malformed forward spec");
                return 1;
                return 1;
            }
            }
        }
        }
@@ -820,7 +761,7 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
        std::string error_msg;
        std::string error_msg;
        transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
        transport = acquire_one_transport(CS_ANY, ttype, serial, &error_msg);
        if (!transport) {
        if (!transport) {
            sendfailmsg(reply_fd, error_msg.c_str());
            SendFail(reply_fd, error_msg);
            return 1;
            return 1;
        }
        }


@@ -833,9 +774,9 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
        if (r == INSTALL_STATUS_OK) {
        if (r == INSTALL_STATUS_OK) {
#if ADB_HOST
#if ADB_HOST
            /* On the host: 1st OKAY is connect, 2nd OKAY is status */
            /* On the host: 1st OKAY is connect, 2nd OKAY is status */
            WriteFdExactly(reply_fd, "OKAY", 4);
            SendOkay(reply_fd);
#endif
#endif
            WriteFdExactly(reply_fd, "OKAY", 4);
            SendOkay(reply_fd);
            return 1;
            return 1;
        }
        }


@@ -851,7 +792,7 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri
            break;
            break;
          case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
          case INSTALL_STATUS_LISTENER_NOT_FOUND: message = "listener not found"; break;
        }
        }
        sendfailmsg(reply_fd, message.c_str());
        SendFail(reply_fd, message);
        return 1;
        return 1;
    }
    }
    return 0;
    return 0;
@@ -862,7 +803,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
    if(!strcmp(service, "kill")) {
    if(!strcmp(service, "kill")) {
        fprintf(stderr,"adb server killed by remote request\n");
        fprintf(stderr,"adb server killed by remote request\n");
        fflush(stdout);
        fflush(stdout);
        adb_write(reply_fd, "OKAY", 4);
        SendOkay(reply_fd);
        usb_cleanup();
        usb_cleanup();
        exit(0);
        exit(0);
    }
    }
@@ -892,25 +833,25 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r


        if (transport) {
        if (transport) {
            s->transport = transport;
            s->transport = transport;
            adb_write(reply_fd, "OKAY", 4);
            SendOkay(reply_fd);
        } else {
        } else {
            sendfailmsg(reply_fd, error_msg.c_str());
            SendFail(reply_fd, error_msg);
        }
        }
        return 1;
        return 1;
    }
    }


    // return a list of all connected devices
    // return a list of all connected devices
    if (!strncmp(service, "devices", 7)) {
    if (!strncmp(service, "devices", 7)) {
        char buffer[4096];
        bool long_listing = (strcmp(service+7, "-l") == 0);
        int use_long = !strcmp(service+7, "-l");
        if (long_listing || service[7] == 0) {
        if (use_long || service[7] == 0) {
            D("Getting device list...\n");
            memset(buffer, 0, sizeof(buffer));
            std::string device_list = list_transports(long_listing);
            D("Getting device list \n");
            D("Sending device list...\n");
            list_transports(buffer, sizeof(buffer), use_long);
            SendOkay(reply_fd);
            D("Wrote device list \n");
            SendProtocolString(reply_fd, device_list);
            send_msg_with_okay(reply_fd, buffer, strlen(buffer));
            return 0;
            return 0;
        }
        }
        return 1;
    }
    }


    // remove TCP transport
    // remove TCP transport
@@ -937,15 +878,15 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
            }
            }
        }
        }


        send_msg_with_okay(reply_fd, buffer, strlen(buffer));
        SendOkay(reply_fd);
        SendProtocolString(reply_fd, buffer);
        return 0;
        return 0;
    }
    }


    // returns our value for ADB_SERVER_VERSION
    // returns our value for ADB_SERVER_VERSION
    if (!strcmp(service, "version")) {
    if (!strcmp(service, "version")) {
        char version[12];
        SendOkay(reply_fd);
        snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
        SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
        send_msg_with_okay(reply_fd, version, strlen(version));
        return 0;
        return 0;
    }
    }


@@ -955,7 +896,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
        if (transport && transport->serial) {
        if (transport && transport->serial) {
            out = transport->serial;
            out = transport->serial;
        }
        }
        send_msg_with_okay(reply_fd, out, strlen(out));
        SendOkay(reply_fd);
        SendProtocolString(reply_fd, out);
        return 0;
        return 0;
    }
    }
    if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
    if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
@@ -964,7 +906,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
        if (transport && transport->devpath) {
        if (transport && transport->devpath) {
            out = transport->devpath;
            out = transport->devpath;
        }
        }
        send_msg_with_okay(reply_fd, out, strlen(out));
        SendOkay(reply_fd);
        SendProtocolString(reply_fd, out);
        return 0;
        return 0;
    }
    }
    // indicates a new emulator instance has started
    // indicates a new emulator instance has started
@@ -977,8 +920,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r


    if(!strncmp(service,"get-state",strlen("get-state"))) {
    if(!strncmp(service,"get-state",strlen("get-state"))) {
        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
        const char *state = connection_state_name(transport);
        SendOkay(reply_fd);
        send_msg_with_okay(reply_fd, state, strlen(state));
        SendProtocolString(reply_fd, transport->connection_state_name());
        return 0;
        return 0;
    }
    }
#endif // ADB_HOST
#endif // ADB_HOST
+2 −1
Original line number Original line Diff line number Diff line
@@ -209,6 +209,8 @@ struct atransport
    unsigned char token[TOKEN_SIZE];
    unsigned char token[TOKEN_SIZE];
    fdevent auth_fde;
    fdevent auth_fde;
    unsigned failed_auth_attempts;
    unsigned failed_auth_attempts;

    const char* connection_state_name() const;
};
};




@@ -369,7 +371,6 @@ enum subproc_mode {
#define USB_FFS_ADB_IN    USB_FFS_ADB_EP(ep2)
#define USB_FFS_ADB_IN    USB_FFS_ADB_EP(ep2)
#endif
#endif


int sendfailmsg(int fd, const char *reason);
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);


void handle_online(atransport *t);
void handle_online(atransport *t);
+3 −7
Original line number Original line Diff line number Diff line
@@ -56,7 +56,7 @@ static bool ReadProtocolString(int fd, std::string* s, std::string* error) {
    buf[4] = 0;
    buf[4] = 0;


    unsigned long len = strtoul(buf, 0, 16);
    unsigned long len = strtoul(buf, 0, 16);
    s->resize(len + 1, '\0'); // Ensure NUL-termination.
    s->resize(len, '\0');
    if (!ReadFdExactly(fd, &(*s)[0], len)) {
    if (!ReadFdExactly(fd, &(*s)[0], len)) {
        *error = perror_str("protocol fault (couldn't read status message)");
        *error = perror_str("protocol fault (couldn't read status message)");
        return false;
        return false;
@@ -136,9 +136,7 @@ static int switch_socket_transport(int fd, std::string* error) {
        service += transport_type;
        service += transport_type;
    }
    }


    char tmp[5];
    if (!SendProtocolString(fd, service)) {
    snprintf(tmp, sizeof(tmp), "%04zx", service.size());
    if (!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, service.c_str(), service.size())) {
        *error = perror_str("write failure during connection");
        *error = perror_str("write failure during connection");
        adb_close(fd);
        adb_close(fd);
        return -1;
        return -1;
@@ -199,9 +197,7 @@ int _adb_connect(const std::string& service, std::string* error) {
        return -1;
        return -1;
    }
    }


    char tmp[5];
    if(!SendProtocolString(fd, service)) {
    snprintf(tmp, sizeof(tmp), "%04zx", service.size());
    if(!WriteFdExactly(fd, tmp, 4) || !WriteFdExactly(fd, &service[0], service.size())) {
        *error = perror_str("write failure during connection");
        *error = perror_str("write failure during connection");
        adb_close(fd);
        adb_close(fd);
        return -1;
        return -1;
+28 −7
Original line number Original line Diff line number Diff line
@@ -22,14 +22,31 @@
#include <unistd.h>
#include <unistd.h>


#include "adb_trace.h"
#include "adb_trace.h"
#include "transport.h"
#include "adb_utils.h"

bool SendProtocolString(int fd, const std::string& s) {
    int length = s.size();
    if (length > 0xffff) {
        length = 0xffff;
    }

    char buf[5];
    snprintf(buf, sizeof(buf), "%04x", length);
    return WriteFdExactly(fd, buf, 4) && WriteFdExactly(fd, s);
}

bool SendOkay(int fd) {
    return WriteFdExactly(fd, "OKAY", 4);
}

bool SendFail(int fd, const std::string& reason) {
    return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
}


bool ReadFdExactly(int fd, void* buf, size_t len) {
bool ReadFdExactly(int fd, void* buf, size_t len) {
    char* p = reinterpret_cast<char*>(buf);
    char* p = reinterpret_cast<char*>(buf);


#if ADB_TRACE
    size_t len0 = len;
    size_t len0 = len;
#endif


    D("readx: fd=%d wanted=%zu\n", fd, len);
    D("readx: fd=%d wanted=%zu\n", fd, len);
    while (len > 0) {
    while (len > 0) {
@@ -47,12 +64,10 @@ bool ReadFdExactly(int fd, void* buf, size_t len) {
        }
        }
    }
    }


#if ADB_TRACE
    D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len);
    D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len);
    if (ADB_TRACING) {
    if (ADB_TRACING) {
        dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
        dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
    }
    }
#endif


    return true;
    return true;
}
}
@@ -61,12 +76,10 @@ bool WriteFdExactly(int fd, const void* buf, size_t len) {
    const char* p = reinterpret_cast<const char*>(buf);
    const char* p = reinterpret_cast<const char*>(buf);
    int r;
    int r;


#if ADB_TRACE
    D("writex: fd=%d len=%d: ", fd, (int)len);
    D("writex: fd=%d len=%d: ", fd, (int)len);
    if (ADB_TRACING) {
    if (ADB_TRACING) {
        dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
        dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
    }
    }
#endif


    while (len > 0) {
    while (len > 0) {
        r = adb_write(fd, p, len);
        r = adb_write(fd, p, len);
@@ -90,6 +103,14 @@ bool WriteFdExactly(int fd, const void* buf, size_t len) {
    return true;
    return true;
}
}


bool WriteFdExactly(int fd, const char* str) {
    return WriteFdExactly(fd, str, strlen(str));
}

bool WriteFdExactly(int fd, const std::string& str) {
    return WriteFdExactly(fd, str.c_str(), str.size());
}

bool WriteStringFully(int fd, const char* str) {
bool WriteStringFully(int fd, const char* str) {
    return WriteFdExactly(fd, str, strlen(str));
    return WriteFdExactly(fd, str, strlen(str));
}
}
Loading