diff options
Diffstat (limited to 'adb/usb_osx.c')
-rw-r--r-- | adb/usb_osx.c | 536 |
1 files changed, 0 insertions, 536 deletions
diff --git a/adb/usb_osx.c b/adb/usb_osx.c deleted file mode 100644 index 49e1eef5b..000000000 --- a/adb/usb_osx.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <CoreFoundation/CoreFoundation.h> - -#include <IOKit/IOKitLib.h> -#include <IOKit/IOCFPlugIn.h> -#include <IOKit/usb/IOUSBLib.h> -#include <IOKit/IOMessage.h> -#include <mach/mach_port.h> - -#include "sysdeps.h" - -#include <stdio.h> - -#define TRACE_TAG TRACE_USB -#include "adb.h" - -#define DBG D - -typedef struct { - int vid; - int pid; -} VendorProduct; - -#define kSupportedDeviceCount 4 -VendorProduct kSupportedDevices[kSupportedDeviceCount] = { - { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER }, - { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER_COMP }, - { VENDOR_ID_HTC, PRODUCT_ID_DREAM }, - { VENDOR_ID_HTC, PRODUCT_ID_DREAM_COMP }, -}; - -static IONotificationPortRef notificationPort = 0; -static io_iterator_t notificationIterators[kSupportedDeviceCount]; - -struct usb_handle -{ - UInt8 bulkIn; - UInt8 bulkOut; - IOUSBInterfaceInterface **interface; - io_object_t usbNotification; - unsigned int zero_mask; -}; - -static CFRunLoopRef currentRunLoop = 0; -static pthread_mutex_t start_lock; -static pthread_cond_t start_cond; - - -static void AndroidDeviceAdded(void *refCon, io_iterator_t iterator); -static void AndroidDeviceNotify(void *refCon, io_iterator_t iterator, natural_t messageType, void *messageArgument); -static usb_handle* FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product); - -static int -InitUSB() -{ - CFMutableDictionaryRef matchingDict; - CFRunLoopSourceRef runLoopSource; - SInt32 vendor, product; - int i; - - //* To set up asynchronous notifications, create a notification port and - //* add its run loop event source to the program's run loop - notificationPort = IONotificationPortCreate(kIOMasterPortDefault); - runLoopSource = IONotificationPortGetRunLoopSource(notificationPort); - CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode); - - memset(notificationIterators, 0, sizeof(notificationIterators)); - - //* loop through all supported vendor/product pairs - for (i = 0; i < kSupportedDeviceCount; i++) { - //* Create our matching dictionary to find the Android device - //* IOServiceAddMatchingNotification consumes the reference, so we do not need to release this - matchingDict = IOServiceMatching(kIOUSBDeviceClassName); - - if (!matchingDict) { - DBG("ERR: Couldn't create USB matching dictionary.\n"); - return -1; - } - - //* Set up two matching dictionaries, one for each product ID we support. - //* This will cause the kernel to notify us only if the vendor and product IDs match. - vendor = kSupportedDevices[i].vid; - product = kSupportedDevices[i].pid; - CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor)); - CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product)); - - //* Now set up two notifications: one to be called when a raw device - //* is first matched by the I/O Kit and another to be called when the - //* device is terminated. - //* we need to do this with each matching dictionary. - IOServiceAddMatchingNotification( - notificationPort, - kIOFirstMatchNotification, - matchingDict, - AndroidDeviceAdded, - NULL, - ¬ificationIterators[i]); - - //* Iterate over set of matching devices to access already-present devices - //* and to arm the notification - AndroidDeviceAdded(NULL, notificationIterators[i]); - } - - return 0; -} - -static void -AndroidDeviceAdded(void *refCon, io_iterator_t iterator) -{ - kern_return_t kr; - io_service_t usbDevice; - IOCFPlugInInterface **plugInInterface = NULL; - IOUSBDeviceInterface182 **dev = NULL; - HRESULT result; - SInt32 score; - UInt16 vendor; - UInt16 product; - UInt8 serialIndex; - char serial[256]; - - while ((usbDevice = IOIteratorNext(iterator))) { - //* Create an intermediate plugin - kr = IOCreatePlugInInterfaceForService(usbDevice, - kIOUSBDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, &score); - - if ((kIOReturnSuccess != kr) || (!plugInInterface)) { - DBG("ERR: Unable to create a plug-in (%08x)\n", kr); - goto continue1; - } - - //* Now create the device interface - result = (*plugInInterface)->QueryInterface(plugInInterface, - CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID) &dev); - - if (result || !dev) { - DBG("ERR: Couldn't create a device interface (%08x)\n", (int) result); - goto continue2; - } - - //* Check the device to see if it's ours - kr = (*dev)->GetDeviceVendor(dev, &vendor); - kr = (*dev)->GetDeviceProduct(dev, &product); - kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); - - if (serialIndex > 0) { - IOUSBDevRequest req; - UInt16 buffer[256]; - - req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); - req.bRequest = kUSBRqGetDescriptor; - req.wValue = (kUSBStringDesc << 8) | serialIndex; - req.wIndex = 0; - req.pData = buffer; - req.wLength = sizeof(buffer); - kr = (*dev)->DeviceRequest(dev, &req); - - if (kr == kIOReturnSuccess && req.wLenDone > 0) { - int i, count; - - // skip first word, and copy the rest to the serial string, changing shorts to bytes. - count = (req.wLenDone - 1) / 2; - for (i = 0; i < count; i++) - serial[i] = buffer[i + 1]; - serial[i] = 0; - } - } - - usb_handle* handle = NULL; - - //* Open the device - kr = (*dev)->USBDeviceOpen(dev); - - if (kr != kIOReturnSuccess) { - DBG("ERR: Could not open device: %08x\n", kr); - goto continue3; - } else { - //* Find an interface for the device - handle = FindDeviceInterface((IOUSBDeviceInterface**)dev, vendor, product); - } - - if (handle == NULL) { - DBG("ERR: Could not find device interface: %08x\n", kr); - (*dev)->USBDeviceClose(dev); - goto continue3; - } - - DBG("AndroidDeviceAdded calling register_usb_transport\n"); - register_usb_transport(handle, (serial[0] ? serial : NULL)); - - // Register for an interest notification of this device being removed. Pass the reference to our - // private data as the refCon for the notification. - kr = IOServiceAddInterestNotification(notificationPort, - usbDevice, - kIOGeneralInterest, - AndroidDeviceNotify, - handle, - &handle->usbNotification); - if (kIOReturnSuccess != kr) { - DBG("ERR: Unable to create interest notification (%08x)\n", kr); - } - -continue3: - (void)(*dev)->Release(dev); -continue2: - IODestroyPlugInInterface(plugInInterface); -continue1: - IOObjectRelease(usbDevice); - } -} - -static void -AndroidDeviceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) -{ - usb_handle *handle = (usb_handle *)refCon; - - if (messageType == kIOMessageServiceIsTerminated) { - DBG("AndroidDeviceNotify\n"); - IOObjectRelease(handle->usbNotification); - usb_kick(handle); - } -} - -static usb_handle* -FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product) -{ - usb_handle* handle = NULL; - IOReturn kr; - IOUSBFindInterfaceRequest request; - io_iterator_t iterator; - io_service_t usbInterface; - IOCFPlugInInterface **plugInInterface; - IOUSBInterfaceInterface **interface = NULL; - HRESULT result; - SInt32 score; - UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol; - UInt8 endpoint, configuration; - - //* Placing the constant KIOUSBFindInterfaceDontCare into the following - //* fields of the IOUSBFindInterfaceRequest structure will allow us to - //* find all of the interfaces - request.bInterfaceClass = kIOUSBFindInterfaceDontCare; - request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; - request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; - request.bAlternateSetting = kIOUSBFindInterfaceDontCare; - - //* SetConfiguration will kill an existing UMS connection, so let's not do this if not necessary. - configuration = 0; - (*dev)->GetConfiguration(dev, &configuration); - if (configuration != 1) - (*dev)->SetConfiguration(dev, 1); - - //* Get an iterator for the interfaces on the device - kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator); - - if (kr != kIOReturnSuccess) { - DBG("ERR: Couldn't create a device interface iterator: (%08x)\n", kr); - return NULL; - } - - while ((usbInterface = IOIteratorNext(iterator))) { - //* Create an intermediate plugin - kr = IOCreatePlugInInterfaceForService( - usbInterface, - kIOUSBInterfaceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, - &score); - - //* No longer need the usbInterface object now that we have the plugin - (void) IOObjectRelease(usbInterface); - - if ((kr != kIOReturnSuccess) || (!plugInInterface)) { - DBG("ERR: Unable to create plugin (%08x)\n", kr); - break; - } - - //* Now create the interface interface for the interface - result = (*plugInInterface)->QueryInterface( - plugInInterface, - CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), - (LPVOID) &interface); - - //* No longer need the intermediate plugin - (*plugInInterface)->Release(plugInInterface); - - if (result || !interface) { - DBG("ERR: Couldn't create interface interface: (%08x)\n", - (unsigned int) result); - break; - } - - //* Now open the interface. This will cause the pipes associated with - //* the endpoints in the interface descriptor to be instantiated - kr = (*interface)->USBInterfaceOpen(interface); - - if (kr != kIOReturnSuccess) - { - DBG("ERR: Could not open interface: (%08x)\n", kr); - (void) (*interface)->Release(interface); - //* continue so we can try the next interface - continue; - } - - //* Get the number of endpoints associated with this interface - kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); - - if (kr != kIOReturnSuccess) { - DBG("ERR: Unable to get number of endpoints: (%08x)\n", kr); - goto next_interface; - } - - //* Get interface class, subclass and protocol - if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess || - (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass) != kIOReturnSuccess || - (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess) - { - DBG("ERR: Unable to get interface class, subclass and protocol\n"); - goto next_interface; - } - - //* check to make sure interface class, subclass and protocol match ADB - //* avoid opening mass storage endpoints - if (is_adb_interface(vendor, product, interfaceClass, interfaceSubClass, interfaceProtocol)) { - handle = calloc(1, sizeof(usb_handle)); - - //* Iterate over the endpoints for this interface and find the first - //* bulk in/out pipes available. These will be our read/write pipes. - for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) { - UInt8 transferType; - UInt16 maxPacketSize; - UInt8 interval; - UInt8 number; - UInt8 direction; - - kr = (*interface)->GetPipeProperties(interface, endpoint, &direction, - &number, &transferType, &maxPacketSize, &interval); - - if (kIOReturnSuccess == kr) { - if (kUSBBulk != transferType) - continue; - - if (kUSBIn == direction) - handle->bulkIn = endpoint; - - if (kUSBOut == direction) - handle->bulkOut = endpoint; - - if (interfaceProtocol == 0x01) { - handle->zero_mask = maxPacketSize - 1; - } - - } else { - DBG("ERR: FindDeviceInterface - could not get pipe properties\n"); - } - } - - handle->interface = interface; - break; - } - -next_interface: - (*interface)->USBInterfaceClose(interface); - (*interface)->Release(interface); - } - - return handle; -} - - -void* RunLoopThread(void* unused) -{ - int i; - - InitUSB(); - - currentRunLoop = CFRunLoopGetCurrent(); - - // Signal the parent that we are running - adb_mutex_lock(&start_lock); - adb_cond_signal(&start_cond); - adb_mutex_unlock(&start_lock); - - CFRunLoopRun(); - currentRunLoop = 0; - - for (i = 0; i < kSupportedDeviceCount; i++) { - IOObjectRelease(notificationIterators[i]); - } - IONotificationPortDestroy(notificationPort); - - DBG("RunLoopThread done\n"); - return NULL; -} - - -static int initialized = 0; -void usb_init() -{ - if (!initialized) - { - adb_thread_t tid; - - adb_mutex_init(&start_lock, NULL); - adb_cond_init(&start_cond, NULL); - - if(adb_thread_create(&tid, RunLoopThread, NULL)) - fatal_errno("cannot create input thread"); - - // Wait for initialization to finish - adb_mutex_lock(&start_lock); - adb_cond_wait(&start_cond, &start_lock); - adb_mutex_unlock(&start_lock); - - adb_mutex_destroy(&start_lock); - adb_cond_destroy(&start_cond); - - initialized = 1; - } -} - -void usb_cleanup() -{ - DBG("usb_cleanup\n"); - close_usb_devices(); - if (currentRunLoop) - CFRunLoopStop(currentRunLoop); -} - -int usb_write(usb_handle *handle, const void *buf, int len) -{ - IOReturn result; - - if (!len) - return 0; - - if (!handle) - return -1; - - if (NULL == handle->interface) { - DBG("ERR: usb_write interface was null\n"); - return -1; - } - - if (0 == handle->bulkOut) { - DBG("ERR: bulkOut endpoint not assigned\n"); - return -1; - } - - result = - (*handle->interface)->WritePipe( - handle->interface, handle->bulkOut, (void *)buf, len); - - if ((result == 0) && (handle->zero_mask)) { - /* we need 0-markers and our transfer */ - if(!(len & handle->zero_mask)) { - result = - (*handle->interface)->WritePipe( - handle->interface, handle->bulkOut, (void *)buf, 0); - } - } - - if (0 == result) - return 0; - - DBG("ERR: usb_write failed with status %d\n", result); - return -1; -} - -int usb_read(usb_handle *handle, void *buf, int len) -{ - IOReturn result; - UInt32 numBytes = len; - - if (!len) { - return 0; - } - - if (!handle) { - return -1; - } - - if (NULL == handle->interface) { - DBG("ERR: usb_read interface was null\n"); - return -1; - } - - if (0 == handle->bulkIn) { - DBG("ERR: bulkIn endpoint not assigned\n"); - return -1; - } - - result = - (*handle->interface)->ReadPipe(handle->interface, - handle->bulkIn, buf, &numBytes); - - if (0 == result) - return 0; - else { - DBG("ERR: usb_read failed with status %d\n", result); - } - - return -1; -} - -int usb_close(usb_handle *handle) -{ - return 0; -} - -void usb_kick(usb_handle *handle) -{ - /* release the interface */ - if (handle->interface) - { - (*handle->interface)->USBInterfaceClose(handle->interface); - (*handle->interface)->Release(handle->interface); - handle->interface = 0; - } -} |