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

Commit 038862e1 authored by The Android Open Source Project's avatar The Android Open Source Project
Browse files

Merge branch 'cupcake'

parents 5a326952 5ae090ed
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -77,14 +77,6 @@ ifeq ($(HOST_OS),windows)
$(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll
endif

ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
	kdbg.c
LOCAL_MODULE := kdbg
include $(BUILD_HOST_EXECUTABLE)
endif

endif

# adbd device daemon
+1 −10
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ host:<request>
<host-prefix>:get-state
    Returns the state of a given device as a string.

<host-prefix>:forward:<local>:<remote>
<host-prefix>:forward:<local>;<remote>
    Asks the ADB server to forward local connections from <local>
    to the <remote> address on a given device.

@@ -135,15 +135,6 @@ shell:
    this to implement "adb shell", but will also cook the input before
    sending it to the device (see interactive_shell() in commandline.c)

bootdebug:
    Ask debugging information to the bootloader. The adbd daemon will
    respond with FAIL to this request.

bootloader:<command>
    Send a request to the bootloader. This can also work if the device
    is currently in the bootloader state. The adbd daemon will respond
    with FAIL to such requests.

remount:
    Ask adbd to remount the device's filesystem in read-write mode,
    instead of read-only. This is usually necessary before performing
+0 −10
Original line number Diff line number Diff line
@@ -985,16 +985,6 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
        return 0;
    }

    if(!strncmp(service,"get-product",strlen("get-product"))) {
        char *out = "unknown";
        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
        if (transport && transport->product) {
            out = transport->product;
        }
        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
        writex(reply_fd, buf, strlen(buf));
        return 0;
    }
    if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
        char *out = "unknown";
         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
+1 −135
Original line number Diff line number Diff line
@@ -144,7 +144,6 @@ void help()
        "  adb start-server             - ensure that there is a server running\n"
        "  adb kill-server              - kill the server if it is running\n"
        "  adb get-state                - prints: offline | bootloader | device\n"
        "  adb get-product              - prints: <product-id>\n"
        "  adb get-serialno             - prints: <serial-number>\n"
        "  adb status-window            - continuously print device status for a specified device\n"
        "  adb remount                  - remounts the /system partition on the device read-write\n"
@@ -377,82 +376,6 @@ int interactive_shell(void)
}



int adb_download_buffer(const char *service, const void* data, int sz,
                        unsigned progress)
{
    char buf[4096];
    unsigned total;
    int fd;
    const unsigned char *ptr;

    snprintf(buf, sizeof buf, "%s:%d", service, sz);
    fd = adb_connect(buf);
    if(fd < 0) {
        fprintf(stderr,"error: %s\n", adb_error());
        return -1;
    }

    adb_socket_setbufsize(fd, CHUNK_SIZE);

    total = sz;
    ptr = data;

    if(progress) {
        char *x = strrchr(service, ':');
        if(x) service = x + 1;
    }

    while(sz > 0) {
        unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
        if(writex(fd, ptr, xfer)) {
            adb_status(fd);
            fprintf(stderr,"* failed to write data '%s' *\n", adb_error());
            return -1;
        }
        sz -= xfer;
        ptr += xfer;
        if(progress) {
            int percent = 100 - (int)(100.0 * ((float)sz / (float)total));
            printf("sending: '%s' %4d%%    \r", service, percent);
            fflush(stdout);
        }
    }
    if(progress) {
        printf("\n");
    }

    if(readx(fd, buf, 4)){
        fprintf(stderr,"* error reading response *\n");
        adb_close(fd);
        return -1;
    }
    if(memcmp(buf, "OKAY", 4)) {
        buf[4] = 0;
        fprintf(stderr,"* error response '%s' *\n", buf);
        adb_close(fd);
        return -1;
    }

    adb_close(fd);
    return 0;
}


int adb_download(const char *service, const char *fn, unsigned progress)
{
    void *data;
    unsigned sz;

    data = load_file(fn, &sz);
    if(data == 0) {
        fprintf(stderr,"* cannot read '%s' *\n", service);
        return -1;
    }

    return adb_download_buffer(service, data, sz, progress);
}

