MtpDevice.cpp revision b14e588bec4d5e39e61b020b5b575f2ce555d316
15ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood/*
25ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
35ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood *
45ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
55ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * you may not use this file except in compliance with the License.
65ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * You may obtain a copy of the License at
75ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood *
85ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
95ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood *
105ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * Unless required by applicable law or agreed to in writing, software
115ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
125ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * See the License for the specific language governing permissions and
145ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood * limitations under the License.
155ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood */
165ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
17a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood#define LOG_TAG "MtpDevice"
18b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood
19b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpDebug.h"
20b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpDevice.h"
21b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpDeviceInfo.h"
22b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpObjectInfo.h"
23b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpProperty.h"
24b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpStorageInfo.h"
25b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpStringBuffer.h"
26a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
275ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <stdio.h>
285ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <stdlib.h>
295ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/types.h>
305ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/ioctl.h>
315ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/stat.h>
325ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <fcntl.h>
335ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <errno.h>
345ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
355ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <usbhost/usbhost.h>
365ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
375ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodnamespace android {
385ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
395ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDevice::MtpDevice(struct usb_device* device, int interface,
405ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood            struct usb_endpoint *ep_in, struct usb_endpoint *ep_out,
415ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood            struct usb_endpoint *ep_intr)
425ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    :   mDevice(device),
435ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mInterface(interface),
445ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mEndpointIn(ep_in),
455ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mEndpointOut(ep_out),
465ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mEndpointIntr(ep_intr),
475ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mDeviceInfo(NULL),
485ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mID(usb_device_get_unique_id(device)),
495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mSessionID(0),
505ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mTransactionID(0)
515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood{
525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
545ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDevice::~MtpDevice() {
555ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    close();
56a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    for (int i = 0; i < mDeviceProperties.size(); i++)
57a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        delete mDeviceProperties[i];
585ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid MtpDevice::initialize() {
615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    openSession();
625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mDeviceInfo = getDeviceInfo();
635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mDeviceInfo) {
645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mDeviceInfo->print();
65a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
66a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        if (mDeviceInfo->mDeviceProperties) {
67a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood            int count = mDeviceInfo->mDeviceProperties->size();
68a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood            for (int i = 0; i < count; i++) {
69a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
70a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                MtpProperty* property = getDevicePropDesc(propCode);
71a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                if (property) {
72a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                    property->print();
73a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                    mDeviceProperties.push(property);
74a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                }
75a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood            }
76a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        }
775ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
785ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
805ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid MtpDevice::close() {
815ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mDevice) {
825ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        usb_device_release_interface(mDevice, mInterface);
835ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        usb_device_close(mDevice);
845ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mDevice = NULL;
855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodconst char* MtpDevice::getDeviceName() {
895ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mDevice)
905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return usb_device_get_name(mDevice);
915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else
925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return "???";
935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::openSession() {
965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mSessionID = 0;
975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mTransactionID = 0;
985ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpSessionID newSession = 1;
995ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1005ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, newSession);
1015ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_OPEN_SESSION))
1025ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return false;
1035ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1045ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_SESSION_ALREADY_OPEN)
1055ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        newSession = mResponse.getParameter(1);
1065ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else if (ret != MTP_RESPONSE_OK)
1075ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return false;
1085ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1095ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mSessionID = newSession;
1105ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mTransactionID = 1;
1115ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return true;
1125ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1135ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1145ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::closeSession() {
1155ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    // FIXME
1165ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return true;
1175ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1185ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1195ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDeviceInfo* MtpDevice::getDeviceInfo() {
1205ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1215ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
1225ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1235ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1245ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1255ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1265ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1275ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        MtpDeviceInfo* info = new MtpDeviceInfo;
1285ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        info->read(mData);
1295ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return info;
1305ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1315ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1325ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1335ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1345ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpStorageIDList* MtpDevice::getStorageIDs() {
1355ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1365ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
1375ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1385ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1395ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1405ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1415ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1425ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return mData.getAUInt32();
1435ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1445ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1455ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1465ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1475ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
1485ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, storageID);
1505ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO))
1515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1545ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1555ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1565ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        MtpStorageInfo* info = new MtpStorageInfo(storageID);
1575ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        info->read(mData);
1585ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return info;
1595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1635ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
1645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood            MtpObjectFormat format, MtpObjectHandle parent) {
1655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1665ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, storageID);
1675ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(2, format);
1685ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(3, parent);
1695ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_OBJECT_HANDLES))
1705ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1715ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1725ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1735ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1745ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1755ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return mData.getAUInt32();
1765ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1775ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1785ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1805ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
1816afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    // FIXME - we might want to add some caching here
1826afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood
1835ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1845ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, handle);
1855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_OBJECT_INFO))
1865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1895ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        MtpObjectInfo* info = new MtpObjectInfo(handle);
1925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        info->read(mData);
1935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return info;
1945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1983e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodvoid* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
1993e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    mRequest.reset();
2003e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    mRequest.setParameter(1, handle);
2013e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    if (sendRequest(MTP_OPERATION_GET_THUMB) && readData()) {
2023e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        MtpResponseCode ret = readResponse();
2033e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        if (ret == MTP_RESPONSE_OK) {
2043e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            return mData.getData(outLength);
2053e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
2063e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    }
2073e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    outLength = 0;
2083e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    return NULL;
2096afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood}
2106afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood
2116afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwoodbool MtpDevice::deleteObject(MtpObjectHandle handle) {
2126afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    mRequest.reset();
2136afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    mRequest.setParameter(1, handle);
2146afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    if (sendRequest(MTP_OPERATION_DELETE_OBJECT)) {
2156afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        MtpResponseCode ret = readResponse();
2166afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        if (ret == MTP_RESPONSE_OK)
2176afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood            return true;
2186afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    }
2196afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    return false;
2206afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood}
2216afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood
2226afc41d095ccb159f6c4705bed903b6c048b922aMike LockwoodMtpObjectHandle MtpDevice::getParent(MtpObjectHandle handle) {
2236afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    MtpObjectInfo* info = getObjectInfo(handle);
2246afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    if (info)
2256afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return info->mParent;
2266afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    else
2276afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return -1;
2286afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood}
2293e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
2306afc41d095ccb159f6c4705bed903b6c048b922aMike LockwoodMtpObjectHandle MtpDevice::getStorageID(MtpObjectHandle handle) {
2316afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    MtpObjectInfo* info = getObjectInfo(handle);
2326afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    if (info)
2336afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return info->mStorageID;
2346afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    else
2356afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return -1;
2363e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood}
2373e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
238a6c490b8b2d96ebaab632286029463f932ae3b6bMike LockwoodMtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
239a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    mRequest.reset();
240a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    mRequest.setParameter(1, code);
241a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    if (!sendRequest(MTP_OPERATION_GET_DEVICE_PROP_DESC))
242a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        return NULL;
243a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    if (!readData())
244a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        return NULL;
245a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    MtpResponseCode ret = readResponse();
246a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    if (ret == MTP_RESPONSE_OK) {
247a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        MtpProperty* property = new MtpProperty;
248a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        property->read(mData);
249a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        return property;
250a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    }
251a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    return NULL;
252a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
253a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
254a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
2555ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::sendRequest(MtpOperationCode operation) {
256a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation));
2575ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setOperationCode(operation);
2585ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mTransactionID > 0)
2595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mRequest.setTransactionID(mTransactionID++);
2605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mRequest.write(mEndpointOut);
2615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.dump();
2625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return (ret > 0);
2635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
2645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
2655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::sendData(MtpOperationCode operation) {
266a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("sendData\n");
2675ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.setOperationCode(mRequest.getOperationCode());
2685ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.setTransactionID(mRequest.getTransactionID());
2695ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mData.write(mEndpointOut);
2705ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.dump();
2715ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return (ret > 0);
2725ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
2735ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
2745ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::readData() {
2755ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.reset();
2765ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mData.read(mEndpointIn);
277a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("readData returned %d\n", ret);
2785ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
2795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mData.dump();
2805ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return true;
2815ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
2825ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else {
283a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        LOGD("readResponse failed\n");
2845ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return false;
2855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
2865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
2875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
2885ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpResponseCode MtpDevice::readResponse() {
289a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("readResponse\n");
2905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mResponse.read(mEndpointIn);
2915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
2925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mResponse.dump();
2935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return mResponse.getResponseCode();
2945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
2955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else {
296a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        LOGD("readResponse failed\n");
2975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return -1;
2985ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
2995ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
3005ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
3015ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}  // namespace android
302