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