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

Commit 767c5e4b authored by Mike Lockwood's avatar Mike Lockwood
Browse files

MTP: Implement GetObjectPropDesc



Change-Id: I283651257254fc9cd9d93eab4605c5e33d3db93e
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 98ef64e4
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -245,7 +245,7 @@ MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
    MtpResponseCode ret = readResponse();
    MtpResponseCode ret = readResponse();
    if (ret == MTP_RESPONSE_OK) {
    if (ret == MTP_RESPONSE_OK) {
        MtpProperty* property = new MtpProperty;
        MtpProperty* property = new MtpProperty;
        property->read(mData);
        property->read(mData, true);
        return property;
        return property;
    }
    }
    return NULL;
    return NULL;
+132 −2
Original line number Original line Diff line number Diff line
@@ -41,6 +41,58 @@ MtpProperty::MtpProperty()
    mMaximumValue.str = NULL;
    mMaximumValue.str = NULL;
}
}


MtpProperty::MtpProperty(MtpPropertyCode propCode,
                         MtpDataType type,
                         bool writeable,
                         int defaultValue)
    :   mCode(propCode),
        mType(type),
        mWriteable(writeable),
        mDefaultArrayLength(0),
        mDefaultArrayValues(NULL),
        mCurrentArrayLength(0),
        mCurrentArrayValues(NULL),
        mFormFlag(kFormNone),
        mEnumLength(0),
        mEnumValues(NULL)
{
    memset(&mDefaultValue, 0, sizeof(mDefaultValue));
    memset(&mCurrentValue, 0, sizeof(mCurrentValue));
    memset(&mMinimumValue, 0, sizeof(mMinimumValue));
    memset(&mMaximumValue, 0, sizeof(mMaximumValue));

    if (defaultValue) {
        switch (type) {
            case MTP_TYPE_INT8:
                mDefaultValue.i8 = defaultValue;
                break;
            case MTP_TYPE_UINT8:
                mDefaultValue.u8 = defaultValue;
                break;
            case MTP_TYPE_INT16:
                mDefaultValue.i16 = defaultValue;
                break;
            case MTP_TYPE_UINT16:
                mDefaultValue.u16 = defaultValue;
                break;
            case MTP_TYPE_INT32:
                mDefaultValue.i32 = defaultValue;
                break;
            case MTP_TYPE_UINT32:
                mDefaultValue.u32 = defaultValue;
                break;
            case MTP_TYPE_INT64:
                mDefaultValue.i64 = defaultValue;
                break;
            case MTP_TYPE_UINT64:
                mDefaultValue.u64 = defaultValue;
                break;
            default:
                LOGE("unknown type %d in MtpProperty::MtpProperty", type);
        }
    }
}

MtpProperty::~MtpProperty() {
MtpProperty::~MtpProperty() {
    if (mType == MTP_TYPE_STR) {
    if (mType == MTP_TYPE_STR) {
        // free all strings
        // free all strings
@@ -66,7 +118,7 @@ MtpProperty::~MtpProperty() {
    delete[] mEnumValues;
    delete[] mEnumValues;
}
}


void MtpProperty::read(MtpDataPacket& packet) {
void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) {
    MtpStringBuffer string;
    MtpStringBuffer string;


    mCode = packet.getUInt16();
    mCode = packet.getUInt16();
@@ -88,6 +140,7 @@ void MtpProperty::read(MtpDataPacket& packet) {
            break;
            break;
        default:
        default:
            readValue(packet, mDefaultValue);
            readValue(packet, mDefaultValue);
            if (deviceProp)
                readValue(packet, mCurrentValue);
                readValue(packet, mCurrentValue);
    }
    }
    mFormFlag = packet.getUInt8();
    mFormFlag = packet.getUInt8();
@@ -104,6 +157,40 @@ void MtpProperty::read(MtpDataPacket& packet) {
    }
    }
}
}


// FIXME - only works for object properties
void MtpProperty::write(MtpDataPacket& packet) {
    packet.putUInt16(mCode);
    packet.putUInt16(mType);
    packet.putUInt8(mWriteable ? 1 : 0);

    switch (mType) {
        case MTP_TYPE_AINT8:
        case MTP_TYPE_AUINT8:
        case MTP_TYPE_AINT16:
        case MTP_TYPE_AUINT16:
        case MTP_TYPE_AINT32:
        case MTP_TYPE_AUINT32:
        case MTP_TYPE_AINT64:
        case MTP_TYPE_AUINT64:
        case MTP_TYPE_AINT128:
        case MTP_TYPE_AUINT128:
            writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength);
            break;
        default:
            writeValue(packet, mDefaultValue);
    }
    packet.putUInt8(mFormFlag);
    if (mFormFlag == kFormRange) {
            writeValue(packet, mMinimumValue);
            writeValue(packet, mMaximumValue);
            writeValue(packet, mStepSize);
    } else if (mFormFlag == kFormEnum) {
        packet.putUInt16(mEnumLength);
        for (int i = 0; i < mEnumLength; i++)
            writeValue(packet, mEnumValues[i]);
    }
}

