MtpDevice.cpp revision 6afc41d095ccb159f6c4705bed903b6c048b922a
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"
18a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood#include "utils/Log.h"
19a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
205ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <stdio.h>
215ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <stdlib.h>
225ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/types.h>
235ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/ioctl.h>
245ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/stat.h>
255ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <fcntl.h>
265ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <errno.h>
275ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
285ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <usbhost/usbhost.h>
295ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
305ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "MtpDevice.h"
315ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "MtpDebug.h"
325ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "MtpDeviceInfo.h"
335ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "MtpObjectInfo.h"
34a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood#include "MtpProperty.h"
355ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "MtpStorageInfo.h"
365ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "MtpStringBuffer.h"
375ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
385ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodnamespace android {
395ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
405ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDevice::MtpDevice(struct usb_device* device, int interface,
415ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood            struct usb_endpoint *ep_in, struct usb_endpoint *ep_out,
425ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood            struct usb_endpoint *ep_intr)
435ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    :   mDevice(device),
445ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mInterface(interface),
455ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mEndpointIn(ep_in),
465ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mEndpointOut(ep_out),
475ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mEndpointIntr(ep_intr),
485ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mDeviceInfo(NULL),
495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mID(usb_device_get_unique_id(device)),
505ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mSessionID(0),
515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mTransactionID(0)
525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood{
535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
545ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
555ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDevice::~MtpDevice() {
565ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    close();
57a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    for (int i = 0; i < mDeviceProperties.size(); i++)
58a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        delete mDeviceProperties[i];
595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid MtpDevice::initialize() {
625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    openSession();
635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mDeviceInfo = getDeviceInfo();
645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mDeviceInfo) {
655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mDeviceInfo->print();
66a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
67a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        if (mDeviceInfo->mDeviceProperties) {
68a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood            int count = mDeviceInfo->mDeviceProperties->size();
69a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood            for (int i = 0; i < count; i++) {
70a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
71a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                MtpProperty* property = getDevicePropDesc(propCode);
72a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                if (property) {
73a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                    property->print();
74a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                    mDeviceProperties.push(property);
75a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood                }
76a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood            }
77a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        }
785ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
805ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
815ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid MtpDevice::close() {
825ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mDevice) {
835ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        usb_device_release_interface(mDevice, mInterface);
845ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        usb_device_close(mDevice);
855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mDevice = NULL;
865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
895ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodconst char* MtpDevice::getDeviceName() {
905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mDevice)
915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return usb_device_get_name(mDevice);
925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else
935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return "???";
945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::openSession() {
975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mSessionID = 0;
985ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mTransactionID = 0;
995ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpSessionID newSession = 1;
1005ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1015ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, newSession);
1025ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_OPEN_SESSION))
1035ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return false;
1045ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1055ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_SESSION_ALREADY_OPEN)
1065ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        newSession = mResponse.getParameter(1);
1075ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else if (ret != MTP_RESPONSE_OK)
1085ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return false;
1095ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1105ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mSessionID = newSession;
1115ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mTransactionID = 1;
1125ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return true;
1135ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1145ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1155ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::closeSession() {
1165ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    // FIXME
1175ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return true;
1185ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1195ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1205ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDeviceInfo* MtpDevice::getDeviceInfo() {
1215ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1225ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
1235ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1245ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1255ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1265ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1275ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1285ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        MtpDeviceInfo* info = new MtpDeviceInfo;
1295ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        info->read(mData);
1305ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return info;
1315ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1325ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1335ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1345ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1355ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpStorageIDList* MtpDevice::getStorageIDs() {
1365ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1375ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
1385ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1395ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1405ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1415ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1425ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1435ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return mData.getAUInt32();
1445ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1455ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1465ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1475ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1485ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
1495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1505ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, storageID);
1515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO))
1525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1545ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1555ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1565ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1575ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        MtpStorageInfo* info = new MtpStorageInfo(storageID);
1585ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        info->read(mData);
1595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return info;
1605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1645ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
1655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood            MtpObjectFormat format, MtpObjectHandle parent) {
1665ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1675ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, storageID);
1685ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(2, format);
1695ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(3, parent);
1705ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_OBJECT_HANDLES))
1715ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1725ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1735ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1745ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1755ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1765ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return mData.getAUInt32();
1775ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1785ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1805ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1815ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
1826afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    // FIXME - we might want to add some caching here
1836afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood
1845ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.reset();
1855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setParameter(1, handle);
1865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!sendRequest(MTP_OPERATION_GET_OBJECT_INFO))
1875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (!readData())
1895ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return NULL;
1905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    MtpResponseCode ret = readResponse();
1915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret == MTP_RESPONSE_OK) {
1925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        MtpObjectInfo* info = new MtpObjectInfo(handle);
1935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        info->read(mData);
1945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return info;
1955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
1965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return NULL;
1975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
1985ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
1993e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodvoid* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
2003e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    mRequest.reset();
2013e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    mRequest.setParameter(1, handle);
2023e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    if (sendRequest(MTP_OPERATION_GET_THUMB) && readData()) {
2033e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        MtpResponseCode ret = readResponse();
2043e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        if (ret == MTP_RESPONSE_OK) {
2053e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            return mData.getData(outLength);
2063e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
2073e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    }
2083e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    outLength = 0;
2093e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    return NULL;
2106afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood}
2116afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood
2126afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwoodbool MtpDevice::deleteObject(MtpObjectHandle handle) {
2136afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    mRequest.reset();
2146afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    mRequest.setParameter(1, handle);
2156afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    if (sendRequest(MTP_OPERATION_DELETE_OBJECT)) {
2166afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        MtpResponseCode ret = readResponse();
2176afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        if (ret == MTP_RESPONSE_OK)
2186afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood            return true;
2196afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    }
2206afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    return false;
2216afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood}
2226afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood
2236afc41d095ccb159f6c4705bed903b6c048b922aMike LockwoodMtpObjectHandle MtpDevice::getParent(MtpObjectHandle handle) {
2246afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    MtpObjectInfo* info = getObjectInfo(handle);
2256afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    if (info)
2266afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return info->mParent;
2276afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    else
2286afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return -1;
2296afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood}
2303e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
2316afc41d095ccb159f6c4705bed903b6c048b922aMike LockwoodMtpObjectHandle MtpDevice::getStorageID(MtpObjectHandle handle) {
2326afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    MtpObjectInfo* info = getObjectInfo(handle);
2336afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    if (info)
2346afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return info->mStorageID;
2356afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood    else
2366afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood        return -1;
2373e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood}
2383e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
239a6c490b8b2d96ebaab632286029463f932ae3b6bMike LockwoodMtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
240a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    mRequest.reset();
241a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    mRequest.setParameter(1, code);
242a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    if (!sendRequest(MTP_OPERATION_GET_DEVICE_PROP_DESC))
243a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        return NULL;
244a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    if (!readData())
245a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        return NULL;
246a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    MtpResponseCode ret = readResponse();
247a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    if (ret == MTP_RESPONSE_OK) {
248a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        MtpProperty* property = new MtpProperty;
249a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        property->read(mData);
250a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        return property;
251a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    }
252a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    return NULL;
253a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
254a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
255a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
2565ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::sendRequest(MtpOperationCode operation) {
257a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation));
2585ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.setOperationCode(operation);
2595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (mTransactionID > 0)
2605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mRequest.setTransactionID(mTransactionID++);
2615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mRequest.write(mEndpointOut);
2625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mRequest.dump();
2635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return (ret > 0);
2645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
2655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
2665ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::sendData(MtpOperationCode operation) {
267a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("sendData\n");
2685ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.setOperationCode(mRequest.getOperationCode());
2695ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.setTransactionID(mRequest.getTransactionID());
2705ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mData.write(mEndpointOut);
2715ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.dump();
2725ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    return (ret > 0);
2735ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
2745ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
2755ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::readData() {
2765ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    mData.reset();
2775ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mData.read(mEndpointIn);
278a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("readData returned %d\n", ret);
2795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
2805ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mData.dump();
2815ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return true;
2825ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
2835ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else {
284a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        LOGD("readResponse failed\n");
2855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return false;
2865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
2875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
2885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
2895ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpResponseCode MtpDevice::readResponse() {
290a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    LOGD("readResponse\n");
2915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    int ret = mResponse.read(mEndpointIn);
2925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    if (ret >= MTP_CONTAINER_HEADER_SIZE) {
2935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        mResponse.dump();
2945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return mResponse.getResponseCode();
2955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
2965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    else {
297a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood        LOGD("readResponse failed\n");
2985ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood        return -1;
2995ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood    }
3005ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}
3015ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood
3025ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood}  // namespace android
303