From 21ef7d0e70c5ad599bc2602cb484f8cd647055ca Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Wed, 30 Jun 2010 17:00:35 -0400 Subject: MTP: Implement GetObjectPropDesc Change-Id: I283651257254fc9cd9d93eab4605c5e33d3db93e Signed-off-by: Mike Lockwood --- media/mtp/MtpDevice.cpp | 2 +- media/mtp/MtpProperty.cpp | 134 +++++++++++++++++++++++++++++++++++++++++++++- media/mtp/MtpProperty.h | 11 +++- media/mtp/MtpServer.cpp | 51 ++++++++++++++---- media/mtp/MtpServer.h | 9 ++++ 5 files changed, 192 insertions(+), 15 deletions(-) (limited to 'media/mtp') diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp index 5612387..3ceb9b4 100644 --- a/media/mtp/MtpDevice.cpp +++ b/media/mtp/MtpDevice.cpp @@ -245,7 +245,7 @@ MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) { MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpProperty* property = new MtpProperty; - property->read(mData); + property->read(mData, true); return property; } return NULL; diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp index a114e83..8d639a5 100644 --- a/media/mtp/MtpProperty.cpp +++ b/media/mtp/MtpProperty.cpp @@ -41,6 +41,58 @@ MtpProperty::MtpProperty() 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() { if (mType == MTP_TYPE_STR) { // free all strings @@ -66,7 +118,7 @@ MtpProperty::~MtpProperty() { delete[] mEnumValues; } -void MtpProperty::read(MtpDataPacket& packet) { +void MtpProperty::read(MtpDataPacket& packet, bool deviceProp) { MtpStringBuffer string; mCode = packet.getUInt16(); @@ -88,7 +140,8 @@ void MtpProperty::read(MtpDataPacket& packet) { break; default: readValue(packet, mDefaultValue); - readValue(packet, mCurrentValue); + if (deviceProp) + readValue(packet, mCurrentValue); } 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() { LOGD("MtpProperty %04X\n", mCode); 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) { length = packet.getUInt32(); if (length == 0) @@ -157,4 +281,10 @@ MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& lengt 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 diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h index 6372290..4923d40 100644 --- a/media/mtp/MtpProperty.h +++ b/media/mtp/MtpProperty.h @@ -55,15 +55,24 @@ public: public: MtpProperty(); + MtpProperty(MtpPropertyCode propCode, + MtpDataType type, + bool writeable = false, + int defaultValue = 0); virtual ~MtpProperty(); - void read(MtpDataPacket& packet); + inline MtpPropertyCode getPropertyCode() const { return mCode; } + + void read(MtpDataPacket& packet, bool deviceProp); + void write(MtpDataPacket& packet); void print(); private: void readValue(MtpDataPacket& packet, MtpPropertyValue& value); + void writeValue(MtpDataPacket& packet, MtpPropertyValue& value); MtpPropertyValue* readArrayValues(MtpDataPacket& packet, int& length); + void writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length); }; }; // namespace android diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 048d1dc..0b99cb1 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "MtpServer" - #include #include #include @@ -27,11 +25,11 @@ #include #include "MtpDebug.h" +#include "MtpDatabase.h" +#include "MtpProperty.h" #include "MtpServer.h" #include "MtpStorage.h" #include "MtpStringBuffer.h" -#include "MtpDatabase.h" -#include "MtpDebug.h" #include "f_mtp.h" @@ -126,6 +124,8 @@ MtpServer::MtpServer(int fd, const char* databasePath) { mDatabase = new MtpDatabase(); mDatabase->open(databasePath, true); + + initObjectProperties(); } MtpServer::~MtpServer() { @@ -157,7 +157,7 @@ void MtpServer::scanStorage() { void MtpServer::run() { int fd = mFD; - LOGD("MtpServer::run fd: %d", fd); + LOGV("MtpServer::run fd: %d\n", fd); while (1) { int ret = mRequest.read(fd); @@ -222,11 +222,37 @@ void MtpServer::run() { break; } } 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() { MtpOperationCode operation = mRequest.getOperationCode(); MtpResponseCode response; @@ -280,6 +306,8 @@ bool MtpServer::handleRequest() { response = doDeleteObject(); break; case MTP_OPERATION_GET_OBJECT_PROP_DESC: + response = doGetObjectPropDesc(); + break; default: response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED; break; @@ -489,9 +517,6 @@ MtpResponseCode MtpServer::doSendObjectInfo() { time_t modifiedTime; if (!parseDateTime(modified, modifiedTime)) 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] != '/') path += "/"; @@ -589,10 +614,14 @@ MtpResponseCode MtpServer::doDeleteObject() { } MtpResponseCode MtpServer::doGetObjectPropDesc() { - MtpObjectProperty property = mRequest.getParameter(1); + MtpObjectProperty propCode = mRequest.getParameter(1); 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 diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h index 40f3c52..40329c5 100644 --- a/media/mtp/MtpServer.h +++ b/media/mtp/MtpServer.h @@ -28,6 +28,7 @@ namespace android { class MtpStorage; class MtpDatabase; +class MtpProperty; class MtpServer { @@ -51,6 +52,9 @@ private: MtpStorageList mStorages; + MtpPropertyList mObjectProperties; + MtpPropertyList mDeviceProperties; + // handle for new object, set by SendObjectInfo and used by SendObject MtpObjectHandle mSendObjectHandle; MtpString mSendObjectFilePath; @@ -66,7 +70,12 @@ public: void scanStorage(); void run(); + MtpProperty* getObjectProperty(MtpPropertyCode propCode); + MtpProperty* getDeviceProperty(MtpPropertyCode propCode); + private: + void initObjectProperties(); + bool handleRequest(); MtpResponseCode doGetDeviceInfo(); -- cgit v1.1