static int lsusb_device_added(const char *dev_name, void *client_data) { struct usb_device *dev = usb_device_open(dev_name); if (!dev) { fprintf(stderr, "can't open device %s: %s\n", dev_name, strerror(errno)); return 0; } if (verbose) { struct usb_descriptor_iter iter; struct usb_descriptor_header *desc; printf("%s:\n", dev_name); usb_descriptor_iter_init(dev, &iter); while ((desc = usb_descriptor_iter_next(&iter)) != NULL) lsusb_parse_descriptor(dev, desc); } else { uint16_t vid, pid; char *mfg_name, *product_name, *serial; vid = usb_device_get_vendor_id(dev); pid = usb_device_get_product_id(dev); mfg_name = usb_device_get_manufacturer_name(dev); product_name = usb_device_get_product_name(dev); serial = usb_device_get_serial(dev); printf("%s: %04x:%04x %s %s %s\n", dev_name, vid, pid, mfg_name, product_name, serial); free(mfg_name); free(product_name); free(serial); } usb_device_close(dev); return 0; }
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; }
// Callback for notification when new USB devices are attached. Return true to exit from usb_host_run. int usb_device_added (const char * devname, void * client_data) { logd ("\n"); //logd ("client_data: %p devname: %s", client_data, devname); logd ("devname: %s", devname); uint16_t usb_vid, usb_pid; int ret; //int unused = (int) client_data; if (ena_su_perm) { // Set Permission w/ SU: char cmd [256] = "su -c chmod 777 "; strlcat (cmd, devname, sizeof (cmd)); //strlcat (cmd, " 2>&1 > /sdcard/res", sizeof (cmd)); errno = 0; ret = system (cmd); // !! Binaries like ssd that write to stdout cause C system() to crash ! logd ("system() ret: %d errno: %d (%s)", ret, errno, strerror (errno)); } struct usb_device * device = usb_device_open (devname); if (! device) { loge ("usb_device_open failed"); return (0); // 0 = Leave usb_host_run() running } usb_vid = usb_device_get_vendor_id (device); usb_pid = usb_device_get_product_id (device); char * usb_ser = usb_device_get_serial (device); logd ("usb_vid: 0x%x (%d - %s) usb_pid: 0x%x usb_ser: %s", usb_vid, usb_vid, usb_vid_get (usb_vid), usb_pid, usb_ser); if (current_device != NULL) { // If we already have a device, just ignore logd ("Ignoring have current_device: %p", current_device); usb_device_close (device); return (0); // 0 = Leave usb_host_run() running } if (usb_vid != USB_VID_GOO || usb_pid >= USB_PID_ACC_MIN || usb_pid <= USB_PID_ACC_MAX) { // If not in Google Accessory mode... logd ("Found new device - attempting to switch to accessory mode"); uint16_t protocol = -1; errno = 0; ret = usb_device_control_transfer (device, USB_DIR_IN | USB_TYPE_VENDOR, ACC_REQ_GET_PROTOCOL, 0, 0, & protocol, sizeof (protocol), 1000); if (ret < 0) { loge ("No Acc OAP protocol ret: %d errno: %d", ret, errno); usb_device_close (device); return (0); // 0 = Leave usb_host_run() running } if (protocol < 2) { loge ("Acc OAP protocol version %d", protocol); usb_device_close (device); return (0); // 0 = Leave usb_host_run() running } logd ("Acc OAP protocol version %d", protocol); send_string (device, ACC_IDX_MAN, AAP_VAL_MAN); // Send Acc strings send_string (device, ACC_IDX_MOD, AAP_VAL_MOD); //send_string (device, ACC_IDX_DES, AAP_VAL_DES); //send_string (device, ACC_IDX_VER, AAP_VAL_VER); //send_string (device, ACC_IDX_URI, AAP_VAL_URI); //send_string (device, ACC_IDX_SER, AAP_VAL_SER); errno = 0; ret = usb_device_control_transfer (device, USB_DIR_OUT | USB_TYPE_VENDOR, ACC_REQ_START, 0, 0, NULL, 0, 1000); if (ret < 0) loge ("Acc Start ret: %d errno: %d", ret, errno); else logd ("Acc Start ret: %d", ret); } logd ("Found android device in accessory mode"); //pthread_mutex_lock (& device_mutex); //pthread_cond_broadcast (& device_cond); //pthread_mutex_unlock (& device_mutex); struct usb_descriptor_iter iter; struct usb_descriptor_header * desc = NULL; struct usb_interface_descriptor * intf = NULL; struct usb_endpoint_descriptor * ep = NULL; usb_descriptor_iter_init (device, & iter); // Init for iterating USB descriptors read_ep = 255; write_ep = 255; while ((desc = usb_descriptor_iter_next (& iter)) != NULL) { if (0); else if (desc->bDescriptorType == LIBUSB_DT_DEVICE) { logd ("Device desc: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_CONFIG) { logd ("Config desc: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_STRING) { logd ("String desc: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_HID) { logd ("HID desc: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_REPORT) { logd ("HID Report desc: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_PHYSICAL) { logd ("Physical desc: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_HUB) { logd ("Hub desc: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_INTERFACE) { intf = (struct usb_interface_descriptor *) desc; logd ("Interface desc/intf: %p", desc); } else if (desc->bDescriptorType == LIBUSB_DT_ENDPOINT) { logd ("Endpoint desc/ep: %p", desc); ep = (struct usb_endpoint_descriptor *) desc; uint8_t ep_addr = ep->bEndpointAddress; if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { if (read_ep == 255) { read_ep = ep_addr; logd ("Set as first read endpoint ep_addr: %d"); } else loge ("Ignored already have read endpoint ep_addr: %d"); } else { if (write_ep == 255) { write_ep = ep_addr; logd ("Set as first write endpoint ep_addr: %d"); } else loge ("Ignored already have write endpoint ep_addr: %d"); } } else loge ("Unknown desc->bDescriptorType: %d", desc->bDescriptorType); } if (! intf) { loge ("interface not found"); usb_device_close (device); return (0); // 0 = Leave usb_host_run() running } if (read_ep == 255 || write_ep == 255) { loge ("Read and/or write endpoints not found"); usb_device_close (device); return (0); // 0 = Leave usb_host_run() running } errno = 0; ret = usb_device_claim_interface (device, intf->bInterfaceNumber); if (ret) { loge ("Error usb_device_claim_interface() errno: %d", errno); usb_device_close (device); return (0); // 0 = Leave usb_host_run() running } current_device = device; loge ("Success usb_device_claim_interface() : Can start AA protocol now"); //ret = hu_aap_start (); byte vr_buf [] = {0, 3, 0, 6, 0, 1, 0, 1, 0, 1}; // Version Request //ret = hu_aap_usb_send (vr_buf, sizeof (vr_buf), 1000); // Send Version Request errno = 0; ret = hu_bulk_send (vr_buf, sizeof (vr_buf)); if (ret) { loge ("Error hu_bulk_send() ret: %d errno: %d (%s)", ret, errno, strerror (errno)); usb_device_close (device); return (0); // 0 = Leave usb_host_run() running } logd ("Success hu_bulk_send()"); return (0); // 0 = Leave usb_host_run() running }
static int usb_device_added(const char *devname, void* client_data) { struct usb_descriptor_header* desc; struct usb_descriptor_iter iter; uint16_t vendorId, productId; int ret; pthread_t th; struct usb_device *device = usb_device_open(devname); if (!device) { fprintf(stderr, "usb_device_open failed\n"); return 0; } vendorId = usb_device_get_vendor_id(device); productId = usb_device_get_product_id(device); if (!sDevice && (vendorId == 0x18D1 && (productId == 0x2D00 || productId == 0x2D01))) { struct usb_descriptor_header* desc; struct usb_descriptor_iter iter; struct usb_interface_descriptor *intf = NULL; struct usb_endpoint_descriptor *ep1 = NULL; struct usb_endpoint_descriptor *ep2 = NULL; printf("Found Android device in accessory mode (%x:%x)...\n", vendorId, productId); sDevice = device; usb_descriptor_iter_init(device, &iter); while ((desc = usb_descriptor_iter_next(&iter)) != NULL && (!intf || !ep1 || !ep2)) { if (desc->bDescriptorType == USB_DT_INTERFACE) { intf = (struct usb_interface_descriptor *)desc; } else if (desc->bDescriptorType == USB_DT_ENDPOINT) { if (ep1) ep2 = (struct usb_endpoint_descriptor *)desc; else ep1 = (struct usb_endpoint_descriptor *)desc; } } if (!intf) { fprintf(stderr, "Interface not found\n"); exit(1); } if (!ep1 || !ep2) { fprintf(stderr, "Endpoints not found\n"); exit(1); } if (usb_device_claim_interface(device, intf->bInterfaceNumber)) { fprintf(stderr, "usb_device_claim_interface failed errno: %d\n", errno); exit(1); } int endpoints[2]; if ((ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { endpoints[0] = ep1->bEndpointAddress; endpoints[1] = ep2->bEndpointAddress; } else { endpoints[0] = ep2->bEndpointAddress; endpoints[1] = ep1->bEndpointAddress; } pthread_create(&th, NULL, message_thread, (void *)endpoints); } else { printf("Found possible Android device (%x:%x) " "- attempting to switch to accessory mode...\n", vendorId, productId); uint16_t protocol = 0; ret = usb_device_control_transfer(device, USB_DIR_IN | USB_TYPE_VENDOR, ACCESSORY_GET_PROTOCOL, 0, 0, &protocol, sizeof(protocol), 0); if (ret == 2) printf("Device supports protocol version %d\n", protocol); else fprintf(stderr, "Failed to read protocol version\n"); send_string(device, ACCESSORY_STRING_MANUFACTURER, "Android CTS"); send_string(device, ACCESSORY_STRING_MODEL, "CTS USB Accessory"); send_string(device, ACCESSORY_STRING_DESCRIPTION, "CTS USB Accessory"); send_string(device, ACCESSORY_STRING_VERSION, "1.0"); send_string(device, ACCESSORY_STRING_URI, "http://source.android.com/compatibility/cts-intro.html"); send_string(device, ACCESSORY_STRING_SERIAL, "1234567890"); ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR, ACCESSORY_START, 0, 0, 0, 0, 0); return 0; } if (device != sDevice) usb_device_close(device); return 0; }