usb_windows.c revision b4add9b74525210478bac702d27fdaf9cf7ab18f
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 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 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 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 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> 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "usb.h" 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//#define TRACE_USB 1 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if TRACE_USB 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DBG(x...) fprintf(stderr, x) 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DBG(x...) 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** Structure usb_handle describes our connection to the usb device via 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbWinApi.dll. This structure is returned from usb_open() routine and 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is expected in each subsequent call that is accessing the device. 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct usb_handle { 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Handle to USB interface 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE adb_interface; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Handle to USB read pipe (endpoint) 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE adb_read_pipe; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Handle to USB write pipe (endpoint) 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE adb_write_pipe; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Interface name 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* interface_name; 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Class ID assigned to the device by androidusb.sys 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const GUID usb_class_id = ANDROID_USB_CLASS_ID; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Checks if interface (device) matches certain criteria 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint recognized_device(usb_handle* handle, ifc_match_func callback); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Opens usb interface (device) by interface (device) name. 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle* do_usb_open(const wchar_t* interface_name); 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Writes data to the opened usb handle 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_write(usb_handle* handle, const void* data, int len); 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Reads data using the opened usb handle 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *handle, void* data, int len); 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Cleans up opened usb handle 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup_handle(usb_handle* handle); 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Cleans up (but don't close) opened usb handle 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle* handle); 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Closes opened usb handle 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle* handle); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle* do_usb_open(const wchar_t* interface_name) { 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Allocate our handle 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle)); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == ret) 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Create interface. 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->adb_interface = AdbCreateInterfaceByName(interface_name); 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == ret->adb_interface) { 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(ret); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Open read pipe (endpoint) 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->adb_read_pipe = 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenDefaultBulkReadEndpoint(ret->adb_interface, 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenAccessTypeReadWrite, 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenSharingModeReadWrite); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != ret->adb_read_pipe) { 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Open write pipe (endpoint) 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->adb_write_pipe = 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface, 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenAccessTypeReadWrite, 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenSharingModeReadWrite); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != ret->adb_write_pipe) { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Save interface name 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long name_len = 0; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // First get expected name length 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbGetInterfaceName(ret->adb_interface, 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &name_len, 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project true); 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (0 != name_len) { 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->interface_name = (char*)malloc(name_len); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != ret->interface_name) { 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Now save the name 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (AdbGetInterfaceName(ret->adb_interface, 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->interface_name, 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &name_len, 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project true)) { 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // We're done at this point 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_OUTOFMEMORY); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Something went wrong. 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(ret); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(ret); 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(errno); 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_write(usb_handle* handle, const void* data, int len) { 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long time_out = 500 + len * 8; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long written = 0; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count = 0; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_write %d\n", len); 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Perform write 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(len > 0) { 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int xfer = (len > 4096) ? 4096 : len; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = AdbWriteEndpointSync(handle->adb_write_pipe, 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void*)data, 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (unsigned long)xfer, 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &written, 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_out); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("AdbWriteEndpointSync returned %d, errno: %d\n", ret, errno); 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret == 0) { 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // assume ERROR_INVALID_HANDLE indicates we are disconnected 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == ERROR_INVALID_HANDLE) 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_kick(handle); 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count += written; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= written; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data += written; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len == 0) 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return count; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_write NULL handle\n"); 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_write failed: %d\n", errno); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *handle, void* data, int len) { 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long time_out = 500 + len * 8; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long read = 0; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_read %d\n", len); 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (1) { 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int xfer = (len > 4096) ? 4096 : len; 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = AdbReadEndpointSync(handle->adb_read_pipe, 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void*)data, 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (unsigned long)xfer, 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &read, 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_out); 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret) { 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return read; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (errno != ERROR_SEM_TIMEOUT) { 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // assume ERROR_INVALID_HANDLE indicates we are disconnected 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == ERROR_INVALID_HANDLE) 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_kick(handle); 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // else we timed out - try again 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_read NULL handle\n"); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_read failed: %d\n", errno); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup_handle(usb_handle* handle) { 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->interface_name) 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle->interface_name); 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_write_pipe) 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_write_pipe); 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_read_pipe) 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_read_pipe); 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_interface) 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_interface); 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->interface_name = NULL; 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_write_pipe = NULL; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_read_pipe = NULL; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_interface = NULL; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle* handle) { 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = ERROR_INVALID_HANDLE; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle* handle) { 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DBG("usb_close\n"); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Cleanup handle 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint recognized_device(usb_handle* handle, ifc_match_func callback) { 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct usb_ifc_info info; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project USB_DEVICE_DESCRIPTOR device_desc; 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project USB_INTERFACE_DESCRIPTOR interf_desc; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == handle) 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Check vendor and product id first 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &device_desc)) { 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Then check interface properties 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &interf_desc)) { 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Must have two endpoints 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (2 != interf_desc.bNumEndpoints) { 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.dev_vendor = device_desc.idVendor; 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.dev_product = device_desc.idProduct; 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.dev_class = device_desc.bDeviceClass; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.dev_subclass = device_desc.bDeviceSubClass; 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.dev_protocol = device_desc.bDeviceProtocol; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.ifc_class = interf_desc.bInterfaceClass; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.ifc_subclass = interf_desc.bInterfaceSubClass; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.ifc_protocol = interf_desc.bInterfaceProtocol; 304b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes info.writable = 1; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // read serial number (if there is one) 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long serial_number_len = sizeof(info.serial_number); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!AdbGetSerialNumber(handle->adb_interface, info.serial_number, 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &serial_number_len, true)) { 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project info.serial_number[0] = 0; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (callback(&info) == 0) { 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic usb_handle *find_usb_device(ifc_match_func callback) { 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_handle* handle = NULL; 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char entry_buffer[2048]; 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char interf_name[2048]; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long entry_buffer_size = sizeof(entry_buffer); 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* copy_name; 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Enumerate all present and active interfaces. 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE enum_handle = 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbEnumInterfaces(usb_class_id, true, true, true); 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == enum_handle) 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // TODO(vchtchetkine): FIXME - temp hack converting wchar_t into char. 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // It would be better to change AdbNextInterface so it will return 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // interface name as single char string. 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const wchar_t* wchar_name = next_interface->device_name; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(copy_name = interf_name; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project L'\0' != *wchar_name; 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wchar_name++, copy_name++) { 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *copy_name = (char)(*wchar_name); 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *copy_name = '\0'; 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle = do_usb_open(next_interface->device_name); 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Lets see if this interface (device) belongs to us 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (recognized_device(handle, callback)) { 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // found it! 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle = NULL; 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry_buffer_size = sizeof(entry_buffer); 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(enum_handle); 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return handle; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle *usb_open(ifc_match_func callback) 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return find_usb_device(callback); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// called from fastboot.c 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid sleep(int seconds) 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Sleep(seconds * 1000); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 377