diff --git a/mtp/MtpDevice.cpp b/mtp/MtpDevice.cpp
new file mode 100755
index 0000000..53f8b2e
--- /dev/null
+++ b/mtp/MtpDevice.cpp
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
+ */
+
+#include "MtpDevice.h"
+#include "MtpDebug.h"
+#include "MtpDeviceInfo.h"
+#include "MtpObjectInfo.h"
+#include "MtpProperty.h"
+#include "MtpStorageInfo.h"
+#include "MtpStringBuffer.h"
+#include "MtpUtils.h"
+#include "MtpDataPacket.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <endian.h>
+
+#include <usbhost/usbhost.h>
+
+
+#if 0
+static bool isMtpDevice(uint16_t vendor, uint16_t product) {
+	// Sandisk Sansa Fuze
+	if (vendor == 0x0781 && product == 0x74c2)
+		return true;
+	// Samsung YP-Z5
+	if (vendor == 0x04e8 && product == 0x503c)
+		return true;
+	return false;
+}
+#endif
+
+MtpDevice* MtpDevice::open(const char* deviceName, int fd) {
+	struct usb_device *device = usb_device_new(deviceName, fd);
+	if (!device) {
+		MTPE("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);
+				MTPD("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);
+				MTPI("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);
+				MTPE("usb_device_control_transfer returned %d errno: %d\n", ret, errno);
+				if (ret > 0) {
+					MTPI("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);
+					MTPI("OS descriptor got %d\n", ret);
+				} else {
+					MTPI("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) {
+					MTPE("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) {
+				MTPE("endpoints not found\n");
+				usb_device_close(device);
+				return NULL;
+			}
+
+			if (usb_device_claim_interface(device, interface->bInterfaceNumber)) {
+				MTPE("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);
+	MTPE("device not found");
+	return NULL;
+}
+
+MtpDevice::MtpDevice(struct usb_device* device, int interface,
+			const struct usb_endpoint_descriptor *ep_in,
+			const struct usb_endpoint_descriptor *ep_out,
+			const struct usb_endpoint_descriptor *ep_intr)
+	:   mDevice(device),
+		mInterface(interface),
+		mRequestIn1(NULL),
+		mRequestIn2(NULL),
+		mRequestOut(NULL),
+		mRequestIntr(NULL),
+		mDeviceInfo(NULL),
+		mSessionID(0),
+		mTransactionID(0),
+		mReceivedResponse(false)
+{
+	mRequestIn1 = usb_request_new(device, ep_in);
+	mRequestIn2 = usb_request_new(device, ep_in);
+	mRequestOut = usb_request_new(device, ep_out);
+	mRequestIntr = usb_request_new(device, ep_intr);
+}
+
+MtpDevice::~MtpDevice() {
+	close();
+	for (size_t i = 0; i < mDeviceProperties.size(); i++)
+		delete mDeviceProperties[i];
+	usb_request_free(mRequestIn1);
+	usb_request_free(mRequestIn2);
+	usb_request_free(mRequestOut);
+	usb_request_free(mRequestIntr);
+}
+
+void MtpDevice::initialize() {
+	openSession();
+	mDeviceInfo = getDeviceInfo();
+	if (mDeviceInfo) {
+		if (mDeviceInfo->mDeviceProperties) {
+			int count = mDeviceInfo->mDeviceProperties->size();
+			for (int i = 0; i < count; i++) {
+				MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
+				MtpProperty* property = getDevicePropDesc(propCode);
+				if (property)
+					mDeviceProperties.push(property);
+			}
+		}
+	}
+}
+
+void MtpDevice::close() {
+	if (mDevice) {
+		usb_device_release_interface(mDevice, mInterface);
+		usb_device_close(mDevice);
+		mDevice = NULL;
+	}
+}
+
+void MtpDevice::print() {
+	if (mDeviceInfo) {
+		mDeviceInfo->print();
+
+		if (mDeviceInfo->mDeviceProperties) {
+			MTPI("***** DEVICE PROPERTIES *****\n");
+			int count = mDeviceInfo->mDeviceProperties->size();
+			for (int i = 0; i < count; i++) {
+				MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
+				MtpProperty* property = getDevicePropDesc(propCode);
+				if (property) {
+					property->print();
+					delete property;
+				}
+			}
+		}
+	}
+
+	if (mDeviceInfo->mPlaybackFormats) {
+			MTPI("***** OBJECT PROPERTIES *****\n");
+		int count = mDeviceInfo->mPlaybackFormats->size();
+		for (int i = 0; i < count; i++) {
+			MtpObjectFormat format = (*mDeviceInfo->mPlaybackFormats)[i];
+			MTPI("*** FORMAT: %s\n", MtpDebug::getFormatCodeName(format));
+			MtpObjectPropertyList* props = getObjectPropsSupported(format);
+			if (props) {
+				for (size_t j = 0; j < props->size(); j++) {
+					MtpObjectProperty prop = (*props)[j];
+					MtpProperty* property = getObjectPropDesc(prop, format);
+					if (property) {
+						property->print();
+						delete property;
+					} else {
+						MTPI("could not fetch property: %s",
+								MtpDebug::getObjectPropCodeName(prop));
+					}
+				}
+			}
+		}
+	}
+}
+
+const char* MtpDevice::getDeviceName() {
+	if (mDevice)
+		return usb_device_get_name(mDevice);
+	else
+		return "???";
+}
+
+bool MtpDevice::openSession() {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mSessionID = 0;
+	mTransactionID = 0;
+	MtpSessionID newSession = 1;
+	mRequest.reset();
+	mRequest.setParameter(1, newSession);
+	if (!sendRequest(MTP_OPERATION_OPEN_SESSION))
+		return false;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_SESSION_ALREADY_OPEN)
+		newSession = mResponse.getParameter(1);
+	else if (ret != MTP_RESPONSE_OK)
+		return false;
+
+	mSessionID = newSession;
+	mTransactionID = 1;
+	return true;
+}
+
+bool MtpDevice::closeSession() {
+	// FIXME
+	return true;
+}
+
+MtpDeviceInfo* MtpDevice::getDeviceInfo() {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		MtpDeviceInfo* info = new MtpDeviceInfo;
+		info->read(mData);
+		return info;
+	}
+	return NULL;
+}
+
+MtpStorageIDList* MtpDevice::getStorageIDs() {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		return mData.getAUInt32();
+	}
+	return NULL;
+}
+
+MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	mRequest.setParameter(1, storageID);
+	if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		MtpStorageInfo* info = new MtpStorageInfo(storageID);
+		info->read(mData);
+		return info;
+	}
+	return NULL;
+}
+
+MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
+			MtpObjectFormat format, MtpObjectHandle parent) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	mRequest.setParameter(1, storageID);
+	mRequest.setParameter(2, format);
+	mRequest.setParameter(3, parent);
+	if (!sendRequest(MTP_OPERATION_GET_OBJECT_HANDLES))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		return mData.getAUInt32();
+	}
+	return NULL;
+}
+
+MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	// FIXME - we might want to add some caching here
+
+	mRequest.reset();
+	mRequest.setParameter(1, handle);
+	if (!sendRequest(MTP_OPERATION_GET_OBJECT_INFO))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		MtpObjectInfo* info = new MtpObjectInfo(handle);
+		info->read(mData);
+		return info;
+	}
+	return NULL;
+}
+
+void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	mRequest.setParameter(1, handle);
+	if (sendRequest(MTP_OPERATION_GET_THUMB) && readData()) {
+		MtpResponseCode ret = readResponse();
+		if (ret == MTP_RESPONSE_OK) {
+			return mData.getData(outLength);
+		}
+	}
+	outLength = 0;
+	return NULL;
+}
+
+MtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	MtpObjectHandle parent = info->mParent;
+	if (parent == 0)
+		parent = MTP_PARENT_ROOT;
+
+	mRequest.setParameter(1, info->mStorageID);
+	mRequest.setParameter(2, info->mParent);
+
+	mData.putUInt32(info->mStorageID);
+	mData.putUInt16(info->mFormat);
+	mData.putUInt16(info->mProtectionStatus);
+	mData.putUInt32(info->mCompressedSize);
+	mData.putUInt16(info->mThumbFormat);
+	mData.putUInt32(info->mThumbCompressedSize);
+	mData.putUInt32(info->mThumbPixWidth);
+	mData.putUInt32(info->mThumbPixHeight);
+	mData.putUInt32(info->mImagePixWidth);
+	mData.putUInt32(info->mImagePixHeight);
+	mData.putUInt32(info->mImagePixDepth);
+	mData.putUInt32(info->mParent);
+	mData.putUInt16(info->mAssociationType);
+	mData.putUInt32(info->mAssociationDesc);
+	mData.putUInt32(info->mSequenceNumber);
+	mData.putString(info->mName);
+
+	char created[100], modified[100];
+	formatDateTime(info->mDateCreated, created, sizeof(created));
+	formatDateTime(info->mDateModified, modified, sizeof(modified));
+
+	mData.putString(created);
+	mData.putString(modified);
+	if (info->mKeywords)
+		mData.putString(info->mKeywords);
+	else
+		mData.putEmptyString();
+
+   if (sendRequest(MTP_OPERATION_SEND_OBJECT_INFO) && sendData()) {
+		MtpResponseCode ret = readResponse();
+		if (ret == MTP_RESPONSE_OK) {
+			info->mStorageID = mResponse.getParameter(1);
+			info->mParent = mResponse.getParameter(2);
+			info->mHandle = mResponse.getParameter(3);
+			return info->mHandle;
+		}
+	}
+	return (MtpObjectHandle)-1;
+}
+
+bool MtpDevice::sendObject(MtpObjectInfo* info, int srcFD) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	int remaining = info->mCompressedSize;
+	mRequest.reset();
+	mRequest.setParameter(1, info->mHandle);
+	if (sendRequest(MTP_OPERATION_SEND_OBJECT)) {
+		// send data header
+		writeDataHeader(MTP_OPERATION_SEND_OBJECT, remaining);
+
+		char buffer[65536];
+		while (remaining > 0) {
+			int count = read(srcFD, buffer, sizeof(buffer));
+			if (count > 0) {
+				int written = mData.write(mRequestOut, buffer, count);
+				// FIXME check error
+				remaining -= count;
+			} else {
+				break;
+			}
+		}
+	}
+	MtpResponseCode ret = readResponse();
+	return (remaining == 0 && ret == MTP_RESPONSE_OK);
+}
+
+bool MtpDevice::deleteObject(MtpObjectHandle handle) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	mRequest.setParameter(1, handle);
+	if (sendRequest(MTP_OPERATION_DELETE_OBJECT)) {
+		MtpResponseCode ret = readResponse();
+		if (ret == MTP_RESPONSE_OK)
+			return true;
+	}
+	return false;
+}
+
+MtpObjectHandle MtpDevice::getParent(MtpObjectHandle handle) {
+	MtpObjectInfo* info = getObjectInfo(handle);
+	if (info) {
+		MtpObjectHandle parent = info->mParent;
+		delete info;
+		return parent;
+	} else {
+		return -1;
+	}
+}
+
+MtpObjectHandle MtpDevice::getStorageID(MtpObjectHandle handle) {
+	MtpObjectInfo* info = getObjectInfo(handle);
+	if (info) {
+		MtpObjectHandle storageId = info->mStorageID;
+		delete info;
+		return storageId;
+	} else {
+		return -1;
+	}
+}
+
+MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	mRequest.setParameter(1, format);
+	if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		return mData.getAUInt16();
+	}
+	return NULL;
+
+}
+
+MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	mRequest.setParameter(1, code);
+	if (!sendRequest(MTP_OPERATION_GET_DEVICE_PROP_DESC))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		MtpProperty* property = new MtpProperty;
+		property->read(mData);
+		return property;
+	}
+	return NULL;
+}
+
+MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) {
+	android::Mutex::Autolock autoLock(mMutex);
+
+	mRequest.reset();
+	mRequest.setParameter(1, code);
+	mRequest.setParameter(2, format);
+	if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROP_DESC))
+		return NULL;
+	if (!readData())
+		return NULL;
+	MtpResponseCode ret = readResponse();
+	if (ret == MTP_RESPONSE_OK) {
+		MtpProperty* property = new MtpProperty;
+		property->read(mData);
+		return property;
+	}
+	return NULL;
+}
+
+bool MtpDevice::readObject(MtpObjectHandle handle,
+		bool (* callback)(void* data, int offset, int length, void* clientData),
+		int objectSize, void* clientData) {
+	android::Mutex::Autolock autoLock(mMutex);
+	bool result = false;
+
+	mRequest.reset();
+	mRequest.setParameter(1, handle);
+	if (sendRequest(MTP_OPERATION_GET_OBJECT)
+			&& mData.readDataHeader(mRequestIn1)) {
+		uint32_t length = mData.getContainerLength();
+		if ((int)length - MTP_CONTAINER_HEADER_SIZE != objectSize) {
+			MTPE("readObject error objectSize: %d, length: %d",
+					objectSize, length);
+			goto fail;
+		}
+		length -= MTP_CONTAINER_HEADER_SIZE;
+		uint32_t remaining = length;
+		int offset = 0;
+
+		int initialDataLength = 0;
+		void* initialData = mData.getData(initialDataLength);
+		if (initialData) {
+			if (initialDataLength > 0) {
+				if (!callback(initialData, 0, initialDataLength, clientData))
+					goto fail;
+				remaining -= initialDataLength;
+				offset += initialDataLength;
+			}
+			free(initialData);
+		}
+
+		// USB reads greater than 16K don't work
+		char buffer1[16384], buffer2[16384];
+		mRequestIn1->buffer = buffer1;
+		mRequestIn2->buffer = buffer2;
+		struct usb_request* req = mRequestIn1;
+		void* writeBuffer = NULL;
+		int writeLength = 0;
+
+		while (remaining > 0 || writeBuffer) {
+			if (remaining > 0) {
+				// queue up a read request
+				req->buffer_length = (remaining > sizeof(buffer1) ? sizeof(buffer1) : remaining);
+				if (mData.readDataAsync(req)) {
+					MTPE("readDataAsync failed");
+					goto fail;
+				}
+			} else {
+				req = NULL;
+			}
+
+			if (writeBuffer) {
+				// write previous buffer
+				if (!callback(writeBuffer, offset, writeLength, clientData)) {
+					MTPE("write failed");
+					// wait for pending read before failing
+					if (req)
+						mData.readDataWait(mDevice);
+					goto fail;
+				}
+				offset += writeLength;
+				writeBuffer = NULL;
+			}
+
+			// wait for read to complete
+			if (req) {
+				int read = mData.readDataWait(mDevice);
+				if (read < 0)
+					goto fail;
+
+				if (read > 0) {
+					writeBuffer = req->buffer;
+					writeLength = read;
+					remaining -= read;
+					req = (req == mRequestIn1 ? mRequestIn2 : mRequestIn1);
+				} else {
+					writeBuffer = NULL;
+				}
+			}
+		}
+
+		MtpResponseCode response = readResponse();
+		if (response == MTP_RESPONSE_OK)
+			result = true;
+	}
+
+fail:
+	return result;
+}
+
+
+// reads the object's data and writes it to the specified file path
+bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) {
+	MTPI("readObject: %s", destPath);
+	int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC, 0640);
+	if (fd < 0) {
+		MTPE("open failed for %s", destPath);
+		return false;
+	}
+
+	fchown(fd, getuid(), group);
+	// set permissions
+	int mask = umask(0);
+	fchmod(fd, perm);
+	umask(mask);
+
+	android::Mutex::Autolock autoLock(mMutex);
+	bool result = false;
+
+	mRequest.reset();
+	mRequest.setParameter(1, handle);
+	if (sendRequest(MTP_OPERATION_GET_OBJECT)
+			&& mData.readDataHeader(mRequestIn1)) {
+		uint32_t length = mData.getContainerLength();
+		if (length < MTP_CONTAINER_HEADER_SIZE)
+			goto fail;
+		length -= MTP_CONTAINER_HEADER_SIZE;
+		uint32_t remaining = length;
+
+		int initialDataLength = 0;
+		void* initialData = mData.getData(initialDataLength);
+		if (initialData) {
+			if (initialDataLength > 0) {
+				if (write(fd, initialData, initialDataLength) != initialDataLength) {
+					free(initialData);
+					goto fail;
+				}
+				remaining -= initialDataLength;
+			}
+			free(initialData);
+		}
+
+		// USB reads greater than 16K don't work
+		char buffer1[16384], buffer2[16384];
+		mRequestIn1->buffer = buffer1;
+		mRequestIn2->buffer = buffer2;
+		struct usb_request* req = mRequestIn1;
+		void* writeBuffer = NULL;
+		int writeLength = 0;
+
+		while (remaining > 0 || writeBuffer) {
+			if (remaining > 0) {
+				// queue up a read request
+				req->buffer_length = (remaining > sizeof(buffer1) ? sizeof(buffer1) : remaining);
+				if (mData.readDataAsync(req)) {
+					MTPE("readDataAsync failed");
+					goto fail;
+				}
+			} else {
+				req = NULL;
+			}
+
+			if (writeBuffer) {
+				// write previous buffer
+				if (write(fd, writeBuffer, writeLength) != writeLength) {
+					MTPE("write failed");
+					// wait for pending read before failing
+					if (req)
+						mData.readDataWait(mDevice);
+					goto fail;
+				}
+				writeBuffer = NULL;
+			}
+
+			// wait for read to complete
+			if (req) {
+				int read = mData.readDataWait(mDevice);
+				if (read < 0)
+					goto fail;
+
+				if (read > 0) {
+					writeBuffer = req->buffer;
+					writeLength = read;
+					remaining -= read;
+					req = (req == mRequestIn1 ? mRequestIn2 : mRequestIn1);
+				} else {
+					writeBuffer = NULL;
+				}
+			}
+		}
+
+		MtpResponseCode response = readResponse();
+		if (response == MTP_RESPONSE_OK)
+			result = true;
+	}
+
+fail:
+	::close(fd);
+	return result;
+}
+
+bool MtpDevice::sendRequest(MtpOperationCode operation) {
+	MTPD("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation));
+	mReceivedResponse = false;
+	mRequest.setOperationCode(operation);
+	if (mTransactionID > 0)
+		mRequest.setTransactionID(mTransactionID++);
+	int ret = mRequest.write(mRequestOut);
+	mRequest.dump();
+	return (ret > 0);
+}
+
+bool MtpDevice::sendData() {
+	MTPD("sendData\n");
+	mData.setOperationCode(mRequest.getOperationCode());
+	mData.setTransactionID(mRequest.getTransactionID());
+	int ret = mData.write(mRequestOut);
+	mData.dump();
+	return (ret > 0);
+}
+
+bool MtpDevice::readData() {
+	mData.reset();
+	int ret = mData.read(mRequestIn1);
+	MTPD("readData returned %d\n", ret);
+	if (ret >= MTP_CONTAINER_HEADER_SIZE) {
+		if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
+			MTPD("got response packet instead of data packet");
+			// we got a response packet rather than data
+			// copy it to mResponse
+			mResponse.copyFrom(mData);
+			mReceivedResponse = true;
+			return false;
+		}
+		mData.dump();
+		return true;
+	}
+	else {
+		MTPE("readResponse failed\n");
+		return false;
+	}
+}
+
+bool MtpDevice::writeDataHeader(MtpOperationCode operation, int dataLength) {
+	mData.setOperationCode(operation);
+	mData.setTransactionID(mRequest.getTransactionID());
+	return (!mData.writeDataHeader(mRequestOut, dataLength));
+}
+
+MtpResponseCode MtpDevice::readResponse() {
+	MTPD("readResponse\n");
+	if (mReceivedResponse) {
+		mReceivedResponse = false;
+		return mResponse.getResponseCode();
+	}
+	int ret = mResponse.read(mRequestIn1);
+	// handle zero length packets, which might occur if the data transfer
+	// ends on a packet boundary
+	if (ret == 0)
+		ret = mResponse.read(mRequestIn1);
+	if (ret >= MTP_CONTAINER_HEADER_SIZE) {
+		mResponse.dump();
+		return mResponse.getResponseCode();
+	} else {
+		MTPE("readResponse failed\n");
+		return -1;
+	}
+}
