Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44e82dda authored by Mike Lockwood's avatar Mike Lockwood
Browse files

MTP: Implement GetPartialObject command



Allows host to read partial contents of files on the device

Change-Id: I74927f7394224d674e1d150a4b72a51d9358459b
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 5b19af05
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
+43 −1
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ private:
    MtpResponseCode     doGetObjectPropList();
    MtpResponseCode     doGetObjectInfo();
    MtpResponseCode     doGetObject();
    MtpResponseCode     doGetPartialObject();
    MtpResponseCode     doSendObjectInfo();
    MtpResponseCode     doSendObject();
    MtpResponseCode     doDeleteObject();