MTP: Implement GetObjectPropDesc

Change-Id: I283651257254fc9cd9d93eab4605c5e33d3db93e
Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
Mike Lockwood
2010-06-30 17:00:35 -04:00
parent 98ef64e4a8
commit 767c5e4be0
5 changed files with 192 additions and 15 deletions

View File

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

View File

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

View File

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

View File

@@ -14,8 +14,6 @@
* limitations under the License.
*/
#define LOG_TAG "MtpServer"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -27,11 +25,11 @@
#include <cutils/properties.h>
#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

View File

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