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>
This commit is contained in:
Mike Lockwood
2010-11-23 09:08:01 -05:00
parent 5b19af05f2
commit 44e82ddaec
3 changed files with 46 additions and 3 deletions

View File

@@ -123,7 +123,7 @@ void MtpPacket::setTransactionID(MtpTransactionID id) {
uint32_t MtpPacket::getParameter(int index) const {
if (index < 1 || index > 5) {
LOGE("index %d out of range in MtpRequestPacket::getParameter", index);
LOGE("index %d out of range in MtpPacket::getParameter", index);
return 0;
}
return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t));
@@ -131,7 +131,7 @@ uint32_t MtpPacket::getParameter(int index) const {
void MtpPacket::setParameter(int index, uint32_t value) {
if (index < 1 || index > 5) {
LOGE("index %d out of range in MtpResponsePacket::setParameter", index);
LOGE("index %d out of range in MtpPacket::setParameter", index);
return;
}
int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t);

View File

@@ -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);

View File

@@ -96,6 +96,7 @@ private:
MtpResponseCode doGetObjectPropList();
MtpResponseCode doGetObjectInfo();
MtpResponseCode doGetObject();
MtpResponseCode doGetPartialObject();
MtpResponseCode doSendObjectInfo();
MtpResponseCode doSendObject();
MtpResponseCode doDeleteObject();