MtpServer.cpp revision 20c3be0e0394e1340c036685eb1edb8f6ef5a2ac
116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/* 216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Copyright (C) 2010 The Android Open Source Project 316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * you may not use this file except in compliance with the License. 616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * You may obtain a copy of the License at 716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 1016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Unless required by applicable law or agreed to in writing, software 1116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 1216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * See the License for the specific language governing permissions and 1416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * limitations under the License. 1516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */ 1616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 1716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h> 1816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdlib.h> 1916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <sys/types.h> 2016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <sys/ioctl.h> 2116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <sys/stat.h> 2216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <fcntl.h> 2316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <errno.h> 24d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood#include <sys/stat.h> 25d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood#include <dirent.h> 2616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 27c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood#include <cutils/properties.h> 28c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood 29a881b44cc7e18bdfa03251bc65b7d0903a1b1efcMike Lockwood#define LOG_TAG "MtpServer" 30a881b44cc7e18bdfa03251bc65b7d0903a1b1efcMike Lockwood 3116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpDebug.h" 327f53a190463274096155704276f3002c1620a364Mike Lockwood#include "MtpDatabase.h" 3321ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood#include "MtpProperty.h" 3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpServer.h" 3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpStorage.h" 3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpStringBuffer.h" 3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 388065e2056073808716db32136d7acfd50eeab924Mike Lockwood#include <linux/usb/f_mtp.h> 3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 407850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android { 417850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodstatic const MtpOperationCode kSupportedOperationCodes[] = { 4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_DEVICE_INFO, 4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_OPEN_SESSION, 4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_CLOSE_SESSION, 4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_STORAGE_IDS, 4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_STORAGE_INFO, 4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_NUM_OBJECTS, 4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT_HANDLES, 5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT_INFO, 5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT, 5216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_GET_THUMB, 5316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_DELETE_OBJECT, 5416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_SEND_OBJECT_INFO, 5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_SEND_OBJECT, 5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_INITIATE_CAPTURE, 5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_FORMAT_STORE, 5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_RESET_DEVICE, 5916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_SELF_TEST, 6016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_SET_OBJECT_PROTECTION, 6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_POWER_DOWN, 62e3e76c456baee122de6715ae280130abaddc906cMike Lockwood MTP_OPERATION_GET_DEVICE_PROP_DESC, 638277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_GET_DEVICE_PROP_VALUE, 648277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_SET_DEVICE_PROP_VALUE, 658277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_RESET_DEVICE_PROP_VALUE, 6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_TERMINATE_OPEN_CAPTURE, 6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_MOVE_OBJECT, 6816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_COPY_OBJECT, 69d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood MTP_OPERATION_GET_PARTIAL_OBJECT, 7016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_INITIATE_OPEN_CAPTURE, 7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED, 728277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_GET_OBJECT_PROP_DESC, 73677f5700c5ea35256079ef14e06b7382e438d860Mike Lockwood MTP_OPERATION_GET_OBJECT_PROP_VALUE, 74677f5700c5ea35256079ef14e06b7382e438d860Mike Lockwood MTP_OPERATION_SET_OBJECT_PROP_VALUE, 75b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood MTP_OPERATION_GET_OBJECT_PROP_LIST, 76b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood// MTP_OPERATION_SET_OBJECT_PROP_LIST, 77b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood// MTP_OPERATION_GET_INTERDEPENDENT_PROP_DESC, 78b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood// MTP_OPERATION_SEND_OBJECT_PROP_LIST, 79438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MTP_OPERATION_GET_OBJECT_REFERENCES, 80438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MTP_OPERATION_SET_OBJECT_REFERENCES, 8116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_SKIP, 8216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}; 8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 84873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwoodstatic const MtpEventCode kSupportedEventCodes[] = { 85873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood MTP_EVENT_OBJECT_ADDED, 86873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood MTP_EVENT_OBJECT_REMOVED, 87873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood}; 88873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood 891865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike LockwoodMtpServer::MtpServer(int fd, MtpDatabase* database, 908e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood int fileGroup, int filePerm, int directoryPerm) 9116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood : mFD(fd), 921865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood mDatabase(database), 938e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood mFileGroup(fileGroup), 948e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood mFilePermission(filePerm), 958e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood mDirectoryPermission(directoryPerm), 9616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionID(0), 9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionOpen(false), 9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectHandle(kInvalidObjectHandle), 994714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectFormat(0), 10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectFileSize(0) 10116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 10216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpServer::~MtpServer() { 10516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10720c3be0e0394e1340c036685eb1edb8f6ef5a2acMike Lockwoodvoid MtpServer::addStorage(const char* filePath, uint64_t reserveSpace) { 10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int index = mStorages.size() + 1; 10916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood index |= index << 16; // set high and low part to our index 11020c3be0e0394e1340c036685eb1edb8f6ef5a2acMike Lockwood MtpStorage* storage = new MtpStorage(index, filePath, reserveSpace); 11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood addStorage(storage); 11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 11316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 11416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpStorage* MtpServer::getStorage(MtpStorageID id) { 115fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood if (id == 0) 116fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood return mStorages[0]; 11716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < mStorages.size(); i++) { 118fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood MtpStorage* storage = mStorages[i]; 11916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (storage->getStorageID() == id) 12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return storage; 12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 12216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return NULL; 12316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 12416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 12516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpServer::run() { 12616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int fd = mFD; 12716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 12821ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood LOGV("MtpServer::run fd: %d\n", fd); 12916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 13016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood while (1) { 13116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ret = mRequest.read(fd); 13216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret < 0) { 133b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("request read returned %d, errno: %d", ret, errno); 134916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 135916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 136916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 137916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 13816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 13916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 14016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpOperationCode operation = mRequest.getOperationCode(); 14116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpTransactionID transaction = mRequest.getTransactionID(); 14216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 143b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("operation: %s", MtpDebug::getOperationCodeName(operation)); 14416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mRequest.dump(); 14516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 14616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME need to generalize this 147438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood bool dataIn = (operation == MTP_OPERATION_SEND_OBJECT_INFO 1488277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood || operation == MTP_OPERATION_SET_OBJECT_REFERENCES 1498277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood || operation == MTP_OPERATION_SET_OBJECT_PROP_VALUE 1508277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood || operation == MTP_OPERATION_SET_DEVICE_PROP_VALUE); 15116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (dataIn) { 15216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ret = mData.read(fd); 15316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret < 0) { 154b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("data read returned %d, errno: %d", ret, errno); 155916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 156916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 157916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 158916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 15916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 16016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 161b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("received data:"); 16216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.dump(); 16316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } else { 16416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.reset(); 16516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 16616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 167916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (handleRequest()) { 168916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (!dataIn && mData.hasData()) { 169916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood mData.setOperationCode(operation); 170916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood mData.setTransactionID(transaction); 171b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("sending data:"); 17223d2071ab44d7b5e3b16e8a81e11884faf01092fMike Lockwood mData.dump(); 173916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood ret = mData.write(fd); 174916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (ret < 0) { 175b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("request write returned %d, errno: %d", ret, errno); 176916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 177916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 178916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 179916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 180916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood break; 181916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 182916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 18316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 184916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood mResponse.setTransactionID(transaction); 185b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("sending response %04X", mResponse.getResponseCode()); 186916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood ret = mResponse.write(fd); 18723d2071ab44d7b5e3b16e8a81e11884faf01092fMike Lockwood mResponse.dump(); 18816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret < 0) { 189b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("request write returned %d, errno: %d", ret, errno); 190916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 191916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 192916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 193916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 19416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 19516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 196916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } else { 19721ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood LOGV("skipping response\n"); 19816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 19916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 2006b3a9d15c8a2282c03f1df7d72a55b6800d4ececMike Lockwood 2016b3a9d15c8a2282c03f1df7d72a55b6800d4ececMike Lockwood if (mSessionOpen) 2026b3a9d15c8a2282c03f1df7d72a55b6800d4ececMike Lockwood mDatabase->sessionEnded(); 20316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 20416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 205873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwoodvoid MtpServer::sendObjectAdded(MtpObjectHandle handle) { 20673ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood if (mSessionOpen) { 20773ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("sendObjectAdded %d\n", handle); 20873ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setEventCode(MTP_EVENT_OBJECT_ADDED); 20973ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setTransactionID(mRequest.getTransactionID()); 21073ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setParameter(1, handle); 21173ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood int ret = mEvent.write(mFD); 21273ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("mEvent.write returned %d\n", ret); 21373ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood } 214873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood} 215873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood 216873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwoodvoid MtpServer::sendObjectRemoved(MtpObjectHandle handle) { 21773ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood if (mSessionOpen) { 21873ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("sendObjectRemoved %d\n", handle); 21973ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setEventCode(MTP_EVENT_OBJECT_REMOVED); 22073ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setTransactionID(mRequest.getTransactionID()); 22173ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setParameter(1, handle); 22273ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood int ret = mEvent.write(mFD); 22373ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("mEvent.write returned %d\n", ret); 22473ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood } 225873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood} 226873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood 227916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwoodbool MtpServer::handleRequest() { 22816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpOperationCode operation = mRequest.getOperationCode(); 22916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpResponseCode response; 23016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 23116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.reset(); 23216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 23316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mSendObjectHandle != kInvalidObjectHandle && operation != MTP_OPERATION_SEND_OBJECT) { 23416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - need to delete mSendObjectHandle from the database 235b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("expected SendObject after SendObjectInfo"); 23616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectHandle = kInvalidObjectHandle; 23716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 23816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 23916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood switch (operation) { 24016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_DEVICE_INFO: 24116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetDeviceInfo(); 24216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 24316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_OPEN_SESSION: 24416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doOpenSession(); 24516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 24616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_CLOSE_SESSION: 24716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doCloseSession(); 24816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 24916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_STORAGE_IDS: 25016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetStorageIDs(); 25116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 25216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_STORAGE_INFO: 25316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetStorageInfo(); 25416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 25516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED: 25616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectPropsSupported(); 25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 25816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_HANDLES: 25916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectHandles(); 26016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 261343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood case MTP_OPERATION_GET_NUM_OBJECTS: 262343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood response = doGetNumObjects(); 263343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood break; 264438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood case MTP_OPERATION_GET_OBJECT_REFERENCES: 265438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood response = doGetObjectReferences(); 266438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood break; 267438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood case MTP_OPERATION_SET_OBJECT_REFERENCES: 268438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood response = doSetObjectReferences(); 269438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood break; 27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_PROP_VALUE: 27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectPropValue(); 27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 2738277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_SET_OBJECT_PROP_VALUE: 2748277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doSetObjectPropValue(); 2758277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 2768277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_GET_DEVICE_PROP_VALUE: 2778277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doGetDevicePropValue(); 2788277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 2798277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_SET_DEVICE_PROP_VALUE: 2808277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doSetDevicePropValue(); 2818277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 2828277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_RESET_DEVICE_PROP_VALUE: 2838277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doResetDevicePropValue(); 2848277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 285b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood case MTP_OPERATION_GET_OBJECT_PROP_LIST: 286b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood response = doGetObjectPropList(); 287b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood break; 28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_INFO: 28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectInfo(); 29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT: 29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObject(); 29316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 294d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood case MTP_OPERATION_GET_PARTIAL_OBJECT: 295d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood response = doGetPartialObject(); 296d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood break; 29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_SEND_OBJECT_INFO: 29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doSendObjectInfo(); 29916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_SEND_OBJECT: 30116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doSendObject(); 30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 30316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_DELETE_OBJECT: 30416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doDeleteObject(); 30516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 30616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_PROP_DESC: 30721ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood response = doGetObjectPropDesc(); 30821ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood break; 309e3e76c456baee122de6715ae280130abaddc906cMike Lockwood case MTP_OPERATION_GET_DEVICE_PROP_DESC: 310e3e76c456baee122de6715ae280130abaddc906cMike Lockwood response = doGetDevicePropDesc(); 311e3e76c456baee122de6715ae280130abaddc906cMike Lockwood break; 31216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood default: 313a881b44cc7e18bdfa03251bc65b7d0903a1b1efcMike Lockwood LOGE("got unsupported command %s", MtpDebug::getOperationCodeName(operation)); 31416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED; 31516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 31616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 31716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 318916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (response == MTP_RESPONSE_TRANSACTION_CANCELLED) 319916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return false; 32016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setResponseCode(response); 321916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return true; 32216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 32316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 32416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetDeviceInfo() { 32516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer string; 326c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood char prop_value[PROPERTY_VALUE_MAX]; 32716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 328782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood MtpObjectFormatList* playbackFormats = mDatabase->getSupportedPlaybackFormats(); 329782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood MtpObjectFormatList* captureFormats = mDatabase->getSupportedCaptureFormats(); 330782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood MtpDevicePropertyList* deviceProperties = mDatabase->getSupportedDeviceProperties(); 331782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood 33216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // fill in device info 33316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(MTP_STANDARD_VERSION); 33416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(6); // MTP Vendor Extension ID 33516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(MTP_STANDARD_VERSION); 33616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set("microsoft.com: 1.0;"); 33716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // MTP Extensions 33816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(0); //Functional Mode 33916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putAUInt16(kSupportedOperationCodes, 34016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood sizeof(kSupportedOperationCodes) / sizeof(uint16_t)); // Operations Supported 341873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood mData.putAUInt16(kSupportedEventCodes, 342873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood sizeof(kSupportedEventCodes) / sizeof(uint16_t)); // Events Supported 343782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(deviceProperties); // Device Properties Supported 344782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(captureFormats); // Capture Formats 345782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(playbackFormats); // Playback Formats 34616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME 34716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set("Google, Inc."); 34816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Manufacturer 349c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood 350c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood property_get("ro.product.model", prop_value, "MTP Device"); 351c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood string.set(prop_value); 35216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Model 35316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set("1.0"); 35416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Device Version 355c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood 356c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood property_get("ro.serialno", prop_value, "????????"); 357c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood string.set(prop_value); 35816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Serial Number 35916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 360782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood delete playbackFormats; 361782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood delete captureFormats; 362782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood delete deviceProperties; 363782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood 36416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 36516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 36616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 36716864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doOpenSession() { 36816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mSessionOpen) { 36916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setParameter(1, mSessionID); 37016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_ALREADY_OPEN; 37116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 37216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionID = mRequest.getParameter(1); 37316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionOpen = true; 3746b3a9d15c8a2282c03f1df7d72a55b6800d4ececMike Lockwood 3756b3a9d15c8a2282c03f1df7d72a55b6800d4ececMike Lockwood mDatabase->sessionStarted(); 3766b3a9d15c8a2282c03f1df7d72a55b6800d4ececMike Lockwood 37716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 37816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 37916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 38016864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doCloseSession() { 38116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 38216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 38316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionID = 0; 38416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionOpen = false; 3856b3a9d15c8a2282c03f1df7d72a55b6800d4ececMike Lockwood mDatabase->sessionEnded(); 38616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 38716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 38816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 38916864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetStorageIDs() { 39016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 39116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 39216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 39316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int count = mStorages.size(); 39416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(count); 39516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 39616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(mStorages[i]->getStorageID()); 39716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 39816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 39916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 40016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 40116864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetStorageInfo() { 40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer string; 40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 40416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 40516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 40616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorageID id = mRequest.getParameter(1); 40716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorage* storage = getStorage(id); 40816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!storage) 40916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_INVALID_STORAGE_ID; 41016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 41116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(storage->getType()); 41216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(storage->getFileSystemType()); 41316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(storage->getAccessCapability()); 41416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt64(storage->getMaxCapacity()); 41516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt64(storage->getFreeSpace()); 41616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(1024*1024*1024); // Free Space in Objects 41716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set(storage->getDescription()); 41816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); 41916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putEmptyString(); // Volume Identifier 42016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 42116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 42216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 42316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 42416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectPropsSupported() { 42516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 42616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 42716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectFormat format = mRequest.getParameter(1); 4282e09e289b7e136481e9215bb61ed47cee5d9919bMike Lockwood MtpObjectPropertyList* properties = mDatabase->getSupportedObjectProperties(format); 429782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(properties); 430bf9b2052d207f8f2a23470f1c4dfe464f430f387Mike Lockwood delete properties; 43116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 43216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 43316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 43416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectHandles() { 43516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 43616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 43716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage 438e13401bf532c7e4bf9ab82c7e9b13642838a927dMike Lockwood MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats 43916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent 44016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // 0x00000000 for all objects? 4411865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood if (parent == 0xFFFFFFFF) 4421865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood parent = 0; 44316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 44416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandleList* handles = mDatabase->getObjectList(storageID, format, parent); 44516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putAUInt32(handles); 44616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood delete handles; 44716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 44816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 44916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 450343af4ef512869695456a91519e73ed3c3d82101Mike LockwoodMtpResponseCode MtpServer::doGetNumObjects() { 451343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood if (!mSessionOpen) 452343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 453343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage 454343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats 455343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent 456343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood // 0x00000000 for all objects? 457343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood if (parent == 0xFFFFFFFF) 458343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood parent = 0; 459343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood 460343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood int count = mDatabase->getNumObjects(storageID, format, parent); 461343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood if (count >= 0) { 462343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood mResponse.setParameter(1, count); 463343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood return MTP_RESPONSE_OK; 464343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood } else { 465343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood mResponse.setParameter(1, 0); 466343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood return MTP_RESPONSE_INVALID_OBJECT_HANDLE; 467343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood } 468343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood} 469343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood 470438344fba74ddd6b931ac733fa48643f27b63de3Mike LockwoodMtpResponseCode MtpServer::doGetObjectReferences() { 471438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood if (!mSessionOpen) 472438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 473438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpStorageID handle = mRequest.getParameter(1); 4748277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4758277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood // FIXME - check for invalid object handle 476438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpObjectHandleList* handles = mDatabase->getObjectReferences(handle); 4778277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood if (handles) { 4788277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood mData.putAUInt32(handles); 4798277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood delete handles; 4808277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood } else { 481438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood mData.putEmptyArray(); 482438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood } 483438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return MTP_RESPONSE_OK; 484438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood} 485438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood 486438344fba74ddd6b931ac733fa48643f27b63de3Mike LockwoodMtpResponseCode MtpServer::doSetObjectReferences() { 487438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood if (!mSessionOpen) 488438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 489438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpStorageID handle = mRequest.getParameter(1); 490438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpObjectHandleList* references = mData.getAUInt32(); 491438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpResponseCode result = mDatabase->setObjectReferences(handle, references); 492438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood delete references; 493438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return result; 494438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood} 495438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood 49616864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectPropValue() { 49716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 49816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectProperty property = mRequest.getParameter(2); 4998277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetObjectPropValue %d %s\n", handle, 5008277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getObjectPropCodeName(property)); 50116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 5028277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->getObjectPropertyValue(handle, property, mData); 5038277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 5048277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5058277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doSetObjectPropValue() { 5068277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 5078277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpObjectProperty property = mRequest.getParameter(2); 5088277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("SetObjectPropValue %d %s\n", handle, 5098277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getObjectPropCodeName(property)); 5108277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5118277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->setObjectPropertyValue(handle, property, mData); 5128277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 5138277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5148277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doGetDevicePropValue() { 5158277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty property = mRequest.getParameter(1); 5168277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetDevicePropValue %s\n", 5178277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getDevicePropCodeName(property)); 5188277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5198277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->getDevicePropertyValue(property, mData); 5208277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 5218277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5228277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doSetDevicePropValue() { 5238277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty property = mRequest.getParameter(1); 5248277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("SetDevicePropValue %s\n", 5258277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getDevicePropCodeName(property)); 5268277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5278277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->setDevicePropertyValue(property, mData); 5288277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 5298277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5308277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doResetDevicePropValue() { 5318277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty property = mRequest.getParameter(1); 5328277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("ResetDevicePropValue %s\n", 5338277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getDevicePropCodeName(property)); 5348277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5358277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->resetDeviceProperty(property); 53616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 53716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 538b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike LockwoodMtpResponseCode MtpServer::doGetObjectPropList() { 539b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood 540b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 54140ce1f262cc4edbc8b7c470830325466263acaecMike Lockwood // use uint32_t so we can support 0xFFFFFFFF 54240ce1f262cc4edbc8b7c470830325466263acaecMike Lockwood uint32_t format = mRequest.getParameter(2); 54340ce1f262cc4edbc8b7c470830325466263acaecMike Lockwood uint32_t property = mRequest.getParameter(3); 544b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood int groupCode = mRequest.getParameter(4); 545f05ff073495b0bb3e49859aee5b54d3e25088985Mike Lockwood int depth = mRequest.getParameter(5); 546b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood LOGD("GetObjectPropList %d format: %s property: %s group: %d depth: %d\n", 547b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood handle, MtpDebug::getFormatCodeName(format), 548b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood MtpDebug::getObjectPropCodeName(property), groupCode, depth); 549b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood 550b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood return mDatabase->getObjectPropertyList(handle, format, property, groupCode, depth, mData); 551b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood} 552b6da06e9dfb916da4b88e09e8a83e22ddae445b5Mike Lockwood 55316864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectInfo() { 55416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 55516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return mDatabase->getObjectInfo(handle, mData); 55616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 55716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 55816864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObject() { 55916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 560c6588763ddc20541688e426a24b1b070527c051fMike Lockwood MtpString pathBuf; 56116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int64_t fileLength; 562fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood MtpObjectFormat format; 563fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format); 5649c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood if (result != MTP_RESPONSE_OK) 5659c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return result; 56616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 5679c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood const char* filePath = (const char *)pathBuf; 56816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mtp_file_range mfr; 569c6588763ddc20541688e426a24b1b070527c051fMike Lockwood mfr.fd = open(filePath, O_RDONLY); 570c6588763ddc20541688e426a24b1b070527c051fMike Lockwood if (mfr.fd < 0) { 571c6588763ddc20541688e426a24b1b070527c051fMike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 572c6588763ddc20541688e426a24b1b070527c051fMike Lockwood } 57316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.offset = 0; 57416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.length = fileLength; 57516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 57616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // send data header 57716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.setOperationCode(mRequest.getOperationCode()); 57816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.setTransactionID(mRequest.getTransactionID()); 57923d2071ab44d7b5e3b16e8a81e11884faf01092fMike Lockwood mData.writeDataHeader(mFD, fileLength + MTP_CONTAINER_HEADER_SIZE); 58016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 58116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // then transfer the file 58216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr); 583c6588763ddc20541688e426a24b1b070527c051fMike Lockwood close(mfr.fd); 584916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (ret < 0) { 585916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) 586916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return MTP_RESPONSE_TRANSACTION_CANCELLED; 587916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood else 588916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 589916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 59016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 59116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 59216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 593d81ce3cf2e6479915658a0829eced062e3655320Mike LockwoodMtpResponseCode MtpServer::doGetPartialObject() { 594d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 595d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood uint32_t offset = mRequest.getParameter(2); 596d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood uint32_t length = mRequest.getParameter(3); 597d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood MtpString pathBuf; 598d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood int64_t fileLength; 599fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood MtpObjectFormat format; 600fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format); 601d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood if (result != MTP_RESPONSE_OK) 602d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood return result; 603d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood if (offset + length > fileLength) 604d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood length = fileLength - offset; 605d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood 606d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood const char* filePath = (const char *)pathBuf; 607d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mtp_file_range mfr; 608d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mfr.fd = open(filePath, O_RDONLY); 609d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood if (mfr.fd < 0) { 610d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 611d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood } 612d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mfr.offset = offset; 613d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mfr.length = length; 614d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mResponse.setParameter(1, length); 615d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood 616d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood // send data header 617d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mData.setOperationCode(mRequest.getOperationCode()); 618d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mData.setTransactionID(mRequest.getTransactionID()); 619d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood mData.writeDataHeader(mFD, length + MTP_CONTAINER_HEADER_SIZE); 620d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood 621d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood // then transfer the file 622d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr); 623d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood close(mfr.fd); 624d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood if (ret < 0) { 625d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood if (errno == ECANCELED) 626d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood return MTP_RESPONSE_TRANSACTION_CANCELLED; 627d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood else 628d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 629d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood } 630d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood return MTP_RESPONSE_OK; 631d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood} 632d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood 63316864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doSendObjectInfo() { 63416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpString path; 63516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorageID storageID = mRequest.getParameter(1); 63616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorage* storage = getStorage(storageID); 63716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle parent = mRequest.getParameter(2); 63816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!storage) 63916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_INVALID_STORAGE_ID; 64016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 64116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // special case the root 6421865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood if (parent == MTP_PARENT_ROOT) { 64316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood path = storage->getPath(); 6441865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood parent = 0; 6451865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood } else { 646fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood int64_t length; 647fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood MtpObjectFormat format; 648fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood int result = mDatabase->getObjectFilePath(parent, path, length, format); 6499c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood if (result != MTP_RESPONSE_OK) 6509c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return result; 651fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood if (format != MTP_FORMAT_ASSOCIATION) 652fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood return MTP_RESPONSE_INVALID_PARENT_OBJECT; 65316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 65416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 65516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // read only the fields we need 65616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // storage ID 65716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectFormat format = mData.getUInt16(); 65816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt16(); // protection status 65916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectFileSize = mData.getUInt32(); 66016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt16(); // thumb format 66116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // thumb compressed size 66216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // thumb pix width 66316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // thumb pix height 66416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // image pix width 66516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // image pix height 66616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // image bit depth 66716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // parent 66816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood uint16_t associationType = mData.getUInt16(); 66916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood uint32_t associationDesc = mData.getUInt32(); // association desc 67016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // sequence number 67116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer name, created, modified; 67216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getString(name); // file name 67316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getString(created); // date created 67416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getString(modified); // date modified 67516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // keywords follow 67616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 677f5b2ff2a636d1a98e959553376ebffa3a2749843Mike Lockwood LOGD("name: %s format: %04X\n", (const char *)name, format); 678fceef46513db3507b413f604cea89e3c7f352663Mike Lockwood time_t modifiedTime; 67916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!parseDateTime(modified, modifiedTime)) 68016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood modifiedTime = 0; 68116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 68216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (path[path.size() - 1] != '/') 68316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood path += "/"; 68416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood path += (const char *)name; 68516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 686fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood // file should not already exist 687fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood if (access(path, R_OK) == 0) 688fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 689fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood 69020c3be0e0394e1340c036685eb1edb8f6ef5a2acMike Lockwood // check space first 69120c3be0e0394e1340c036685eb1edb8f6ef5a2acMike Lockwood if (mSendObjectFileSize > storage->getFreeSpace()) 69220c3be0e0394e1340c036685eb1edb8f6ef5a2acMike Lockwood return MTP_RESPONSE_STORAGE_FULL; 69320c3be0e0394e1340c036685eb1edb8f6ef5a2acMike Lockwood 6944714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path, 6954714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood format, parent, storageID, mSendObjectFileSize, modifiedTime); 696fceef46513db3507b413f604cea89e3c7f352663Mike Lockwood if (handle == kInvalidObjectHandle) { 69716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 698fceef46513db3507b413f604cea89e3c7f352663Mike Lockwood } 69916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 70016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (format == MTP_FORMAT_ASSOCIATION) { 70116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mode_t mask = umask(0); 7028e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood int ret = mkdir((const char *)path, mDirectoryPermission); 70316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood umask(mask); 70416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret && ret != -EEXIST) 70516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 7068e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood chown((const char *)path, getuid(), mFileGroup); 70716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } else { 70816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectFilePath = path; 70916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // save the handle for the SendObject call, which should follow 71016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectHandle = handle; 7114714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectFormat = format; 71216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 71316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 71416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setParameter(1, storageID); 7158277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood mResponse.setParameter(2, parent); 71616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setParameter(3, handle); 71716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 71816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 71916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 72016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 72116864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doSendObject() { 7224714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood MtpResponseCode result = MTP_RESPONSE_OK; 7234714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mode_t mask; 7244714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood int ret; 725e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood uint64_t actualSize = -1; 7264714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood 72716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mSendObjectHandle == kInvalidObjectHandle) { 728b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("Expected SendObjectInfo before SendObject"); 7294714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_NO_VALID_OBJECT_INFO; 7304714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood goto done; 73116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 73216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 73316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // read the header 7344714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood ret = mData.readDataHeader(mFD); 73516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - check for errors here. 73616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 73716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // reset so we don't attempt to send this back 73816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.reset(); 73916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 74016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mtp_file_range mfr; 741c6588763ddc20541688e426a24b1b070527c051fMike Lockwood mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC); 742c6588763ddc20541688e426a24b1b070527c051fMike Lockwood if (mfr.fd < 0) { 7434714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_GENERAL_ERROR; 7444714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood goto done; 745c6588763ddc20541688e426a24b1b070527c051fMike Lockwood } 7468e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood fchown(mfr.fd, getuid(), mFileGroup); 7478e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood // set permissions 7484714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mask = umask(0); 7498e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood fchmod(mfr.fd, mFilePermission); 7508e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood umask(mask); 7518e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood 75216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.offset = 0; 75316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.length = mSendObjectFileSize; 75416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 755f5b2ff2a636d1a98e959553376ebffa3a2749843Mike Lockwood LOGD("receiving %s\n", (const char *)mSendObjectFilePath); 75616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // transfer the file 75716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); 758c6588763ddc20541688e426a24b1b070527c051fMike Lockwood close(mfr.fd); 7598e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood 760b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("MTP_RECEIVE_FILE returned %d", ret); 76116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 762916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (ret < 0) { 763916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood unlink(mSendObjectFilePath); 764916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) 7654714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_TRANSACTION_CANCELLED; 766916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood else 7674714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_GENERAL_ERROR; 768e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood } else if (mSendObjectFileSize == 0xFFFFFFFF) { 769e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood // actual size is likely > 4 gig so stat the file to compute actual length 770e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood struct stat s; 771e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood if (lstat(mSendObjectFilePath, &s) == 0) { 772e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood actualSize = s.st_size; 773e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood LOGD("actualSize: %lld\n", actualSize); 774e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood } 775916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 7764714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood 7774714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwooddone: 7784714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat, 779e1b8cf1cafb75ce1339b67eb1764e224a257c579Mike Lockwood actualSize, result == MTP_RESPONSE_OK); 7804714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectHandle = kInvalidObjectHandle; 7814714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectFormat = 0; 7824714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood return result; 78316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 78416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 785d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwoodstatic void deleteRecursive(const char* path) { 786d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood char pathbuf[PATH_MAX]; 787d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood int pathLength = strlen(path); 788d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (pathLength >= sizeof(pathbuf) - 1) { 789d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood LOGE("path too long: %s\n", path); 790d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 791d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood strcpy(pathbuf, path); 792d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (pathbuf[pathLength - 1] != '/') { 793d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood pathbuf[pathLength++] = '/'; 794d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 795d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood char* fileSpot = pathbuf + pathLength; 796d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood int pathRemaining = sizeof(pathbuf) - pathLength - 1; 797d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood 798d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood DIR* dir = opendir(path); 799d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (!dir) { 800d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood LOGE("opendir %s failed: %s", path, strerror(errno)); 801d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood return; 802d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 803d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood 804d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood struct dirent* entry; 805d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood while ((entry = readdir(dir))) { 806d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood const char* name = entry->d_name; 807d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood 808d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood // ignore "." and ".." 809d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) { 810d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood continue; 811d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 812d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood 813d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood int nameLength = strlen(name); 814d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (nameLength > pathRemaining) { 815d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood LOGE("path %s/%s too long\n", path, name); 816d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood continue; 817d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 818d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood strcpy(fileSpot, name); 819d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood 820d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood int type = entry->d_type; 821d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (entry->d_type == DT_DIR) { 822d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood deleteRecursive(pathbuf); 823d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood rmdir(pathbuf); 824d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } else { 825d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood unlink(pathbuf); 826d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 827d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 8287ce05cf6009a2fbbceb3d2c0ff639473d0b7d6a9Mike Lockwood closedir(dir); 829d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood} 830d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood 831d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwoodstatic void deletePath(const char* path) { 832d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood struct stat statbuf; 833d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (stat(path, &statbuf) == 0) { 834d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood if (S_ISDIR(statbuf.st_mode)) { 835d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood deleteRecursive(path); 836d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood rmdir(path); 837d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } else { 838d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood unlink(path); 839d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 840d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } else { 841d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood LOGE("deletePath stat failed for %s: %s", path, strerror(errno)); 842d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood } 843d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood} 844d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood 84516864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doDeleteObject() { 84616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 847d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood MtpObjectFormat format = mRequest.getParameter(2); 84816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - support deleting all objects if handle is 0xFFFFFFFF 84916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - implement deleting objects by format 85016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 85116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpString filePath; 85216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int64_t fileLength; 853fd34626771a63d3a835863e1b4bf71dcb26e28d8Mike Lockwood int result = mDatabase->getObjectFilePath(handle, filePath, fileLength, format); 8549c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood if (result == MTP_RESPONSE_OK) { 8559c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood LOGV("deleting %s", (const char *)filePath); 856d32114950770a6e9361e0869a41e5a03a7acab42Mike Lockwood deletePath((const char *)filePath); 8579c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return mDatabase->deleteFile(handle); 8589c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood } else { 8599c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return result; 8609c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood } 86116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 86216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 86316864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectPropDesc() { 86421ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood MtpObjectProperty propCode = mRequest.getParameter(1); 86516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectFormat format = mRequest.getParameter(2); 8668277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetObjectPropDesc %s %s\n", MtpDebug::getObjectPropCodeName(propCode), 8678277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getFormatCodeName(format)); 8688277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpProperty* property = mDatabase->getObjectPropertyDesc(propCode, format); 86921ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood if (!property) 87021ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; 8718277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood property->write(mData); 8728277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood delete property; 8738277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return MTP_RESPONSE_OK; 8748277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 87516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 8768277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doGetDevicePropDesc() { 8778277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty propCode = mRequest.getParameter(1); 8788277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetDevicePropDesc %s\n", MtpDebug::getDevicePropCodeName(propCode)); 8798277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode); 8808277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood if (!property) 8818277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 88221ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood property->write(mData); 8838277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood delete property; 88421ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood return MTP_RESPONSE_OK; 88516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 8867850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 8877850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood} // namespace android 888