From d81ce3cf2e6479915658a0829eced062e3655320 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Tue, 23 Nov 2010 09:08:01 -0500 Subject: MTP: Implement GetPartialObject command Allows host to read partial contents of files on the device Change-Id: I74927f7394224d674e1d150a4b72a51d9358459b Signed-off-by: Mike Lockwood --- media/mtp/MtpServer.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'media/mtp/MtpServer.cpp') diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index ca13636..b841bf3 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -66,7 +66,7 @@ static const MtpOperationCode kSupportedOperationCodes[] = { // MTP_OPERATION_TERMINATE_OPEN_CAPTURE, // MTP_OPERATION_MOVE_OBJECT, // MTP_OPERATION_COPY_OBJECT, -// MTP_OPERATION_GET_PARTIAL_OBJECT, + MTP_OPERATION_GET_PARTIAL_OBJECT, // MTP_OPERATION_INITIATE_OPEN_CAPTURE, MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED, MTP_OPERATION_GET_OBJECT_PROP_DESC, @@ -289,6 +289,9 @@ bool MtpServer::handleRequest() { case MTP_OPERATION_GET_OBJECT: response = doGetObject(); break; + case MTP_OPERATION_GET_PARTIAL_OBJECT: + response = doGetPartialObject(); + break; case MTP_OPERATION_SEND_OBJECT_INFO: response = doSendObjectInfo(); break; @@ -583,6 +586,45 @@ MtpResponseCode MtpServer::doGetObject() { return MTP_RESPONSE_OK; } +MtpResponseCode MtpServer::doGetPartialObject() { + MtpObjectHandle handle = mRequest.getParameter(1); + uint32_t offset = mRequest.getParameter(2); + uint32_t length = mRequest.getParameter(3); + MtpString pathBuf; + int64_t fileLength; + int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength); + if (result != MTP_RESPONSE_OK) + return result; + if (offset + length > fileLength) + length = fileLength - offset; + + const char* filePath = (const char *)pathBuf; + mtp_file_range mfr; + mfr.fd = open(filePath, O_RDONLY); + if (mfr.fd < 0) { + return MTP_RESPONSE_GENERAL_ERROR; + } + mfr.offset = offset; + mfr.length = length; + mResponse.setParameter(1, length); + + // send data header + mData.setOperationCode(mRequest.getOperationCode()); + mData.setTransactionID(mRequest.getTransactionID()); + mData.writeDataHeader(mFD, length + MTP_CONTAINER_HEADER_SIZE); + + // then transfer the file + int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr); + close(mfr.fd); + if (ret < 0) { + if (errno == ECANCELED) + return MTP_RESPONSE_TRANSACTION_CANCELLED; + else + return MTP_RESPONSE_GENERAL_ERROR; + } + return MTP_RESPONSE_OK; +} + MtpResponseCode MtpServer::doSendObjectInfo() { MtpString path; MtpStorageID storageID = mRequest.getParameter(1); -- cgit v1.1