static void format_host_command(char* buffer, size_t  buflen, const char* command, transport_type ttype, const char* serial)
{
    if (serial) {
@@ -678,13 +601,6 @@ static int logcat(transport_type transport, char* serial, int argc, char **argv)
    return 0;
}

int adb_download_data(const char *what, const void* data, int sz, unsigned progress)
{
    char service[4096];
    snprintf(service, sizeof service, "bootloader:flash:%s", what);
    return adb_download_buffer(service, data, sz, 1);
}

#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
static int top_works(const char *top)
{
@@ -977,32 +893,6 @@ top:
        }
    }

    if(!strcmp(argv[0], "debug")) {
        int fd = adb_connect("bootdebug:");
        if(fd >= 0) {
            read_and_dump(fd);
            adb_close(fd);
            return 0;
        }
        fprintf(stderr,"error: %s\n", adb_error());
        return 1;
    }

    if(!strcmp(argv[0], "bl")) {
        int fd;
        if(argc != 2) return usage();
        snprintf(buf, sizeof buf, "bootloader:%s", argv[1]);
        fd = adb_connect(buf);
        if(fd >= 0) {
            read_and_dump(fd);
            adb_close(fd);
            return 0;
        } else {
            fprintf(stderr,"* command failed: %s *\n", adb_error());
        }
        return 1;
    }

    if(!strcmp(argv[0], "kill-server")) {
        int fd;
        fd = _adb_connect("host:kill");
@@ -1024,27 +914,6 @@ top:
        return 1;
    }

    /* adb_download() commands */

    if(!strcmp(argv[0], "send")) {
        if(argc != 3) return usage();
        snprintf(buf, sizeof buf, "bootloader:send:%s", argv[1]);
        if(adb_download(buf, argv[2], 1)) {
            return 1;
        } else {
            return 0;
        }
    }

    if(!strcmp(argv[0], "recover")) {
        if(argc != 2) return usage();
        if(adb_download("recover", argv[1], 1)) {
            return 1;
        } else {
            return 0;
        }
    }

    if(!strcmp(argv[0], "bugreport")) {
        if (argc != 1) {
            return 1;
@@ -1057,9 +926,7 @@ top:

    if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
        char* service = argv[0];
        if (!strncmp(service, "wait-for-bootloader", strlen("wait-for-bootloader"))) {
            fprintf(stderr,"WAIT FOR BOOTLOADER\n");
        } else if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
            if (ttype == kTransportUsb) {
                service = "wait-for-usb";
            } else if (ttype == kTransportLocal) {
@@ -1157,7 +1024,6 @@ top:
    /* passthrough commands */

    if(!strcmp(argv[0],"get-state") ||
        !strcmp(argv[0],"get-product") ||
        !strcmp(argv[0],"get-serialno"))
    {
        char *tmp;

adb/kdbg.c

deleted100644 → 0
+0 −474
Original line number Diff line number Diff line
/*
 * 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 _GNU_SOURCE
#include <stdio.h>

#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <ctype.h>

#include <linux/usbdevice_fs.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
#include <linux/usb/ch9.h>
#else
#include <linux/usb_ch9.h>
#endif
#include <asm/byteorder.h>

#include <cutils/fdevent.h>
#include "adb.h"


#define TRACE_USB 0

#if TRACE_USB
#define DBG1(x...) fprintf(stderr, x)
#define DBG(x...) fprintf(stderr, x)
#else
#define DBG(x...)
#define DBG1(x...)
#endif

struct usb_handle
{
    struct usb_handle *next;
    char fname[32];
    int desc;
    unsigned char ep_in;
    unsigned char ep_out;
    unsigned int interface;
};

static struct usb_handle *g_first_usb_device;
static struct usb_handle *g_last_usb_device;

static void new_device(char *dev_name, unsigned char ep_in, unsigned char ep_out, unsigned int interface)
{
    struct usb_handle* usb;

    DBG("New device being added %s \n", dev_name);

    usb = (struct usb_handle *)calloc(1, sizeof(struct usb_handle));
    strcpy(usb->fname, dev_name);
    usb->ep_in = ep_in;
    usb->ep_out = ep_out;
    usb->interface = interface;
    usb->next = NULL;
    if(g_last_usb_device)
        g_last_usb_device->next = usb;
    else
        g_first_usb_device = usb;
    g_last_usb_device = usb;
}


static inline int badname(const char *name)
{
    if(!isdigit(name[0])) return 1;
    if(!isdigit(name[1])) return 1;
    if(!isdigit(name[2])) return 1;
    if(name[3] != 0) return 1;
    return 0;
}

static int find_usb_devices(const char *base, unsigned vendor, unsigned product1, unsigned product2,
                            unsigned ifclass, unsigned ifsubclass,
                            unsigned ifprotocol, unsigned numendpoints)
{
    char busname[32], devname[32];
    unsigned char local_ep_in, local_ep_out;
    DIR *busdir , *devdir ;
    struct dirent *de;
    int fd ;
    int ret_val = -1;
    int found_device = 0;

    busdir = opendir(base);
    if(busdir == 0) return 0;

    while((de = readdir(busdir)) != 0) {
        if(badname(de->d_name)) continue;

        snprintf(busname, sizeof busname, "%s/%s", base, de->d_name);
        devdir = opendir(busname);
        if(devdir == 0) continue;

        DBG("[ scanning %s ]\n", busname);
        while((de = readdir(devdir))) {
            if(badname(de->d_name)) continue;
            snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name);

            DBG("[ scanning %s ]\n", devname);
            fd = open(devname, O_RDWR);
            if(fd < 0) {
                continue;
            } else {
                unsigned char devdesc[256];
                unsigned char* bufptr = devdesc;
                struct usb_device_descriptor* device;
                struct usb_config_descriptor* config;
                struct usb_interface_descriptor* interface;
                struct usb_endpoint_descriptor *ep1, *ep2;
                unsigned vid, pid;
                int i, interfaces;

                size_t desclength = read(fd, devdesc, sizeof(devdesc));

                // should have device and configuration descriptors, and atleast two endpoints
                if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) {
                    DBG("desclength %d is too small\n", desclength);
                    close(fd);
                    continue;
                }

                device = (struct usb_device_descriptor*)bufptr;
                bufptr += USB_DT_DEVICE_SIZE;
                if(device->bLength == USB_DT_DEVICE_SIZE && device->bDescriptorType == USB_DT_DEVICE) {
                    vid = __le16_to_cpu(device->idVendor);
                    pid = __le16_to_cpu(device->idProduct);
                    pid = devdesc[10] | (devdesc[11] << 8);
                    DBG("[ %s is V:%04x P:%04x ]\n", devname, vid, pid);
                    if((vendor == vid) && (product1 == pid || product2 == pid)){

                       // should have config descriptor next
                       config = (struct usb_config_descriptor *)bufptr;
                       bufptr += USB_DT_CONFIG_SIZE;
                       if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) {
                            DBG("usb_config_descriptor not found\n");
                            close(fd);
                            continue;
                           }

                           // loop through all the interfaces and look for the ADB interface
                           interfaces = config->bNumInterfaces;
                           for (i = 0; i < interfaces; i++) {
                              if (bufptr + USB_DT_ENDPOINT_SIZE > devdesc + desclength)
                                 break;

                              interface = (struct usb_interface_descriptor *)bufptr;
                              bufptr += USB_DT_INTERFACE_SIZE;
                              if (interface->bLength != USB_DT_INTERFACE_SIZE ||
                              interface->bDescriptorType != USB_DT_INTERFACE) {
                              DBG("usb_interface_descriptor not found\n");
                                  break;
                              }

                          DBG("bInterfaceClass: %d,  bInterfaceSubClass: %d,\
                              bInterfaceProtocol: %d, bNumEndpoints: %d\n",
                              interface->bInterfaceClass, interface->bInterfaceSubClass,
                              interface->bInterfaceProtocol, interface->bNumEndpoints);
                          // Sooner bootloader has zero for bInterfaceClass, while adb has USB_CLASS_CDC_DATA
                              if (interface->bInterfaceClass == ifclass &&
                                   interface->bInterfaceSubClass == ifsubclass &&
                                   interface->bInterfaceProtocol == ifprotocol &&
                                   interface->bNumEndpoints == numendpoints) {

                                   DBG("looking for bulk endpoints\n");
                                   // looks like ADB...
                                   ep1 = (struct usb_endpoint_descriptor *)bufptr;
                                   bufptr += USB_DT_ENDPOINT_SIZE;
                                   ep2 = (struct usb_endpoint_descriptor *)bufptr;
                                   bufptr += USB_DT_ENDPOINT_SIZE;

                                   if (bufptr > devdesc + desclength ||
                                       ep1->bLength != USB_DT_ENDPOINT_SIZE ||
                                       ep1->bDescriptorType != USB_DT_ENDPOINT ||
                                       ep2->bLength != USB_DT_ENDPOINT_SIZE ||
                                       ep2->bDescriptorType != USB_DT_ENDPOINT) {
                                       DBG("endpoints not found\n");
                                       break;
                                  }

                                  // both endpoints should be bulk
                                  if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK ||
                                     ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) {
                                      DBG("bulk endpoints not found\n");
                                      continue;
                                  }

                                  // we have a match.  now we just need to figure out which is in and which is out.
                                  if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
                                      local_ep_in = ep1->bEndpointAddress;
                                      local_ep_out = ep2->bEndpointAddress;
                                  } else {
                                      local_ep_in = ep2->bEndpointAddress;
                                      local_ep_out = ep1->bEndpointAddress;
                                  }

                                  new_device(devname, local_ep_in, local_ep_out, i);
                                  found_device = 1;
                                  close(fd);
                              } else {
                                  // skip to next interface
                                  bufptr += (interface->bNumEndpoints * USB_DT_ENDPOINT_SIZE);
                              }
                          } // end of for
                    } //end of productid if
                }
                close(fd);
            } // end of if
        } // end of devdir while
        closedir(devdir);
    } //end of busdir while
    closedir(busdir);

    return found_device;
}


static void find_devices(unsigned vendor, unsigned product1, unsigned product2)
{
    // don't scan /proc/bus/usb if we find something in /dev/bus/usb, to avoid duplication of devices.
    if (!find_usb_devices("/dev/bus/usb", vendor, product1, product2, USB_CLASS_VENDOR_SPEC, 1, 0, 2)) {
        find_usb_devices("/proc/bus/usb", vendor, product1, product2, USB_CLASS_VENDOR_SPEC, 1, 0, 2);
    }
}

void usb_open_device(struct usb_handle *h)
{
    int n = 0;

    h->desc = open(h->fname, O_RDWR);
    //DBG("[ usb open %s fd = %d]\n", h->fname, h->desc);
    n = ioctl(h->desc, USBDEVFS_CLAIMINTERFACE, &h->interface);
    if(n != 0) goto fail;
//    t->usb_is_open = 1;
    return;


fail:
    DBG("[ usb open %s error=%d, err_str = %s]\n",
                h->fname,  errno, strerror(errno));
    if(h->desc >= 0) {
        close(h->desc);
        h->desc = -1;
    }
//    t->usb_is_open = 0;
}

int usb_write(struct usb_handle *h, const void *_data, int len)
{
    unsigned char *data = (unsigned char*) _data;
    struct usbdevfs_bulktransfer bulk;
    int n;

    while(len >= 0) {
        int xfer = (len > 4096) ? 4096 : len;

        bulk.ep = h->ep_out;
        bulk.len = xfer;
        bulk.data = data;
        bulk.timeout = 500 + xfer * 8;

        bulk.timeout *= 10;

        n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
        if(n != xfer) {
            DBG("ERROR: n = %d, errno = %d (%s)\n",
                n, errno, strerror(errno));
            return -1;
        }
        if(len == 0)
            break;

        len -= xfer;
        data += xfer;
        if(len == 0)
            break;
    }

    return 0;
}

int usb_read(struct usb_handle *h, void *_data, int len)
{
    unsigned char *data_start = (unsigned char*) _data;
    unsigned char *data = (unsigned char*) _data;
    struct usbdevfs_bulktransfer bulk;
    int n;

    while(len > 0) {
        int xfer = (len > 4096) ? 4096 : len;

        bulk.ep = h->ep_in;
        bulk.len = xfer;
        bulk.data = data;

            // adjust timeout based on the data we're transferring,
            // otherwise the timeout interrupts us partway through
            // and we get out of sync...
        bulk.timeout = 500 + xfer * 8;

        bulk.timeout = 500 + xfer / 128;

//        bulk.timeout *= 10;
        DBG1("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname);
        n = ioctl(h->desc, USBDEVFS_BULK, &bulk);
        DBG1("[ usb read %d ] = %d, fname=%s\n", xfer, n, h->fname);
        if(n < 0) {
            if((errno == ETIMEDOUT) && (h->desc != -1)) {
                DBG("[ timeout ]\n");
                if(n > 0){
                    data += n;
                    len -= n;
                }
                continue;
            }
            DBG1("ERROR: n = %d, errno = %d (%s)\n",
                n, errno, strerror(errno));
            return -1;
        }

        len -= n;
        data += n;
        if(n != xfer)
            break;
    }

    return data - data_start;
}

void usb_kick(struct usb_handle *h)
{
    close(h->desc);
    h->desc = -1;
}

int usb_close(struct usb_handle *h)
{
    close(h->desc);
    h->desc = -1;
    return 0;
}

void list_devices()
{
    int i = 0;
    struct usb_handle *h = g_first_usb_device;
    while(h) {
        printf("%d: %s\n", i, h->fname);
        i++;
        h = h->next;
    }
}

int main(int argc, char **argv)
{
    char buffer[4096/*-64*/];
    int len;
    int c;
    char *arg;
    int device_index = 0;
    struct usb_handle *h;
    int i;

    find_devices(VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER, PRODUCT_ID_SOONER_COMP);
    while(1) {
        c = getopt(argc, argv, "d:l");
        if (c == EOF)
            break;
        switch(c) {
            case 'd':
                device_index = strtol(optarg, NULL, 0);
                break;
            case 'l':
                list_devices();
                return 0;
            case '?':
                fprintf(stderr, "%s: invalid option -%c\n",
                        argv[0], optopt);
                return 1;
        }
    }

    argc -= optind - 1;
    argv += optind - 1;

    h = g_first_usb_device;
    i = device_index;
    while(i-- > 0 && h) {
        h = h->next;
    }
    if(h == NULL) {
        fprintf(stderr, "no device %d\n", device_index);
        return 1;
    }

    usb_open_device(h);
    if(g_first_usb_device->desc < 0) {
        fprintf(stderr, "could not open device (%s), %s\n", h->fname, strerror(errno));
        return 1;
    }
    len = 0;
    if(argc == 1) {
        char *line = NULL;
        size_t line_size = 0;
        while((len = getline(&line, &line_size, stdin)) >= 0) {
            //if(len > 0 && line[len - 1] == '\n')
            //  len--;
            usb_write(h, line, len);
            while(1) {
                len = usb_read(h, buffer, sizeof(buffer));
                if(len < 0)
                    break;
                write(STDOUT_FILENO, buffer, len);
                if(len < (int)sizeof(buffer))
                    break;
            }
        }
        return 0;
    }
    while(argc > 1) {
        argc--;
        argv++;
        arg = *argv;
        while(arg) {
            if(*arg)
                buffer[len++] = *arg++;
            else {
                arg = NULL;
                if(argc > 1)
                    buffer[len++] = ' ';
                else
                    break;
            }
            if(len == sizeof(buffer)) {
                usb_write(h, buffer, len);
                len = 0;
            }
        }
    }
    usb_write(h, buffer, len);
    while(1) {
        len = usb_read(h, buffer, sizeof(buffer));
        if(len < 0)
            break;
        write(STDOUT_FILENO, buffer, len);
        if(len < (int)sizeof(buffer))
            break;
    }
    return 0;
}
Loading