usb_windows.c revision f6330a2eeb78c0971f33feee7fd1ee06472a7dba
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <windows.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <winerror.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <usb100.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <adb_api.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_USB 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** Structure usb_handle describes our connection to the usb device via 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbWinApi.dll. This structure is returned from usb_open() routine and 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is expected in each subsequent call that is accessing the device. 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct usb_handle { 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Previous entry in the list of opened usb handles 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_handle *prev; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Next entry in the list of opened usb handles 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_handle *next; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Handle to USB interface 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE adb_interface; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Handle to USB read pipe (endpoint) 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE adb_read_pipe; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Handle to USB write pipe (endpoint) 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE adb_write_pipe; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Interface name 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* interface_name; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /// Mask for determining when to use zero length packets 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned zero_mask; 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Class ID assigned to the device by androidusb.sys 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const GUID usb_class_id = ANDROID_USB_CLASS_ID; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// List of opened usb handles 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic usb_handle handle_list = { 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .prev = &handle_list, 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .next = &handle_list, 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Locker for the list of opened usb handles 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectADB_MUTEX_DEFINE( usb_lock ); 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Checks if there is opened usb handle in handle_list for this device. 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint known_device(const char* dev_name); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Checks if there is opened usb handle in handle_list for this device. 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// usb_lock mutex must be held before calling this routine. 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint known_device_locked(const char* dev_name); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Registers opened usb handle (adds it to handle_list). 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint register_new_device(usb_handle* handle); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Checks if interface (device) matches certain criteria 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint recognized_device(usb_handle* handle); 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Enumerates present and available interfaces (devices), opens new ones and 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// registers usb transport for them. 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid find_devices(); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Entry point for thread that polls (every second) for new usb interfaces. 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// This routine calls find_devices in infinite loop. 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid* device_poll_thread(void* unused); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Initializes this module 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_init(); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Cleans up this module 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup(); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Opens usb interface (device) by interface (device) name. 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle* do_usb_open(const wchar_t* interface_name); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Writes data to the opened usb handle 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_write(usb_handle* handle, const void* data, int len); 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Reads data using the opened usb handle 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *handle, void* data, int len); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Cleans up opened usb handle 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup_handle(usb_handle* handle); 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Cleans up (but don't close) opened usb handle 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle* handle); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Closes opened usb handle 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle* handle); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/// Gets interface (device) name for an opened usb handle 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *usb_name(usb_handle* handle); 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint known_device_locked(const char* dev_name) { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_handle* usb; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != dev_name) { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Iterate through the list looking for the name match. 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(usb = handle_list.next; usb != &handle_list; usb = usb->next) { 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // In Windows names are not case sensetive! 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((NULL != usb->interface_name) && 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (0 == stricmp(usb->interface_name, dev_name))) { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint known_device(const char* dev_name) { 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret = 0; 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != dev_name) { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&usb_lock); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = known_device_locked(dev_name); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb_lock); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint register_new_device(usb_handle* handle) { 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == handle) 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&usb_lock); 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Check if device is already in the list 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (known_device_locked(handle->interface_name)) { 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb_lock); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Not in the list. Add this handle to the list. 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->next = &handle_list; 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->prev = handle_list.prev; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->prev->next = handle; 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->next->prev = handle; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb_lock); 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid* device_poll_thread(void* unused) { 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("Created device thread\n"); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(1) { 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project find_devices(); 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_sleep_ms(1000); 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_init() { 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t tid; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_thread_create(&tid, device_poll_thread, NULL)) { 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fatal_errno("cannot create input thread"); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup() { 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusb_handle* do_usb_open(const wchar_t* interface_name) { 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Allocate our handle 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle)); 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == ret) 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Set linkers back to the handle 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->next = ret; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->prev = ret; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Create interface. 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->adb_interface = AdbCreateInterfaceByName(interface_name); 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == ret->adb_interface) { 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(ret); 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Open read pipe (endpoint) 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->adb_read_pipe = 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenDefaultBulkReadEndpoint(ret->adb_interface, 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenAccessTypeReadWrite, 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenSharingModeReadWrite); 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != ret->adb_read_pipe) { 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Open write pipe (endpoint) 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->adb_write_pipe = 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface, 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenAccessTypeReadWrite, 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbOpenSharingModeReadWrite); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != ret->adb_write_pipe) { 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Save interface name 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long name_len = 0; 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // First get expected name length 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbGetInterfaceName(ret->adb_interface, 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &name_len, 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project true); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (0 != name_len) { 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->interface_name = (char*)malloc(name_len); 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != ret->interface_name) { 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Now save the name 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (AdbGetInterfaceName(ret->adb_interface, 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret->interface_name, 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &name_len, 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project true)) { 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // We're done at this point 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_OUTOFMEMORY); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Something went wrong. 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(ret); 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(ret); 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(errno); 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_write(usb_handle* handle, const void* data, int len) { 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long time_out = 500 + len * 8; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long written = 0; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_write %d\n", len); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Perform write 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = AdbWriteEndpointSync(handle->adb_write_pipe, 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void*)data, 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (unsigned long)len, 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &written, 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_out); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret) { 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Make sure that we've written what we were asked to write 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_write got: %ld, expected: %d\n", written, len); 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (written == (unsigned long)len) { 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(handle->zero_mask && (len & handle->zero_mask) == 0) { 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Send a zero length packet 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbWriteEndpointSync(handle->adb_write_pipe, 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void*)data, 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 0, 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &written, 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_out); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // assume ERROR_INVALID_HANDLE indicates we are disconnected 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == ERROR_INVALID_HANDLE) 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_kick(handle); 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_write NULL handle\n"); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_write failed: %d\n", errno); 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *handle, void* data, int len) { 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long time_out = 500 + len * 8; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long read = 0; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_read %d\n", len); 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (len > 0) { 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int xfer = (len > 4096) ? 4096 : len; 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = AdbReadEndpointSync(handle->adb_read_pipe, 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void*)data, 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (unsigned long)xfer, 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &read, 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_out); 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = GetLastError(); 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, errno); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret) { 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data += read; 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= read; 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len == 0) 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (errno != ERROR_SEM_TIMEOUT) { 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // assume ERROR_INVALID_HANDLE indicates we are disconnected 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (errno == ERROR_INVALID_HANDLE) 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_kick(handle); 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_read NULL handle\n"); 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_read failed: %d\n", errno); 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup_handle(usb_handle* handle) { 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->interface_name) 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle->interface_name); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_write_pipe) 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_write_pipe); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_read_pipe) 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_read_pipe); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_interface) 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_interface); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->interface_name = NULL; 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_write_pipe = NULL; 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_read_pipe = NULL; 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_interface = NULL; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle* handle) { 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&usb_lock); 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb_lock); 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = ERROR_INVALID_HANDLE; 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle* handle) { 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_close\n"); 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Remove handle from the list 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&usb_lock); 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((handle->next != handle) && (handle->prev != handle)) { 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->next->prev = handle->prev; 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->prev->next = handle->next; 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->prev = handle; 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->next = handle; 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb_lock); 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Cleanup handle 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *usb_name(usb_handle* handle) { 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == handle) { 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = ERROR_INVALID_HANDLE; 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (const char*)handle->interface_name; 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint recognized_device(usb_handle* handle) { 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == handle) 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Check vendor and product id first 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project USB_DEVICE_DESCRIPTOR device_desc; 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &device_desc)) { 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Then check interface properties 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project USB_INTERFACE_DESCRIPTOR interf_desc; 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &interf_desc)) { 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Must have two endpoints 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (2 != interf_desc.bNumEndpoints) { 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (is_adb_interface(device_desc.idVendor, device_desc.idProduct, 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) { 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(interf_desc.bInterfaceProtocol == 0x01) { 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbEndpointInformation endpoint_info; 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // assuming zero is a valid bulk endpoint ID 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) { 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->zero_mask = endpoint_info.max_packet_size - 1; 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid find_devices() { 449f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner usb_handle* handle = NULL; 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char entry_buffer[2048]; 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char interf_name[2048]; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long entry_buffer_size = sizeof(entry_buffer); 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* copy_name; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Enumerate all present and active interfaces. 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE enum_handle = 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbEnumInterfaces(usb_class_id, true, true, true); 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == enum_handle) 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // TODO: FIXME - temp hack converting wchar_t into char. 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // It would be better to change AdbNextInterface so it will return 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // interface name as single char string. 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const wchar_t* wchar_name = next_interface->device_name; 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(copy_name = interf_name; 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project L'\0' != *wchar_name; 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wchar_name++, copy_name++) { 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *copy_name = (char)(*wchar_name); 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *copy_name = '\0'; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Lets see if we already have this device in the list 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!known_device(interf_name)) { 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // This seems to be a new device. Open it! 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle = do_usb_open(next_interface->device_name); 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Lets see if this interface (device) belongs to us 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (recognized_device(handle)) { 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("adding a new device %s\n", interf_name); 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char serial_number[512]; 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long serial_number_len = sizeof(serial_number); 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (AdbGetSerialNumber(handle->adb_interface, 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial_number, 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &serial_number_len, 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project true)) { 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Lets make sure that we don't duplicate this device 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (register_new_device(handle)) { 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project register_usb_transport(handle, serial_number); 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("register_new_device failed for %s\n", interf_name); 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("cannot get serial number\n"); 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry_buffer_size = sizeof(entry_buffer); 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(enum_handle); 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 514