static void *usb_open_thread(void *x) { struct usb_handle *usb = (struct usb_handle *)x; int fd; while(1) { //wait untill the USB device needs opening pthread_mutex_lock(&usb->lock); while(usb->fd != -1) pthread_cond_wait(&usb->notify, &usb->lock); pthread_mutex_unlock(&usb->lock); D("[ usb_thread - opening device ]\n"); do { /* XXX use inotify */ fd = open("/dev/android_usbexp", O_RDWR); if (fd < 0) { usleep(1000 * 1000); } } while(fd < 0); D("[Opening device suceeded]\n"); fcntl(fd, F_SETFD, FD_CLOEXEC); usb->fd = fd; D("[ usb_thread - registering device ]\n"); // not sure if this is needed register_usb_transport(usb); } // never gets here return 0; }
static void *usb_open_thread(void *x) { struct usb_handle *usb = (struct usb_handle *)x; int fd; while (1) { // wait until the USB device needs opening adb_mutex_lock(&usb->lock); while (usb->fd != -1) adb_cond_wait(&usb->notify, &usb->lock); adb_mutex_unlock(&usb->lock); D("[ usb_thread - opening device ]\n"); do { /* XXX use inotify? */ fd = unix_open("/dev/android_adb", O_RDWR); if (fd < 0) { // to support older kernels fd = unix_open("/dev/android", O_RDWR); } if (fd < 0) { adb_sleep_ms(1000); } } while (fd < 0); D("[ opening device succeeded ]\n"); close_on_exec(fd); usb->fd = fd; D("[ usb_thread - registering device ]\n"); register_usb_transport(usb, 0, 1); } // never gets here return 0; }
static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; io_service_t usbInterface; IOCFPlugInInterface **plugInInterface = NULL; IOUSBInterfaceInterface220 **iface = NULL; IOUSBDeviceInterface197 **dev = NULL; HRESULT result; SInt32 score; UInt32 locationId; UInt16 vendor; UInt16 product; UInt8 serialIndex; char serial[256]; char devpathBuf[64]; char *devpath = NULL; while ((usbInterface = IOIteratorNext(iterator))) { //* Create an intermediate interface plugin kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); IOObjectRelease(usbInterface); if ((kIOReturnSuccess != kr) || (!plugInInterface)) { DBG("ERR: Unable to create an interface plug-in (%08x)\n", kr); continue; } //* This gets us the interface object result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID*) &iface); //* We only needed the plugin to get the interface, so discard it (*plugInInterface)->Release(plugInInterface); if (result || !iface) { DBG("ERR: Couldn't query the interface (%08x)\n", (int) result); continue; } //* this gets us an ioservice, with which we will find the actual //* device; after getting a plugin, and querying the interface, of //* course. //* Gotta love OS X kr = (*iface)->GetDevice(iface, &usbDevice); if (kIOReturnSuccess != kr || !usbDevice) { DBG("ERR: Couldn't grab device from interface (%08x)\n", kr); continue; } plugInInterface = NULL; score = 0; //* create an intermediate device plugin kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); //* only needed this to find the plugin (void)IOObjectRelease(usbDevice); if ((kIOReturnSuccess != kr) || (!plugInInterface)) { DBG("ERR: Unable to create a device plug-in (%08x)\n", kr); continue; } result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &dev); //* only needed this to query the plugin (*plugInInterface)->Release(plugInInterface); if (result || !dev) { DBG("ERR: Couldn't create a device interface (%08x)\n", (int) result); continue; } //* Now after all that, we actually have a ref to the device and //* the interface that matched our criteria kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceProduct(dev, &product); kr = (*dev)->GetLocationID(dev, &locationId); if (kr == 0) { snprintf(devpathBuf, sizeof(devpathBuf), "usb:%lX", locationId); devpath = devpathBuf; } kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); if (serialIndex > 0) { IOUSBDevRequest req; UInt16 buffer[256]; UInt16 languages[128]; memset(languages, 0, sizeof(languages)); req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = (kUSBStringDesc << 8) | 0; req.wIndex = 0; req.pData = languages; req.wLength = sizeof(languages); kr = (*dev)->DeviceRequest(dev, &req); if (kr == kIOReturnSuccess && req.wLenDone > 0) { int langCount = (req.wLenDone - 2) / 2, lang; for (lang = 1; lang <= langCount; lang++) { memset(buffer, 0, sizeof(buffer)); memset(&req, 0, sizeof(req)); req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = (kUSBStringDesc << 8) | serialIndex; req.wIndex = languages[lang]; 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; break; } } } } (*dev)->Release(dev); DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product, serial); usb_handle* handle = CheckInterface((IOUSBInterfaceInterface**)iface, vendor, product); if (handle == NULL) { DBG("ERR: Could not find device interface: %08x\n", kr); (*iface)->Release(iface); continue; } DBG("AndroidDeviceAdded calling register_usb_transport\n"); register_usb_transport(handle, (serial[0] ? serial : NULL), devpath, 1); // 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, usbInterface, kIOGeneralInterest, AndroidInterfaceNotify, handle, &handle->usbNotification); if (kIOReturnSuccess != kr) { DBG("ERR: Unable to create interest notification (%08x)\n", kr); } } }
void find_devices() { usb_handle* handle = NULL; char entry_buffer[2048]; char interf_name[2048]; AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); unsigned long entry_buffer_size = sizeof(entry_buffer); char* copy_name; // Enumerate all present and active interfaces. ADBAPIHANDLE enum_handle = bridge->AdbEnumInterfaces(usb_class_id, true, true, true); if (NULL == enum_handle) return; while (bridge->AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { // TODO: FIXME - temp hack converting wchar_t into char. // It would be better to change AdbNextInterface so it will return // interface name as single char string. const wchar_t* wchar_name = next_interface->device_name; for(copy_name = interf_name; L'\0' != *wchar_name; wchar_name++, copy_name++) { *copy_name = (char)(*wchar_name); } *copy_name = '\0'; // Lets see if we already have this device in the list if (!known_device(interf_name)) { // This seems to be a new device. Open it! handle = do_usb_open(next_interface->device_name); if (NULL != handle) { // Lets see if this interface (device) belongs to us if (recognized_device(handle)) { D("adding a new device %s\n", interf_name); char serial_number[512]; unsigned long serial_number_len = sizeof(serial_number); if (bridge->AdbGetSerialNumber(handle->adb_interface, serial_number, &serial_number_len, true)) { // Lets make sure that we don't duplicate this device if (register_new_device(handle)) { register_usb_transport(handle, serial_number, NULL, 1); } else { D("register_new_device failed for %s\n", interf_name); usb_cleanup_handle(handle, bridge->AdbCloseHandle, "bridge4"); free(handle); } } else { D("cannot get serial number\n"); usb_cleanup_handle(handle, bridge->AdbCloseHandle, "bridge5"); free(handle); } } else { usb_cleanup_handle(handle, bridge->AdbCloseHandle, "bridge6"); free(handle); } } } entry_buffer_size = sizeof(entry_buffer); } bridge->AdbCloseHandle(enum_handle); }
void find_devices() { usb_handle* handle = nullptr; char entry_buffer[2048]; AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); unsigned long entry_buffer_size = sizeof(entry_buffer); // Enumerate all present and active interfaces. ADBAPIHANDLE enum_handle = AdbEnumInterfaces(usb_class_id, true, true, true); if (nullptr == enum_handle) { D("AdbEnumInterfaces failed: %s", android::base::SystemErrorCodeToString(GetLastError()).c_str()); return; } while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { // Lets see if we already have this device in the list if (!known_device(next_interface->device_name)) { // This seems to be a new device. Open it! handle = do_usb_open(next_interface->device_name); if (nullptr != handle) { // Lets see if this interface (device) belongs to us if (recognized_device(handle)) { D("adding a new device %ls", next_interface->device_name); // We don't request a wchar_t string from AdbGetSerialNumber() because of a bug // in adb_winusb_interface.cpp:CopyMemory(buffer, ser_num->bString, // bytes_written) where the last parameter should be (str_len * // sizeof(wchar_t)). The bug reads 2 bytes past the end of a stack buffer in the // best case, and in the unlikely case of a long serial number, it will read 2 // bytes past the end of a heap allocation. This doesn't affect the resulting // string, but we should avoid the bad reads in the first place. char serial_number[512]; unsigned long serial_number_len = sizeof(serial_number); if (AdbGetSerialNumber(handle->adb_interface, serial_number, &serial_number_len, true)) { // Lets make sure that we don't duplicate this device if (register_new_device(handle)) { register_usb_transport(handle, serial_number, nullptr, 1); } else { D("register_new_device failed for %ls", next_interface->device_name); usb_cleanup_handle(handle); free(handle); } } else { D("cannot get serial number: %s", android::base::SystemErrorCodeToString(GetLastError()).c_str()); usb_cleanup_handle(handle); free(handle); } } else { usb_cleanup_handle(handle); free(handle); } } } entry_buffer_size = sizeof(entry_buffer); } if (GetLastError() != ERROR_NO_MORE_ITEMS) { // Only ERROR_NO_MORE_ITEMS is expected at the end of enumeration. D("AdbNextInterface failed: %s", android::base::SystemErrorCodeToString(GetLastError()).c_str()); } _adb_close_handle(enum_handle); }