char* usb_device_get_serial(struct usb_device *device) { struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc; if (desc->iSerialNumber) return usb_device_get_string(device, desc->iSerialNumber); else return NULL; }
char* usb_device_get_manufacturer_name(struct usb_device *device) { struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc; if (desc->iManufacturer) return usb_device_get_string(device, desc->iManufacturer); else return NULL; }
char* usb_device_get_product_name(struct usb_device *device) { struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc; if (desc->iProduct) return usb_device_get_string(device, desc->iProduct); else return NULL; }
static const char *get_str(struct usb_device *dev, int id) { char *str = usb_device_get_string(dev, id); if (id && str) { strlcpy(str_buff, str, sizeof(str_buff)); free(str); } else { snprintf(str_buff, sizeof(str_buff), "%02x", id); } return str_buff; }
MtpDevice* MtpDevice::open(const char* deviceName, int fd) { struct usb_device *device = usb_device_new(deviceName, fd); if (!device) { ALOGE("usb_device_new failed for %s", deviceName); return NULL; } struct usb_descriptor_header* desc; struct usb_descriptor_iter iter; usb_descriptor_iter_init(device, &iter); while ((desc = usb_descriptor_iter_next(&iter)) != NULL) { if (desc->bDescriptorType == USB_DT_INTERFACE) { struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc; if (interface->bInterfaceClass == USB_CLASS_STILL_IMAGE && interface->bInterfaceSubClass == 1 && // Still Image Capture interface->bInterfaceProtocol == 1) // Picture Transfer Protocol (PIMA 15470) { char* manufacturerName = usb_device_get_manufacturer_name(device); char* productName = usb_device_get_product_name(device); ALOGD("Found camera: \"%s\" \"%s\"\n", manufacturerName, productName); free(manufacturerName); free(productName); } else if (interface->bInterfaceClass == 0xFF && interface->bInterfaceSubClass == 0xFF && interface->bInterfaceProtocol == 0) { char* interfaceName = usb_device_get_string(device, interface->iInterface); if (!interfaceName) { continue; } else if (strcmp(interfaceName, "MTP")) { free(interfaceName); continue; } free(interfaceName); // Looks like an android style MTP device char* manufacturerName = usb_device_get_manufacturer_name(device); char* productName = usb_device_get_product_name(device); ALOGD("Found MTP device: \"%s\" \"%s\"\n", manufacturerName, productName); free(manufacturerName); free(productName); } #if 0 else { // look for special cased devices based on vendor/product ID // we are doing this mainly for testing purposes uint16_t vendor = usb_device_get_vendor_id(device); uint16_t product = usb_device_get_product_id(device); if (!isMtpDevice(vendor, product)) { // not an MTP or PTP device continue; } // request MTP OS string and descriptor // some music players need to see this before entering MTP mode. char buffer[256]; memset(buffer, 0, sizeof(buffer)); int ret = usb_device_control_transfer(device, USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_STANDARD, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | 0xEE, 0, buffer, sizeof(buffer), 0); printf("usb_device_control_transfer returned %d errno: %d\n", ret, errno); if (ret > 0) { printf("got MTP string %s\n", buffer); ret = usb_device_control_transfer(device, USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, 1, 0, 4, buffer, sizeof(buffer), 0); printf("OS descriptor got %d\n", ret); } else { printf("no MTP string\n"); } } #endif // if we got here, then we have a likely MTP or PTP device // interface should be followed by three endpoints struct usb_endpoint_descriptor *ep; struct usb_endpoint_descriptor *ep_in_desc = NULL; struct usb_endpoint_descriptor *ep_out_desc = NULL; struct usb_endpoint_descriptor *ep_intr_desc = NULL; for (int i = 0; i < 3; i++) { ep = (struct usb_endpoint_descriptor *)usb_descriptor_iter_next(&iter); if (!ep || ep->bDescriptorType != USB_DT_ENDPOINT) { ALOGE("endpoints not found\n"); usb_device_close(device); return NULL; } if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK) { if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ep_in_desc = ep; else ep_out_desc = ep; } else if (ep->bmAttributes == USB_ENDPOINT_XFER_INT && ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { ep_intr_desc = ep; } } if (!ep_in_desc || !ep_out_desc || !ep_intr_desc) { ALOGE("endpoints not found\n"); usb_device_close(device); return NULL; } if (usb_device_claim_interface(device, interface->bInterfaceNumber)) { ALOGE("usb_device_claim_interface failed errno: %d\n", errno); usb_device_close(device); return NULL; } MtpDevice* mtpDevice = new MtpDevice(device, interface->bInterfaceNumber, ep_in_desc, ep_out_desc, ep_intr_desc); mtpDevice->initialize(); return mtpDevice; } } usb_device_close(device); ALOGE("device not found"); return NULL; }