1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * All rights reserved.
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met:
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Redistributions of source code must retain the above copyright
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
125ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau *    the documentation and/or other materials provided with the
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    distribution.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
225ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE.
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <windows.h>
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <winerror.h>
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <usb100.h>
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <adb_api.h>
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
350eabf64ce0c649e4ef691ae1b70cb20d599dd429Christopher Ferris#include <stdlib.h>
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "usb.h"
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//#define TRACE_USB 1
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if TRACE_USB
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DBG(x...) fprintf(stderr, x)
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DBG(x...)
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
46913eb8bf874fcec647667bd7113da65b6e38488aDavid Krause#define MAX_USBFS_BULK_SIZE (1024 * 1024)
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** Structure usb_handle describes our connection to the usb device via
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project  AdbWinApi.dll. This structure is returned from usb_open() routine and
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project  is expected in each subsequent call that is accessing the device.
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct usb_handle {
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /// Handle to USB interface
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ADBAPIHANDLE  adb_interface;
555ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /// Handle to USB read pipe (endpoint)
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ADBAPIHANDLE  adb_read_pipe;
585ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /// Handle to USB write pipe (endpoint)
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ADBAPIHANDLE  adb_write_pipe;
615ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /// Interface name
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char*         interface_name;
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Class ID assigned to the device by androidusb.sys
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const GUID usb_class_id = ANDROID_USB_CLASS_ID;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Checks if interface (device) matches certain criteria
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint recognized_device(usb_handle* handle, ifc_match_func callback);
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Opens usb interface (device) by interface (device) name.
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle* do_usb_open(const wchar_t* interface_name);
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Writes data to the opened usb handle
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_write(usb_handle* handle, const void* data, int len);
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Reads data using the opened usb handle
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *handle, void* data, int len);
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Cleans up opened usb handle
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup_handle(usb_handle* handle);
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Cleans up (but don't close) opened usb handle
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle* handle);
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Closes opened usb handle
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle* handle);
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle* do_usb_open(const wchar_t* interface_name) {
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Allocate our handle
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle));
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL == ret)
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Create interface.
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret->adb_interface = AdbCreateInterfaceByName(interface_name);
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL == ret->adb_interface) {
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(ret);
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = GetLastError();
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Open read pipe (endpoint)
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret->adb_read_pipe =
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        AdbOpenDefaultBulkReadEndpoint(ret->adb_interface,
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                   AdbOpenAccessTypeReadWrite,
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                   AdbOpenSharingModeReadWrite);
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL != ret->adb_read_pipe) {
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // Open write pipe (endpoint)
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret->adb_write_pipe =
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface,
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                      AdbOpenAccessTypeReadWrite,
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                      AdbOpenSharingModeReadWrite);
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (NULL != ret->adb_write_pipe) {
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // Save interface name
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            unsigned long name_len = 0;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // First get expected name length
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            AdbGetInterfaceName(ret->adb_interface,
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                          NULL,
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                          &name_len,
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                          true);
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (0 != name_len) {
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ret->interface_name = (char*)malloc(name_len);
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (NULL != ret->interface_name) {
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    // Now save the name
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if (AdbGetInterfaceName(ret->adb_interface,
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                  ret->interface_name,
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                  &name_len,
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                  true)) {
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        // We're done at this point
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        return ret;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } else {
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    SetLastError(ERROR_OUTOFMEMORY);
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Something went wrong.
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    errno = GetLastError();
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    usb_cleanup_handle(ret);
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(ret);
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SetLastError(errno);
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return NULL;
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_write(usb_handle* handle, const void* data, int len) {
156bbb7981e49048a657d724bfda9465cdfe7c03a87Jiebing Li    unsigned long time_out = 5000;
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned long written = 0;
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned count = 0;
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ret;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DBG("usb_write %d\n", len);
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL != handle) {
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // Perform write
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while(len > 0) {
165913eb8bf874fcec647667bd7113da65b6e38488aDavid Krause            int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ret = AdbWriteEndpointSync(handle->adb_write_pipe,
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                   (void*)data,
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                   (unsigned long)xfer,
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                   &written,
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                   time_out);
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = GetLastError();
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DBG("AdbWriteEndpointSync returned %d, errno: %d\n", ret, errno);
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ret == 0) {
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // assume ERROR_INVALID_HANDLE indicates we are disconnected
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (errno == ERROR_INVALID_HANDLE)
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                usb_kick(handle);
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            count += written;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            len -= written;
1825957c1ffe79b34d8b1859f9f11644d1007193cbcMark Salyzyn            data = (const char *)data + written;
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (len == 0)
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return count;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        DBG("usb_write NULL handle\n");
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetLastError(ERROR_INVALID_HANDLE);
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DBG("usb_write failed: %d\n", errno);
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *handle, void* data, int len) {
198bbb7981e49048a657d724bfda9465cdfe7c03a87Jiebing Li    unsigned long time_out = 0;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned long read = 0;
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int ret;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DBG("usb_read %d\n", len);
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL != handle) {
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while (1) {
205913eb8bf874fcec647667bd7113da65b6e38488aDavid Krause            int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	        ret = AdbReadEndpointSync(handle->adb_read_pipe,
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	                              (void*)data,
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	                              (unsigned long)xfer,
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	                              &read,
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	                              time_out);
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = GetLastError();
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno);
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ret) {
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return read;
216bbb7981e49048a657d724bfda9465cdfe7c03a87Jiebing Li            } else {
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // assume ERROR_INVALID_HANDLE indicates we are disconnected
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (errno == ERROR_INVALID_HANDLE)
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    usb_kick(handle);
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // else we timed out - try again
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        DBG("usb_read NULL handle\n");
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetLastError(ERROR_INVALID_HANDLE);
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DBG("usb_read failed: %d\n", errno);
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup_handle(usb_handle* handle) {
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL != handle) {
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (NULL != handle->interface_name)
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(handle->interface_name);
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (NULL != handle->adb_write_pipe)
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            AdbCloseHandle(handle->adb_write_pipe);
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (NULL != handle->adb_read_pipe)
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            AdbCloseHandle(handle->adb_read_pipe);
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (NULL != handle->adb_interface)
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            AdbCloseHandle(handle->adb_interface);
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        handle->interface_name = NULL;
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        handle->adb_write_pipe = NULL;
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        handle->adb_read_pipe = NULL;
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        handle->adb_interface = NULL;
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle* handle) {
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL != handle) {
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        usb_cleanup_handle(handle);
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetLastError(ERROR_INVALID_HANDLE);
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = ERROR_INVALID_HANDLE;
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle* handle) {
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DBG("usb_close\n");
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL != handle) {
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // Cleanup handle
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        usb_cleanup_handle(handle);
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(handle);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
273157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachslerint usb_wait_for_disconnect(usb_handle *usb) {
274157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler    /* TODO: Punt for now */
275157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler    return 0;
276157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler}
277157b00171a06f9ac2fd25ee3a86e801e896713d6Mark Wachsler
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint recognized_device(usb_handle* handle, ifc_match_func callback) {
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct usb_ifc_info info;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    USB_DEVICE_DESCRIPTOR device_desc;
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    USB_INTERFACE_DESCRIPTOR interf_desc;
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL == handle)
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Check vendor and product id first
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!AdbGetUsbDeviceDescriptor(handle->adb_interface,
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                 &device_desc)) {
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Then check interface properties
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface,
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                    &interf_desc)) {
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Must have two endpoints
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (2 != interf_desc.bNumEndpoints) {
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.dev_vendor = device_desc.idVendor;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.dev_product = device_desc.idProduct;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.dev_class = device_desc.bDeviceClass;
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.dev_subclass = device_desc.bDeviceSubClass;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.dev_protocol = device_desc.bDeviceProtocol;
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.ifc_class = interf_desc.bInterfaceClass;
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.ifc_subclass = interf_desc.bInterfaceSubClass;
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    info.ifc_protocol = interf_desc.bInterfaceProtocol;
311b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes    info.writable = 1;
3125ae3f93f3bafbeb1fc9a3324475c58c725749c5eAnatol Pomazau
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // read serial number (if there is one)
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned long serial_number_len = sizeof(info.serial_number);
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!AdbGetSerialNumber(handle->adb_interface, info.serial_number,
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    &serial_number_len, true)) {
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        info.serial_number[0] = 0;
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
32013081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson    info.device_path[0] = 0;
32113081c6915220db03886b177f1a8e0b2c63467c9Scott Anderson
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (callback(&info) == 0) {
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic usb_handle *find_usb_device(ifc_match_func callback) {
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	usb_handle* handle = NULL;
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char entry_buffer[2048];
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char interf_name[2048];
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned long entry_buffer_size = sizeof(entry_buffer);
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* copy_name;
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Enumerate all present and active interfaces.
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ADBAPIHANDLE enum_handle =
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        AdbEnumInterfaces(usb_class_id, true, true, true);
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (NULL == enum_handle)
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) {
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // TODO(vchtchetkine): FIXME - temp hack converting wchar_t into char.
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // It would be better to change AdbNextInterface so it will return
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // interface name as single char string.
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const wchar_t* wchar_name = next_interface->device_name;
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for(copy_name = interf_name;
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                L'\0' != *wchar_name;
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                wchar_name++, copy_name++) {
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *copy_name = (char)(*wchar_name);
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *copy_name = '\0';
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        handle = do_usb_open(next_interface->device_name);
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (NULL != handle) {
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // Lets see if this interface (device) belongs to us
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (recognized_device(handle, callback)) {
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                // found it!
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                usb_cleanup_handle(handle);
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                free(handle);
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                handle = NULL;
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        entry_buffer_size = sizeof(entry_buffer);
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    AdbCloseHandle(enum_handle);
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return handle;
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle *usb_open(ifc_match_func callback)
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return find_usb_device(callback);
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// called from fastboot.c
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid sleep(int seconds)
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    Sleep(seconds * 1000);
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
386