MTP host fixes:
Add support for detecting android MTP devices Fix problem reading data packet with header sent separately from payload. Change-Id: I07b34af6783ebe2e63a317796ba0c8223df86edf Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
@@ -118,52 +118,66 @@ bool MtpClient::usbDeviceAdded(const char *devname) {
|
||||
{
|
||||
LOGD("Found camera: \"%s\" \"%s\"\n", usb_device_get_manufacturer_name(device),
|
||||
usb_device_get_product_name(device));
|
||||
} else if (interface->bInterfaceClass == 0xFF &&
|
||||
interface->bInterfaceSubClass == 0xFF &&
|
||||
interface->bInterfaceProtocol == 0) {
|
||||
char* interfaceName = usb_device_get_string(device, interface->iInterface);
|
||||
if (!interfaceName || strcmp(interfaceName, "MTP"))
|
||||
continue;
|
||||
// Looks like an android style MTP device
|
||||
LOGD("Found MTP device: \"%s\" \"%s\"\n", usb_device_get_manufacturer_name(device),
|
||||
usb_device_get_product_name(device));
|
||||
} else {
|
||||
// not an MTP or PTP device
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
LOGE("endpoints not found\n");
|
||||
return mDone;
|
||||
}
|
||||
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) {
|
||||
// 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) {
|
||||
LOGE("endpoints not found\n");
|
||||
return mDone;
|
||||
}
|
||||
|
||||
struct usb_endpoint *ep_in = usb_endpoint_open(device, ep_in_desc);
|
||||
struct usb_endpoint *ep_out = usb_endpoint_open(device, ep_out_desc);
|
||||
struct usb_endpoint *ep_intr = usb_endpoint_open(device, ep_intr_desc);
|
||||
|
||||
if (usb_device_claim_interface(device, interface->bInterfaceNumber)) {
|
||||
LOGE("usb_device_claim_interface failed\n");
|
||||
usb_endpoint_close(ep_in);
|
||||
usb_endpoint_close(ep_out);
|
||||
usb_endpoint_close(ep_intr);
|
||||
return mDone;
|
||||
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;
|
||||
}
|
||||
|
||||
MtpDevice* mtpDevice = new MtpDevice(device, interface->bInterfaceNumber,
|
||||
ep_in, ep_out, ep_intr);
|
||||
mDeviceList.add(mtpDevice);
|
||||
mtpDevice->initialize();
|
||||
deviceAdded(mtpDevice);
|
||||
}
|
||||
if (!ep_in_desc || !ep_out_desc || !ep_intr_desc) {
|
||||
LOGE("endpoints not found\n");
|
||||
return mDone;
|
||||
}
|
||||
|
||||
struct usb_endpoint *ep_in = usb_endpoint_open(device, ep_in_desc);
|
||||
struct usb_endpoint *ep_out = usb_endpoint_open(device, ep_out_desc);
|
||||
struct usb_endpoint *ep_intr = usb_endpoint_open(device, ep_intr_desc);
|
||||
|
||||
if (usb_device_claim_interface(device, interface->bInterfaceNumber)) {
|
||||
LOGE("usb_device_claim_interface failed\n");
|
||||
usb_endpoint_close(ep_in);
|
||||
usb_endpoint_close(ep_out);
|
||||
usb_endpoint_close(ep_intr);
|
||||
return mDone;
|
||||
}
|
||||
|
||||
MtpDevice* mtpDevice = new MtpDevice(device, interface->bInterfaceNumber,
|
||||
ep_in, ep_out, ep_intr);
|
||||
mDeviceList.add(mtpDevice);
|
||||
mtpDevice->initialize();
|
||||
deviceAdded(mtpDevice);
|
||||
return mDone;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -372,7 +372,7 @@ int MtpDataPacket::writeDataHeader(int fd, uint32_t length) {
|
||||
int MtpDataPacket::read(struct usb_endpoint *ep) {
|
||||
// first read the header
|
||||
int length = transfer(ep, mBuffer, mBufferSize);
|
||||
if (length > MTP_CONTAINER_HEADER_SIZE) {
|
||||
if (length >= MTP_CONTAINER_HEADER_SIZE) {
|
||||
// look at the length field to see if the data spans multiple packets
|
||||
uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
|
||||
while (totalLength > length) {
|
||||
|
||||
Reference in New Issue
Block a user