summaryrefslogtreecommitdiffstats
path: root/media/mtp/MtpServer.cpp
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-11-23 09:08:01 -0500
committerMike Lockwood <lockwood@android.com>2010-11-23 18:45:01 -0500
commitd81ce3cf2e6479915658a0829eced062e3655320 (patch)
treef174670a23626ba7643eb561566a1490fb1ffaa3 /media/mtp/MtpServer.cpp
parentb892d0e5556ed6ded3e0548f75ab16fc2e3d92c3 (diff)
downloadframeworks_av-d81ce3cf2e6479915658a0829eced062e3655320.zip
frameworks_av-d81ce3cf2e6479915658a0829eced062e3655320.tar.gz
frameworks_av-d81ce3cf2e6479915658a0829eced062e3655320.tar.bz2
MTP: Implement GetPartialObject command
Allows host to read partial contents of files on the device Change-Id: I74927f7394224d674e1d150a4b72a51d9358459b Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'media/mtp/MtpServer.cpp')
-rw-r--r--media/mtp/MtpServer.cpp44
1 files changed, 43 insertions, 1 deletions
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);