void MtpProperty::print() {
void MtpProperty::print() {
    LOGD("MtpProperty %04X\n", mCode);
    LOGD("MtpProperty %04X\n", mCode);
    LOGD("    type %04X\n", mType);
    LOGD("    type %04X\n", mType);
@@ -147,6 +234,43 @@ void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
    }
    }
}
}


void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {
    switch (mType) {
        case MTP_TYPE_INT8:
            packet.putInt8(value.i8);
            break;
        case MTP_TYPE_UINT8:
            packet.putUInt8(value.u8);
            break;
        case MTP_TYPE_INT16:
            packet.putInt16(value.i16);
            break;
        case MTP_TYPE_UINT16:
            packet.putUInt16(value.u16);
            break;
        case MTP_TYPE_INT32:
            packet.putInt32(value.i32);
            break;
        case MTP_TYPE_UINT32:
            packet.putUInt32(value.u32);
            break;
        case MTP_TYPE_INT64:
            packet.putInt64(value.i64);
            break;
        case MTP_TYPE_UINT64:
            packet.putUInt64(value.u64);
            break;
        case MTP_TYPE_INT128:
            packet.putInt128(value.i128);
            break;
        case MTP_TYPE_UINT128:
            packet.putUInt128(value.u128);
            break;
        default:
            LOGE("unknown type %d in MtpProperty::readValue", mType);
    }
}

MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) {
MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) {
    length = packet.getUInt32();
    length = packet.getUInt32();
    if (length == 0)
    if (length == 0)
@@ -157,4 +281,10 @@ MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& lengt
    return result;
    return result;
}
}


void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) {
    packet.putUInt32(length);
    for (int i = 0; i < length; i++)
        writeValue(packet, values[i]);
}

}  // namespace android
}  // namespace android
+10 −1
Original line number Original line Diff line number Diff line
@@ -55,15 +55,24 @@ public:


public:
public:
                        MtpProperty();
                        MtpProperty();
                        MtpProperty(MtpPropertyCode propCode,
                                     MtpDataType type,
                                     bool writeable = false,
                                     int defaultValue = 0);
    virtual             ~MtpProperty();
    virtual             ~MtpProperty();


    void                read(MtpDataPacket& packet);
    inline MtpPropertyCode getPropertyCode() const { return mCode; }

    void                read(MtpDataPacket& packet, bool deviceProp);
    void                write(MtpDataPacket& packet);


    void                print();
    void                print();


private:
private:
    void                readValue(MtpDataPacket& packet, MtpPropertyValue& value);
    void                readValue(MtpDataPacket& packet, MtpPropertyValue& value);
    void                writeValue(MtpDataPacket& packet, MtpPropertyValue& value);
    MtpPropertyValue*   readArrayValues(MtpDataPacket& packet, int& length);
    MtpPropertyValue*   readArrayValues(MtpDataPacket& packet, int& length);
    void                writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length);
};
};


}; // namespace android
}; // namespace android
+40 −11
Original line number Original line Diff line number Diff line
@@ -14,8 +14,6 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#define LOG_TAG "MtpServer"

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/types.h>
@@ -27,11 +25,11 @@
#include <cutils/properties.h>
#include <cutils/properties.h>


#include "MtpDebug.h"
#include "MtpDebug.h"
#include "MtpDatabase.h"
#include "MtpProperty.h"
#include "MtpServer.h"
#include "MtpServer.h"
#include "MtpStorage.h"
#include "MtpStorage.h"
#include "MtpStringBuffer.h"
#include "MtpStringBuffer.h"
#include "MtpDatabase.h"
#include "MtpDebug.h"


#include "f_mtp.h"
#include "f_mtp.h"


@@ -126,6 +124,8 @@ MtpServer::MtpServer(int fd, const char* databasePath)
{
{
    mDatabase = new MtpDatabase();
    mDatabase = new MtpDatabase();
    mDatabase->open(databasePath, true);
    mDatabase->open(databasePath, true);

    initObjectProperties();
}
}


