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. 249408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = GetLastError(); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(ret); 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(ret); 252408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SetLastError(saved_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); 270408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_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 288408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (saved_errno == ERROR_INVALID_HANDLE) 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_kick(handle); 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 291408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall errno = saved_errno; 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_write NULL handle\n"); 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_write failed: %d\n", errno); 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_read(usb_handle *handle, void* data, int len) { 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long time_out = 500 + len * 8; 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long read = 0; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_read %d\n", len); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (len > 0) { 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int xfer = (len > 4096) ? 4096 : len; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = AdbReadEndpointSync(handle->adb_read_pipe, 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (void*)data, 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (unsigned long)xfer, 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &read, 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project time_out); 317408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = GetLastError(); 318408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, saved_errno); 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret) { 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project data += read; 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len -= read; 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len == 0) 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 325408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else if (saved_errno != ERROR_SEM_TIMEOUT) { 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // assume ERROR_INVALID_HANDLE indicates we are disconnected 327408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (saved_errno == ERROR_INVALID_HANDLE) 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_kick(handle); 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 331408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall errno = saved_errno; 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_read NULL handle\n"); 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_read failed: %d\n", errno); 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_cleanup_handle(usb_handle* handle) { 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->interface_name) 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle->interface_name); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_write_pipe) 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_write_pipe); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_read_pipe) 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_read_pipe); 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle->adb_interface) 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(handle->adb_interface); 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->interface_name = NULL; 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_write_pipe = NULL; 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_read_pipe = NULL; 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->adb_interface = NULL; 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid usb_kick(usb_handle* handle) { 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&usb_lock); 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb_lock); 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = ERROR_INVALID_HANDLE; 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usb_close(usb_handle* handle) { 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("usb_close\n"); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Remove handle from the list 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&usb_lock); 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((handle->next != handle) && (handle->prev != handle)) { 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->next->prev = handle->prev; 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->prev->next = handle->next; 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->prev = handle; 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->next = handle; 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&usb_lock); 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Cleanup handle 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char *usb_name(usb_handle* handle) { 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == handle) { 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SetLastError(ERROR_INVALID_HANDLE); 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = ERROR_INVALID_HANDLE; 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (const char*)handle->interface_name; 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint recognized_device(usb_handle* handle) { 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == handle) 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Check vendor and product id first 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project USB_DEVICE_DESCRIPTOR device_desc; 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &device_desc)) { 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Then check interface properties 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project USB_INTERFACE_DESCRIPTOR interf_desc; 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &interf_desc)) { 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Must have two endpoints 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (2 != interf_desc.bNumEndpoints) { 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (is_adb_interface(device_desc.idVendor, device_desc.idProduct, 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) { 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(interf_desc.bInterfaceProtocol == 0x01) { 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbEndpointInformation endpoint_info; 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // assuming zero is a valid bulk endpoint ID 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) { 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle->zero_mask = endpoint_info.max_packet_size - 1; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid find_devices() { 451f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner usb_handle* handle = NULL; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char entry_buffer[2048]; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char interf_name[2048]; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long entry_buffer_size = sizeof(entry_buffer); 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* copy_name; 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Enumerate all present and active interfaces. 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ADBAPIHANDLE enum_handle = 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbEnumInterfaces(usb_class_id, true, true, true); 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL == enum_handle) 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // TODO: FIXME - temp hack converting wchar_t into char. 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // It would be better to change AdbNextInterface so it will return 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // interface name as single char string. 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const wchar_t* wchar_name = next_interface->device_name; 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(copy_name = interf_name; 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project L'\0' != *wchar_name; 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project wchar_name++, copy_name++) { 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *copy_name = (char)(*wchar_name); 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *copy_name = '\0'; 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Lets see if we already have this device in the list 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!known_device(interf_name)) { 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // This seems to be a new device. Open it! 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle = do_usb_open(next_interface->device_name); 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (NULL != handle) { 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Lets see if this interface (device) belongs to us 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (recognized_device(handle)) { 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("adding a new device %s\n", interf_name); 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char serial_number[512]; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned long serial_number_len = sizeof(serial_number); 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (AdbGetSerialNumber(handle->adb_interface, 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project serial_number, 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &serial_number_len, 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project true)) { 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Lets make sure that we don't duplicate this device 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (register_new_device(handle)) { 4935c93dba771f11bb2228e69d1585c9fe8339c9275Mike Lockwood register_usb_transport(handle, serial_number, 1); 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("register_new_device failed for %s\n", interf_name); 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("cannot get serial number\n"); 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project usb_cleanup_handle(handle); 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(handle); 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project entry_buffer_size = sizeof(entry_buffer); 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AdbCloseHandle(enum_handle); 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 516