More work on PTP host support.

Change-Id: Ifbd5bd5efa3cdb750ae1a2aae38181457554d34d
Signed-off-by: Mike Lockwood <mike@spruce.(none)>
This commit is contained in:
Mike Lockwood
2010-05-19 10:33:39 -04:00
committed by Mike Lockwood
parent ec4eff80cd
commit 5bae7f615b
20 changed files with 507 additions and 71 deletions

View File

@@ -57,13 +57,17 @@ LOCAL_SRC_FILES:= \
MtpClient.cpp \
MtpDataPacket.cpp \
MtpDebug.cpp \
MtpDeviceInfo.cpp \
MtpPacket.cpp \
MtpRequestPacket.cpp \
MtpResponsePacket.cpp \
MtpStorageInfo.cpp \
MtpStringBuffer.cpp \
../../libs/utils/VectorImpl.cpp \
../../libs/utils/SharedBuffer.cpp \
LOCAL_STATIC_LIBRARIES := libusbhost
LOCAL_STATIC_LIBRARIES := libusbhost libcutils
LOCAL_LDLIBS := -lpthread
LOCAL_CFLAGS := -g -DMTP_HOST

View File

@@ -26,6 +26,8 @@
#include "MtpClient.h"
#include "MtpDebug.h"
#include "MtpDeviceInfo.h"
#include "MtpStorageInfo.h"
#include "MtpStringBuffer.h"
namespace android {
@@ -65,30 +67,55 @@ printf("openSession\n");
return true;
}
bool MtpClient::getDeviceInfo() {
mRequest.reset();
if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
return false;
if (!readData())
return false;
MtpResponseCode ret = readResponse();
if (ret == MTP_RESPONSE_OK) {
MtpStringBuffer string;
// fill in device info
printf("MTP standard version: %d\n", mData.getUInt16());
printf("MTP Vendor Extension ID: %d\n", mData.getUInt32());
printf("MTP vendor extension version: %d\n", mData.getUInt16());
mData.getString(string);
printf("vendor extension desc %s\n", (const char *)string);
return true;
}
return false;
bool MtpClient::closeSession() {
// FIXME
return true;
}
bool MtpClient::closeSession() {
return true;
MtpDeviceInfo* MtpClient::getDeviceInfo() {
mRequest.reset();
if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
return NULL;
if (!readData())
return NULL;
MtpResponseCode ret = readResponse();
printf("getDeviceInfo returned %04X\n", ret);
if (ret == MTP_RESPONSE_OK) {
MtpDeviceInfo* info = new MtpDeviceInfo;
info->read(mData);
return info;
}
return NULL;
}
MtpStorageIDList* MtpClient::getStorageIDs() {
mRequest.reset();
if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
return NULL;
if (!readData())
return NULL;
MtpResponseCode ret = readResponse();
if (ret == MTP_RESPONSE_OK) {
return mData.getAUInt32();
}
return NULL;
}
MtpStorageInfo* MtpClient::getStorageInfo(MtpStorageID storageID) {
mRequest.reset();
mRequest.setParameter(1, storageID);
if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO))
return NULL;
if (!readData())
return NULL;
MtpResponseCode ret = readResponse();
printf("getStorageInfo returned %04X\n", ret);
if (ret == MTP_RESPONSE_OK) {
MtpStorageInfo* info = new MtpStorageInfo(storageID);
info->read(mData);
return info;
}
return NULL;
}
bool MtpClient::sendRequest(MtpOperationCode operation) {
@@ -111,7 +138,8 @@ bool MtpClient::sendData(MtpOperationCode operation) {
}
bool MtpClient::readData() {
int ret = mData.read(mEndpointIn);
mData.reset();
int ret = mData.read(mEndpointIn);
printf("readData returned %d\n", ret);
if (ret >= MTP_CONTAINER_HEADER_SIZE) {
mData.dump();

View File

@@ -20,12 +20,13 @@
#include "MtpRequestPacket.h"
#include "MtpDataPacket.h"
#include "MtpResponsePacket.h"
#include "mtp.h"
#include "MtpUtils.h"
#include "MtpTypes.h"
namespace android {
class MtpDeviceInfo;
class MtpStorageInfo;
class MtpClient {
private:
struct usb_endpoint *mEndpointIn;
@@ -47,9 +48,12 @@ public:
virtual ~MtpClient();
bool openSession();
bool getDeviceInfo();
bool closeSession();
MtpDeviceInfo* getDeviceInfo();
MtpStorageIDList* getStorageIDs();
MtpStorageInfo* getStorageInfo(MtpStorageID storageID);
private:
bool sendRequest(MtpOperationCode operation);
bool sendData(MtpOperationCode operation);

View File

@@ -75,6 +75,70 @@ void MtpDataPacket::getString(MtpStringBuffer& string)
string.readFromPacket(this);
}
Int8List* MtpDataPacket::getAInt8() {
Int8List* result = new Int8List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getInt8());
return result;
}
UInt8List* MtpDataPacket::getAUInt8() {
UInt8List* result = new UInt8List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getUInt8());
return result;
}
Int16List* MtpDataPacket::getAInt16() {
Int16List* result = new Int16List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getInt16());
return result;
}
UInt16List* MtpDataPacket::getAUInt16() {
UInt16List* result = new UInt16List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getUInt16());
return result;
}
Int32List* MtpDataPacket::getAInt32() {
Int32List* result = new Int32List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getInt32());
return result;
}
UInt32List* MtpDataPacket::getAUInt32() {
UInt32List* result = new UInt32List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getUInt32());
return result;
}
Int64List* MtpDataPacket::getAInt64() {
Int64List* result = new Int64List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getInt64());
return result;
}
UInt64List* MtpDataPacket::getAUInt64() {
UInt64List* result = new UInt64List;
int count = getUInt32();
for (int i = 0; i < count; i++)
result->push(getUInt64());
return result;
}
void MtpDataPacket::putInt8(int8_t value) {
allocate(mOffset + 1);
mBuffer[mOffset++] = (uint8_t)value;

View File

@@ -46,6 +46,15 @@ public:
inline int64_t getInt64() { return (int64_t)getUInt64(); }
void getString(MtpStringBuffer& string);
Int8List* getAInt8();
UInt8List* getAUInt8();
Int16List* getAInt16();
UInt16List* getAUInt16();
Int32List* getAInt32();
UInt32List* getAUInt32();
Int64List* getAInt64();
UInt64List* getAUInt64();
void putInt8(int8_t value);
void putUInt8(uint8_t value);
void putInt16(int16_t value);

View File

@@ -16,6 +16,7 @@
#include "MtpDatabase.h"
#include "MtpDataPacket.h"
#include "MtpUtils.h"
#include "SqliteDatabase.h"
#include "SqliteStatement.h"

View File

@@ -17,9 +17,8 @@
#ifndef _MTP_DATABASE_H
#define _MTP_DATABASE_H
#include "MtpUtils.h"
#include "MtpTypes.h"
#include "SqliteDatabase.h"
#include "mtp.h"
namespace android {

View File

@@ -17,7 +17,7 @@
#ifndef _MTP_DEBUG_H
#define _MTP_DEBUG_H
#include "mtp.h"
#include "MtpTypes.h"
namespace android {

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "MtpDataPacket.h"
#include "MtpDeviceInfo.h"
#include "MtpStringBuffer.h"
namespace android {
MtpDeviceInfo::MtpDeviceInfo()
: mStandardVersion(0),
mVendorExtensionID(0),
mVendorExtensionVersion(0),
mVendorExtensionDesc(NULL),
mFunctionalCode(0),
mOperations(NULL),
mEvents(NULL),
mDeviceProperties(NULL),
mCaptureFormats(NULL),
mPlaybackFormats(NULL),
mManufacturer(NULL),
mModel(NULL),
mVersion(NULL),
mSerial(NULL)
{
}
MtpDeviceInfo::~MtpDeviceInfo() {
if (mVendorExtensionDesc)
free(mVendorExtensionDesc);
delete mOperations;
delete mEvents;
delete mDeviceProperties;
delete mCaptureFormats;
delete mPlaybackFormats;
if (mManufacturer)
free(mManufacturer);
if (mModel)
free(mModel);
if (mVersion)
free(mVersion);
if (mSerial)
free(mSerial);
}
void MtpDeviceInfo::read(MtpDataPacket& packet) {
MtpStringBuffer string;
// read the device info
mStandardVersion = packet.getUInt16();
mVendorExtensionID = packet.getUInt32();
mVendorExtensionVersion = packet.getUInt16();
packet.getString(string);
mVendorExtensionDesc = strdup((const char *)string);
mFunctionalCode = packet.getUInt16();
mOperations = packet.getAUInt16();
mEvents = packet.getAUInt16();
mDeviceProperties = packet.getAUInt16();
mCaptureFormats = packet.getAUInt16();
mPlaybackFormats = packet.getAUInt16();
packet.getString(string);
mManufacturer = strdup((const char *)string);
packet.getString(string);
mModel = strdup((const char *)string);
packet.getString(string);
mVersion = strdup((const char *)string);
packet.getString(string);
mSerial = strdup((const char *)string);
}
void MtpDeviceInfo::print() {
printf("Device Info:\n\tmStandardVersion: %d\n\tmVendorExtensionID: %d\n\tmVendorExtensionVersiony: %d\n",
mStandardVersion, mVendorExtensionID, mVendorExtensionVersion);
printf("\tmVendorExtensionDesc: %s\n\tmFunctionalCode: %d\n\tmManufacturer: %s\n\tmModel: %s\n\tmVersion: %s\n\tmSerial: %s\n",
mVendorExtensionDesc, mFunctionalCode, mManufacturer, mModel, mVersion, mSerial);
}
} // namespace android

54
media/mtp/MtpDeviceInfo.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MTP_DEVICE_INFO_H
#define _MTP_DEVICE_INFO_H
struct stat;
namespace android {
class MtpDataPacket;
class MtpDeviceInfo {
public:
uint16_t mStandardVersion;
uint32_t mVendorExtensionID;
uint16_t mVendorExtensionVersion;
char* mVendorExtensionDesc;
uint16_t mFunctionalCode;
UInt16List* mOperations;
UInt16List* mEvents;
MtpDevicePropertyList* mDeviceProperties;
MtpObjectFormatList* mCaptureFormats;
MtpObjectFormatList* mPlaybackFormats;
char* mManufacturer;
char* mModel;
char* mVersion;
char* mSerial;
public:
MtpDeviceInfo();
virtual ~MtpDeviceInfo();
void read(MtpDataPacket& packet);
void print();
};
}; // namespace android
#endif // _MTP_DEVICE_INFO_H

View File

@@ -16,6 +16,7 @@
#include "MtpDatabase.h"
#include "MtpMediaScanner.h"
#include "mtp.h"
#include <sys/types.h>
#include <sys/stat.h>

View File

@@ -21,6 +21,7 @@
#include <usbhost/usbhost.h>
#include "MtpPacket.h"
#include "mtp.h"
namespace android {

View File

@@ -17,10 +17,7 @@
#ifndef _MTP_PACKET_H
#define _MTP_PACKET_H
#include "mtp.h"
#include "MtpUtils.h"
#include <stdint.h>
#include "MtpTypes.h"
struct usb_endpoint;

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "MtpDataPacket.h"
#include "MtpStorageInfo.h"
#include "MtpStringBuffer.h"
namespace android {
MtpStorageInfo::MtpStorageInfo(MtpStorageID id)
: mStorageID(id),
mStorageType(0),
mFileSystemType(0),
mAccessCapability(0),
mMaxCapacity(0),
mFreeSpaceBytes(0),
mFreeSpaceObjects(0),
mStorageDescription(NULL),
mVolumeIdentifier(NULL)
{
}
MtpStorageInfo::~MtpStorageInfo() {
if (mStorageDescription)
free(mStorageDescription);
if (mVolumeIdentifier)
free(mVolumeIdentifier);
}
void MtpStorageInfo::read(MtpDataPacket& packet) {
MtpStringBuffer string;
// read the device info
mStorageType = packet.getUInt16();
mFileSystemType = packet.getUInt16();
mAccessCapability = packet.getUInt16();
mMaxCapacity = packet.getUInt64();
mFreeSpaceBytes = packet.getUInt64();
mFreeSpaceObjects = packet.getUInt32();
packet.getString(string);
mStorageDescription = strdup((const char *)string);
packet.getString(string);
mVolumeIdentifier = strdup((const char *)string);
}
void MtpStorageInfo::print() {
printf("Storage Info %08X:\n\tmStorageType: %d\n\tmFileSystemType: %d\n\tmAccessCapability: %d\n",
mStorageID, mStorageType, mFileSystemType, mAccessCapability);
printf("\tmMaxCapacity: %lld\n\tmFreeSpaceBytes: %lld\n\tmFreeSpaceObjects: %d\n",
mMaxCapacity, mFreeSpaceBytes, mFreeSpaceObjects);
printf("\tmStorageDescription: %s\n\tmVolumeIdentifier: %s\n",
mStorageDescription, mVolumeIdentifier);
}
} // namespace android

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MTP_STORAGE_INFO_H
#define _MTP_STORAGE_INFO_H
#include "MtpTypes.h"
namespace android {
class MtpDataPacket;
class MtpStorageInfo {
public:
MtpStorageID mStorageID;
uint16_t mStorageType;
uint16_t mFileSystemType;
uint16_t mAccessCapability;
uint64_t mMaxCapacity;
uint64_t mFreeSpaceBytes;
uint32_t mFreeSpaceObjects;
char* mStorageDescription;
char* mVolumeIdentifier;
public:
MtpStorageInfo(MtpStorageID id);
virtual ~MtpStorageInfo();
void read(MtpDataPacket& packet);
void print();
};
}; // namespace android
#endif // _MTP_STORAGE_INFO_H

75
media/mtp/MtpTypes.h Normal file
View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MTP_TYPES_H
#define _MTP_TYPES_H
#include <stdint.h>
#include "utils/String8.h"
#include "utils/Vector.h"
namespace android {
typedef uint16_t MtpOperationCode;
typedef uint16_t MtpResponseCode;
typedef uint32_t MtpSessionID;
typedef uint32_t MtpStorageID;
typedef uint32_t MtpTransactionID;
typedef uint16_t MtpDeviceProperty;
typedef uint16_t MtpObjectFormat;
typedef uint16_t MtpObjectProperty;
// object handles are unique across all storage but only within a single session.
// object handles cannot be reused after an object is deleted.
// values 0x00000000 and 0xFFFFFFFF are reserved for special purposes.
typedef uint32_t MtpObjectHandle;
#define kInvalidObjectHandle 0xFFFFFFFF
// MtpObjectHandle bits and masks
#define kObjectHandleMarkBit 0x80000000 // used for mark & sweep by MtpMediaScanner
#define kObjectHandleTableMask 0x70000000 // mask for object table
#define kObjectHandleTableFile 0x00000000 // object is only in the file table
#define kObjectHandleTableAudio 0x10000000 // object is in the audio table
#define kObjectHandleTableVideo 0x20000000 // object is in the video table
#define kObjectHandleTableImage 0x30000000 // object is in the images table
#define kObjectHandleTablePlaylist 0x40000000 // object is in the playlist table
#define kObjectHandleIndexMask 0x0FFFFFFF // mask for object index in file table
class MtpStorage;
typedef android::Vector<MtpStorage *> MtpStorageList;
typedef android::Vector<uint8_t> UInt8List;
typedef android::Vector<uint32_t> UInt16List;
typedef android::Vector<uint32_t> UInt32List;
typedef android::Vector<uint64_t> UInt64List;
typedef android::Vector<int8_t> Int8List;
typedef android::Vector<int32_t> Int16List;
typedef android::Vector<int32_t> Int32List;
typedef android::Vector<int64_t> Int64List;
typedef UInt16List MtpDevicePropertyList;
typedef UInt16List MtpObjectFormatList;
typedef UInt32List MtpObjectHandleList;
typedef UInt16List MtpObjectPropertyList;
typedef UInt32List MtpStorageIDList;
typedef android::String8 MtpString;
}; // namespace android
#endif // _MTP_TYPES_H

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <stdio.h>
#include <time.h>
#include <cutils/tztime.h>

View File

@@ -17,19 +17,10 @@
#ifndef _MTP_UTILS_H
#define _MTP_UTILS_H
#include "utils/String8.h"
#include "utils/Vector.h"
#include <stdint.h>
namespace android {
class MtpStorage;
typedef android::Vector<MtpStorage *> MtpStorageList;
typedef android::Vector<uint32_t> UInt32List;
typedef UInt32List MtpObjectHandleList;
typedef android::String8 MtpString;
bool parseDateTime(const char* dateTime, time_t& outSeconds);
void formatDateTime(time_t seconds, char* buffer, int bufferLength);

View File

@@ -19,31 +19,6 @@
#include <stdint.h>
typedef uint16_t MtpOperationCode;
typedef uint16_t MtpResponseCode;
typedef uint32_t MtpSessionID;
typedef uint32_t MtpStorageID;
typedef uint32_t MtpTransactionID;
typedef uint16_t MtpObjectFormat;
typedef uint16_t MtpObjectProperty;
// object handles are unique across all storage but only within a single session.
// object handles cannot be reused after an object is deleted.
// values 0x00000000 and 0xFFFFFFFF are reserved for special purposes.
typedef uint32_t MtpObjectHandle;
#define kInvalidObjectHandle 0xFFFFFFFF
// MtpObjectHandle bits and masks
#define kObjectHandleMarkBit 0x80000000 // used for mark & sweep by MtpMediaScanner
#define kObjectHandleTableMask 0x70000000 // mask for object table
#define kObjectHandleTableFile 0x00000000 // object is only in the file table
#define kObjectHandleTableAudio 0x10000000 // object is in the audio table
#define kObjectHandleTableVideo 0x20000000 // object is in the video table
#define kObjectHandleTableImage 0x30000000 // object is in the images table
#define kObjectHandleTablePlaylist 0x40000000 // object is in the playlist table
#define kObjectHandleIndexMask 0x0FFFFFFF // mask for object index in file table
#define MTP_STANDARD_VERSION 100
// Container Types

View File

@@ -22,6 +22,8 @@
#include <linux/usb/ch9.h>
#include "MtpClient.h"
#include "MtpDeviceInfo.h"
#include "MtpStorageInfo.h"
using namespace android;
@@ -37,7 +39,21 @@ static void start_session(struct usb_endpoint *ep_in, struct usb_endpoint *ep_ou
delete sClient;
sClient = new MtpClient(ep_in, ep_out, ep_intr);
sClient->openSession();
sClient->getDeviceInfo();
MtpDeviceInfo* info = sClient->getDeviceInfo();
if (info) {
info->print();
delete info;
}
MtpStorageIDList* storageIDs = sClient->getStorageIDs();
if (storageIDs) {
for (int i = 0; i < storageIDs->size(); i++) {
MtpStorageInfo* info = sClient->getStorageInfo((*storageIDs)[i]);
if (info) {
info->print();
delete info;
}
}
}
}
static void usb_device_added(const char *devname)