MtpServer::~MtpServer() {
MtpServer::~MtpServer() {
@@ -157,7 +157,7 @@ void MtpServer::scanStorage() {
void MtpServer::run() {
void MtpServer::run() {
    int fd = mFD;
    int fd = mFD;


    LOGD("MtpServer::run fd: %d", fd);
    LOGV("MtpServer::run fd: %d\n", fd);


    while (1) {
    while (1) {
        int ret = mRequest.read(fd);
        int ret = mRequest.read(fd);
@@ -222,11 +222,37 @@ void MtpServer::run() {
                break;
                break;
            }
            }
        } else {
        } else {
            LOGV("skipping response");
            LOGV("skipping response\n");
        }
        }
    }
    }
}
}


MtpProperty* MtpServer::getObjectProperty(MtpPropertyCode propCode) {
    for (int i = 0; i < mObjectProperties.size(); i++) {
        MtpProperty* property = mObjectProperties[i];
        if (property->getPropertyCode() == propCode)
            return property;
    }
    return NULL;
}

MtpProperty* MtpServer::getDeviceProperty(MtpPropertyCode propCode) {
    for (int i = 0; i < mDeviceProperties.size(); i++) {
        MtpProperty* property = mDeviceProperties[i];
        if (property->getPropertyCode() == propCode)
            return property;
    }
    return NULL;
}

void MtpServer::initObjectProperties() {
    mObjectProperties.push(new MtpProperty(MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT16));
    mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16));
    mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64));
    mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR));
    mObjectProperties.push(new MtpProperty(MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32));
}

bool MtpServer::handleRequest() {
bool MtpServer::handleRequest() {
    MtpOperationCode operation = mRequest.getOperationCode();
    MtpOperationCode operation = mRequest.getOperationCode();
    MtpResponseCode response;
    MtpResponseCode response;
@@ -280,6 +306,8 @@ bool MtpServer::handleRequest() {
            response = doDeleteObject();
            response = doDeleteObject();
            break;
            break;
        case MTP_OPERATION_GET_OBJECT_PROP_DESC:
        case MTP_OPERATION_GET_OBJECT_PROP_DESC:
            response = doGetObjectPropDesc();
            break;
        default:
        default:
            response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
            response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED;
            break;
            break;
@@ -489,9 +517,6 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
    time_t modifiedTime;
    time_t modifiedTime;
    if (!parseDateTime(modified, modifiedTime))
    if (!parseDateTime(modified, modifiedTime))
        modifiedTime = 0;
        modifiedTime = 0;
    LOGV("SendObjectInfo format: %04X size: %d name: %s, created: %s, modified: %s",
            format, mSendObjectFileSize, (const char*)name, (const char*)created,
            (const char*)modified);


    if (path[path.size() - 1] != '/')
    if (path[path.size() - 1] != '/')
        path += "/";
        path += "/";
@@ -589,10 +614,14 @@ MtpResponseCode MtpServer::doDeleteObject() {
}
}


MtpResponseCode MtpServer::doGetObjectPropDesc() {
MtpResponseCode MtpServer::doGetObjectPropDesc() {
    MtpObjectProperty property = mRequest.getParameter(1);
    MtpObjectProperty propCode = mRequest.getParameter(1);
    MtpObjectFormat format = mRequest.getParameter(2);
    MtpObjectFormat format = mRequest.getParameter(2);
    MtpProperty* property = getObjectProperty(propCode);
    if (!property)
        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;


    return -1;
    property->write(mData);
    return MTP_RESPONSE_OK;
}
}


}  // namespace android
}  // namespace android
+9 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ namespace android {


class MtpStorage;
class MtpStorage;
class MtpDatabase;
class MtpDatabase;
class MtpProperty;


class MtpServer {
class MtpServer {


@@ -51,6 +52,9 @@ private:


    MtpStorageList      mStorages;
    MtpStorageList      mStorages;


    MtpPropertyList     mObjectProperties;
    MtpPropertyList     mDeviceProperties;

    // handle for new object, set by SendObjectInfo and used by SendObject
    // handle for new object, set by SendObjectInfo and used by SendObject
    MtpObjectHandle     mSendObjectHandle;
    MtpObjectHandle     mSendObjectHandle;
    MtpString           mSendObjectFilePath;
    MtpString           mSendObjectFilePath;
@@ -66,7 +70,12 @@ public:
    void                scanStorage();
    void                scanStorage();
    void                run();
    void                run();


    MtpProperty*        getObjectProperty(MtpPropertyCode propCode);
    MtpProperty*        getDeviceProperty(MtpPropertyCode propCode);

private:
private:
    void                initObjectProperties();

    bool                handleRequest();
    bool                handleRequest();


    MtpResponseCode     doGetDeviceInfo();
    MtpResponseCode     doGetDeviceInfo();