MtpDevice.cpp revision e3e76c456baee122de6715ae280130abaddc906c
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" 260cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include "MtpUtils.h" 27a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 285ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <stdio.h> 295ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <stdlib.h> 305ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/types.h> 315ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/ioctl.h> 325ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <sys/stat.h> 335ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <fcntl.h> 345ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <errno.h> 350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include <endian.h> 365ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 375ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <usbhost/usbhost.h> 385ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 395ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodnamespace android { 405ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 415ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDevice::MtpDevice(struct usb_device* device, int interface, 425ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood struct usb_endpoint *ep_in, struct usb_endpoint *ep_out, 435ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood struct usb_endpoint *ep_intr) 445ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood : mDevice(device), 455ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mInterface(interface), 465ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mEndpointIn(ep_in), 475ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mEndpointOut(ep_out), 485ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mEndpointIntr(ep_intr), 495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mDeviceInfo(NULL), 505ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mID(usb_device_get_unique_id(device)), 515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mSessionID(0), 525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mTransactionID(0) 535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood{ 545ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 555ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 565ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDevice::~MtpDevice() { 575ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood close(); 58a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood for (int i = 0; i < mDeviceProperties.size(); i++) 59a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood delete mDeviceProperties[i]; 605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid MtpDevice::initialize() { 635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood openSession(); 645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mDeviceInfo = getDeviceInfo(); 655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (mDeviceInfo) { 665ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mDeviceInfo->print(); 67a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 68a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood if (mDeviceInfo->mDeviceProperties) { 69a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood int count = mDeviceInfo->mDeviceProperties->size(); 70a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood for (int i = 0; i < count; i++) { 71a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i]; 72a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood MtpProperty* property = getDevicePropDesc(propCode); 73a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood if (property) { 74a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood property->print(); 75a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood mDeviceProperties.push(property); 76a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood } 77a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood } 78a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood } 795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 805ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 815ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 825ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid MtpDevice::close() { 835ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (mDevice) { 845ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood usb_device_release_interface(mDevice, mInterface); 855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood usb_device_close(mDevice); 865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mDevice = NULL; 875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 895ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodconst char* MtpDevice::getDeviceName() { 915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (mDevice) 925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return usb_device_get_name(mDevice); 935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood else 945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return "???"; 955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::openSession() { 980cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 990cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 1005ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mSessionID = 0; 1015ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mTransactionID = 0; 1025ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpSessionID newSession = 1; 1035ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.reset(); 1045ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setParameter(1, newSession); 1055ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!sendRequest(MTP_OPERATION_OPEN_SESSION)) 1065ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return false; 1075ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpResponseCode ret = readResponse(); 1085ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret == MTP_RESPONSE_SESSION_ALREADY_OPEN) 1095ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood newSession = mResponse.getParameter(1); 1105ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood else if (ret != MTP_RESPONSE_OK) 1115ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return false; 1125ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1135ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mSessionID = newSession; 1145ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mTransactionID = 1; 1155ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return true; 1165ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1175ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1185ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::closeSession() { 1195ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood // FIXME 1205ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return true; 1215ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1225ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1235ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpDeviceInfo* MtpDevice::getDeviceInfo() { 1240cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 1250cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 1265ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.reset(); 1275ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO)) 1285ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1295ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!readData()) 1305ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1315ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpResponseCode ret = readResponse(); 1325ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret == MTP_RESPONSE_OK) { 1335ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpDeviceInfo* info = new MtpDeviceInfo; 1345ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood info->read(mData); 1355ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return info; 1365ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 1375ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1385ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1395ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1405ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpStorageIDList* MtpDevice::getStorageIDs() { 1410cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 1420cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 1435ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.reset(); 1445ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS)) 1455ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1465ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!readData()) 1475ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1485ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpResponseCode ret = readResponse(); 1495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret == MTP_RESPONSE_OK) { 1505ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return mData.getAUInt32(); 1515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 1525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1545ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1555ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) { 1560cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 1570cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 1585ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.reset(); 1595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setParameter(1, storageID); 1605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO)) 1615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!readData()) 1635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpResponseCode ret = readResponse(); 1655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret == MTP_RESPONSE_OK) { 1665ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpStorageInfo* info = new MtpStorageInfo(storageID); 1675ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood info->read(mData); 1685ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return info; 1695ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 1705ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1715ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1725ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1735ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID, 1745ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpObjectFormat format, MtpObjectHandle parent) { 1750cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 1760cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 1775ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.reset(); 1785ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setParameter(1, storageID); 1795ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setParameter(2, format); 1805ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setParameter(3, parent); 1815ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!sendRequest(MTP_OPERATION_GET_OBJECT_HANDLES)) 1825ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1835ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!readData()) 1845ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpResponseCode ret = readResponse(); 1865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret == MTP_RESPONSE_OK) { 1875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return mData.getAUInt32(); 1885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 1895ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 1905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1925ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) { 1930cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 1940cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 1956afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood // FIXME - we might want to add some caching here 1966afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood 1975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.reset(); 1985ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setParameter(1, handle); 1995ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!sendRequest(MTP_OPERATION_GET_OBJECT_INFO)) 2005ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 2015ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (!readData()) 2025ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 2035ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpResponseCode ret = readResponse(); 2045ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret == MTP_RESPONSE_OK) { 2055ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood MtpObjectInfo* info = new MtpObjectInfo(handle); 2065ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood info->read(mData); 2075ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return info; 2085ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 2095ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return NULL; 2105ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 2115ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 2123e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodvoid* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) { 2130cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 2140cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2153e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood mRequest.reset(); 2163e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood mRequest.setParameter(1, handle); 2173e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (sendRequest(MTP_OPERATION_GET_THUMB) && readData()) { 2183e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood MtpResponseCode ret = readResponse(); 2193e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (ret == MTP_RESPONSE_OK) { 2203e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return mData.getData(outLength); 2213e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 2223e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 2233e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood outLength = 0; 2243e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return NULL; 2256afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood} 2266afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood 2270cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike LockwoodMtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) { 2280cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 2290cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2300cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mRequest.reset(); 2310cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpObjectHandle parent = info->mParent; 2320cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (parent == 0) 2330cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood parent = MTP_PARENT_ROOT; 2340cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mRequest.setParameter(1, info->mStorageID); 2360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mRequest.setParameter(2, info->mParent); 2370cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2380cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mStorageID); 2390cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt16(info->mFormat); 2400cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt16(info->mProtectionStatus); 2410cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mCompressedSize); 2420cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt16(info->mThumbFormat); 2430cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mThumbCompressedSize); 2440cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mThumbPixWidth); 2450cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mThumbPixHeight); 2460cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mImagePixWidth); 2470cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mImagePixHeight); 2480cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mImagePixDepth); 2490cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mParent); 2500cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt16(info->mAssociationType); 2510cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mAssociationDesc); 2520cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putUInt32(info->mSequenceNumber); 2530cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putString(info->mName); 2540cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2550cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood char created[100], modified[100]; 2560cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood formatDateTime(info->mDateCreated, created, sizeof(created)); 2570cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood formatDateTime(info->mDateModified, modified, sizeof(modified)); 2580cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2590cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putString(created); 2600cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putString(modified); 2610cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (info->mKeywords) 2620cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putString(info->mKeywords); 2630cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood else 2640cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.putEmptyString(); 2650cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2660cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (sendRequest(MTP_OPERATION_SEND_OBJECT_INFO) && sendData()) { 2670cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpResponseCode ret = readResponse(); 2680cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (ret == MTP_RESPONSE_OK) { 2690cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood info->mStorageID = mResponse.getParameter(1); 2700cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood info->mParent = mResponse.getParameter(2); 2710cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood info->mHandle = mResponse.getParameter(3); 2720cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return info->mHandle; 2730cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 2740cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 2750cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return (MtpObjectHandle)-1; 2760cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 2770cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2780cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwoodbool MtpDevice::sendObject(MtpObjectInfo* info, int srcFD) { 2790cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 2800cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2810cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int remaining = info->mCompressedSize; 2820cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mRequest.reset(); 2830cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mRequest.setParameter(1, info->mHandle); 2840cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (sendRequest(MTP_OPERATION_SEND_OBJECT)) { 2850cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // send data header 2860cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood writeDataHeader(MTP_OPERATION_SEND_OBJECT, remaining); 2870cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2880cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood char buffer[65536]; 2890cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood while (remaining > 0) { 2900cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int count = read(srcFD, buffer, sizeof(buffer)); 2910cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (count > 0) { 2920cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int written = mData.write(mEndpointOut, buffer, count); 2930cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // FIXME check error 2940cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood remaining -= count; 2950cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } else { 2960cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood break; 2970cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 2980cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 2990cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 3000cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpResponseCode ret = readResponse(); 3010cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return (remaining == 0 && ret == MTP_RESPONSE_OK); 3020cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 3030cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3046afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwoodbool MtpDevice::deleteObject(MtpObjectHandle handle) { 3050cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 3060cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3076afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood mRequest.reset(); 3086afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood mRequest.setParameter(1, handle); 3096afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood if (sendRequest(MTP_OPERATION_DELETE_OBJECT)) { 3106afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood MtpResponseCode ret = readResponse(); 3116afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood if (ret == MTP_RESPONSE_OK) 3126afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood return true; 3136afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood } 3146afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood return false; 3156afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood} 3166afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood 3176afc41d095ccb159f6c4705bed903b6c048b922aMike LockwoodMtpObjectHandle MtpDevice::getParent(MtpObjectHandle handle) { 3186afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood MtpObjectInfo* info = getObjectInfo(handle); 3196afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood if (info) 3206afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood return info->mParent; 3216afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood else 3226afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood return -1; 3236afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood} 3243e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood 3256afc41d095ccb159f6c4705bed903b6c048b922aMike LockwoodMtpObjectHandle MtpDevice::getStorageID(MtpObjectHandle handle) { 3266afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood MtpObjectInfo* info = getObjectInfo(handle); 3276afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood if (info) 3286afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood return info->mStorageID; 3296afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood else 3306afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood return -1; 3313e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood} 3323e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood 333a6c490b8b2d96ebaab632286029463f932ae3b6bMike LockwoodMtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) { 3340cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood Mutex::Autolock autoLock(mMutex); 3350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 336a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood mRequest.reset(); 337a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood mRequest.setParameter(1, code); 338a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood if (!sendRequest(MTP_OPERATION_GET_DEVICE_PROP_DESC)) 339a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood return NULL; 340a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood if (!readData()) 341a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood return NULL; 342a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood MtpResponseCode ret = readResponse(); 343a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood if (ret == MTP_RESPONSE_OK) { 344a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood MtpProperty* property = new MtpProperty; 345e3e76c456baee122de6715ae280130abaddc906cMike Lockwood property->read(mData); 346a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood return property; 347a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood } 348a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood return NULL; 349a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 350a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 3510cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwoodclass ReadObjectThread : public Thread { 3520cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwoodprivate: 3530cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpDevice* mDevice; 3540cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpObjectHandle mHandle; 3550cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int mObjectSize; 3560cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood void* mInitialData; 3570cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int mInitialDataLength; 3580cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int mFD; 3590cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3600cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwoodpublic: 3610cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood ReadObjectThread(MtpDevice* device, MtpObjectHandle handle, int objectSize) 3620cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood : mDevice(device), 3630cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mHandle(handle), 3640cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mObjectSize(objectSize), 3650cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mInitialData(NULL), 3660cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mInitialDataLength(0) 3670cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood { 3680cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 3690cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3700cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood virtual ~ReadObjectThread() { 3710cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (mFD >= 0) 3720cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood close(mFD); 3730cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood free(mInitialData); 3740cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 3750cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3760cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // returns file descriptor 3770cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int init() { 3780cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mDevice->mRequest.reset(); 3790cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mDevice->mRequest.setParameter(1, mHandle); 3800cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (mDevice->sendRequest(MTP_OPERATION_GET_OBJECT) 3810cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood && mDevice->mData.readDataHeader(mDevice->mEndpointIn)) { 3820cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3830cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // mData will contain header and possibly the beginning of the object data 3840cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mInitialData = mDevice->mData.getData(mInitialDataLength); 3850cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3860cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // create a pipe for the client to read from 3870cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int pipefd[2]; 3880cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (pipe(pipefd) < 0) { 3890cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood LOGE("pipe failed (%s)", strerror(errno)); 3900cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return -1; 3910cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 3920cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 3930cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mFD = pipefd[1]; 3940cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return pipefd[0]; 3950cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } else { 3960cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return -1; 3970cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 3980cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 3990cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 4000cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood virtual bool threadLoop() { 4010cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int remaining = mObjectSize; 4020cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (mInitialData) { 4030cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood write(mFD, mInitialData, mInitialDataLength); 4040cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood remaining -= mInitialDataLength; 4050cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood free(mInitialData); 4060cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mInitialData = NULL; 4070cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 4080cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 409da90dff17b6ce79d0a7d8ab2dbe2aa69cd1c11aaMike Lockwood char buffer[16384]; 4100cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood while (remaining > 0) { 4110cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int readSize = (remaining > sizeof(buffer) ? sizeof(buffer) : remaining); 4120cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int count = mDevice->mData.readData(mDevice->mEndpointIn, buffer, readSize); 4130cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int written; 4140cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (count >= 0) { 4150cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int written = write(mFD, buffer, count); 4160cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // FIXME check error 4170cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood remaining -= count; 4180cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } else { 4190cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood break; 4200cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 4210cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 4220cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 4230cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpResponseCode ret = mDevice->readResponse(); 4240cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mDevice->mMutex.unlock(); 4250cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return false; 4260cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 4270cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}; 4280cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 4290cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // returns the file descriptor for a pipe to read the object's data 4300cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwoodint MtpDevice::readObject(MtpObjectHandle handle, int objectSize) { 4310cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mMutex.lock(); 4320cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 4330cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood ReadObjectThread* thread = new ReadObjectThread(this, handle, objectSize); 4340cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int fd = thread->init(); 4350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (fd < 0) { 4360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood delete thread; 4370cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mMutex.unlock(); 4380cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } else { 4390cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood thread->run("ReadObjectThread"); 4400cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 4410cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return fd; 4420cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 443a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 4445ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::sendRequest(MtpOperationCode operation) { 445f43c641bf3f8bcb5748f4ae504d434896edc94f5Mike Lockwood LOGV("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation)); 4465ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setOperationCode(operation); 4475ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (mTransactionID > 0) 4485ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.setTransactionID(mTransactionID++); 4495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood int ret = mRequest.write(mEndpointOut); 4505ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mRequest.dump(); 4515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return (ret > 0); 4525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 4535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 4540cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwoodbool MtpDevice::sendData() { 455f43c641bf3f8bcb5748f4ae504d434896edc94f5Mike Lockwood LOGV("sendData\n"); 4565ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mData.setOperationCode(mRequest.getOperationCode()); 4575ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mData.setTransactionID(mRequest.getTransactionID()); 4585ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood int ret = mData.write(mEndpointOut); 4595ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mData.dump(); 4605ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return (ret > 0); 4615ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 4625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 4635ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodbool MtpDevice::readData() { 4645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mData.reset(); 4655ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood int ret = mData.read(mEndpointIn); 466f43c641bf3f8bcb5748f4ae504d434896edc94f5Mike Lockwood LOGV("readData returned %d\n", ret); 4675ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret >= MTP_CONTAINER_HEADER_SIZE) { 4685ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mData.dump(); 4695ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return true; 4705ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 4715ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood else { 472f43c641bf3f8bcb5748f4ae504d434896edc94f5Mike Lockwood LOGV("readResponse failed\n"); 4735ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return false; 4745ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 4755ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 4765ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 4770cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwoodbool MtpDevice::writeDataHeader(MtpOperationCode operation, int dataLength) { 4780cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.setOperationCode(operation); 4790cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mData.setTransactionID(mRequest.getTransactionID()); 4800cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return (!mData.writeDataHeader(mEndpointOut, dataLength)); 4810cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 4820cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 4835ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodMtpResponseCode MtpDevice::readResponse() { 484f43c641bf3f8bcb5748f4ae504d434896edc94f5Mike Lockwood LOGV("readResponse\n"); 4855ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood int ret = mResponse.read(mEndpointIn); 4865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood if (ret >= MTP_CONTAINER_HEADER_SIZE) { 4875ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood mResponse.dump(); 4885ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return mResponse.getResponseCode(); 4895ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 4905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood else { 491a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood LOGD("readResponse failed\n"); 4925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood return -1; 4935ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 4945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 4955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 4965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} // namespace android 497