MtpServer.cpp revision 8277cec96ffa55082962591bca1c55abbeec8c26
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> 2416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 25c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood#include <cutils/properties.h> 26c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood 2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpDebug.h" 287f53a190463274096155704276f3002c1620a364Mike Lockwood#include "MtpDatabase.h" 2921ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood#include "MtpProperty.h" 3016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpServer.h" 3116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpStorage.h" 3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpStringBuffer.h" 3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 348065e2056073808716db32136d7acfd50eeab924Mike Lockwood#include <linux/usb/f_mtp.h> 3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 367850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android { 377850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodstatic const MtpOperationCode kSupportedOperationCodes[] = { 3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_DEVICE_INFO, 4016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_OPEN_SESSION, 4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_CLOSE_SESSION, 4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_STORAGE_IDS, 4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_STORAGE_INFO, 4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_NUM_OBJECTS, 4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT_HANDLES, 4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT_INFO, 4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT, 4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_GET_THUMB, 4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_DELETE_OBJECT, 5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_SEND_OBJECT_INFO, 5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_SEND_OBJECT, 5216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_INITIATE_CAPTURE, 5316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_FORMAT_STORE, 5416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_RESET_DEVICE, 5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_SELF_TEST, 5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_SET_OBJECT_PROTECTION, 5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_POWER_DOWN, 58343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood// MTP_OPERATION_GET_DEVICE_PROP_DESC, 598277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_GET_DEVICE_PROP_VALUE, 608277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_SET_DEVICE_PROP_VALUE, 618277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_RESET_DEVICE_PROP_VALUE, 6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_TERMINATE_OPEN_CAPTURE, 6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_MOVE_OBJECT, 6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_COPY_OBJECT, 6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_GET_PARTIAL_OBJECT, 6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_INITIATE_OPEN_CAPTURE, 6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED, 688277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MTP_OPERATION_GET_OBJECT_PROP_DESC, 698277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood// MTP_OPERATION_GET_OBJECT_PROP_VALUE, 70343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood// MTP_OPERATION_SET_OBJECT_PROP_VALUE, 71438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MTP_OPERATION_GET_OBJECT_REFERENCES, 72438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MTP_OPERATION_SET_OBJECT_REFERENCES, 7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood// MTP_OPERATION_SKIP, 7416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}; 7516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 76873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwoodstatic const MtpEventCode kSupportedEventCodes[] = { 77873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood MTP_EVENT_OBJECT_ADDED, 78873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood MTP_EVENT_OBJECT_REMOVED, 79873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood}; 80873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood 811865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike LockwoodMtpServer::MtpServer(int fd, MtpDatabase* database, 828e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood int fileGroup, int filePerm, int directoryPerm) 8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood : mFD(fd), 841865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood mDatabase(database), 858e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood mFileGroup(fileGroup), 868e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood mFilePermission(filePerm), 878e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood mDirectoryPermission(directoryPerm), 8816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionID(0), 8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionOpen(false), 9016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectHandle(kInvalidObjectHandle), 914714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectFormat(0), 9216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectFileSize(0) 9316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 9416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 9616864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpServer::~MtpServer() { 9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 9916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpServer::addStorage(const char* filePath) { 10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int index = mStorages.size() + 1; 10116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood index |= index << 16; // set high and low part to our index 10216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorage* storage = new MtpStorage(index, filePath, mDatabase); 10316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood addStorage(storage); 10416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10616864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpStorage* MtpServer::getStorage(MtpStorageID id) { 10716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < mStorages.size(); i++) { 10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorage* storage = mStorages[i]; 10916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (storage->getStorageID() == id) 11016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return storage; 11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return NULL; 11316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 11416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 11516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpServer::run() { 11616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int fd = mFD; 11716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 11821ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood LOGV("MtpServer::run fd: %d\n", fd); 11916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood while (1) { 12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ret = mRequest.read(fd); 12216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret < 0) { 123b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("request read returned %d, errno: %d", ret, errno); 124916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 125916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 126916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 127916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 12816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 12916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 13016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpOperationCode operation = mRequest.getOperationCode(); 13116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpTransactionID transaction = mRequest.getTransactionID(); 13216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 133b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("operation: %s", MtpDebug::getOperationCodeName(operation)); 13416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mRequest.dump(); 13516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 13616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME need to generalize this 137438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood bool dataIn = (operation == MTP_OPERATION_SEND_OBJECT_INFO 1388277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood || operation == MTP_OPERATION_SET_OBJECT_REFERENCES 1398277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood || operation == MTP_OPERATION_SET_OBJECT_PROP_VALUE 1408277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood || operation == MTP_OPERATION_SET_DEVICE_PROP_VALUE); 14116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (dataIn) { 14216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ret = mData.read(fd); 14316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret < 0) { 144b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("data read returned %d, errno: %d", ret, errno); 145916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 146916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 147916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 148916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 14916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 15016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 151b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("received data:"); 15216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.dump(); 15316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } else { 15416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.reset(); 15516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 15616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 157916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (handleRequest()) { 158916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (!dataIn && mData.hasData()) { 159916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood mData.setOperationCode(operation); 160916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood mData.setTransactionID(transaction); 161b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("sending data:"); 162916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood ret = mData.write(fd); 163916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (ret < 0) { 164b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("request write returned %d, errno: %d", ret, errno); 165916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 166916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 167916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 168916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 169916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood break; 170916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 171916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 17216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 173916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood mResponse.setTransactionID(transaction); 174b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("sending response %04X", mResponse.getResponseCode()); 175916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood ret = mResponse.write(fd); 17616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret < 0) { 177b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("request write returned %d, errno: %d", ret, errno); 178916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) { 179916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood // return to top of loop and wait for next command 180916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood continue; 181916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 18216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 18316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 184916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } else { 18521ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood LOGV("skipping response\n"); 18616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 18716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 18816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 18916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 190873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwoodvoid MtpServer::sendObjectAdded(MtpObjectHandle handle) { 19173ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood if (mSessionOpen) { 19273ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("sendObjectAdded %d\n", handle); 19373ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setEventCode(MTP_EVENT_OBJECT_ADDED); 19473ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setTransactionID(mRequest.getTransactionID()); 19573ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setParameter(1, handle); 19673ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood int ret = mEvent.write(mFD); 19773ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("mEvent.write returned %d\n", ret); 19873ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood } 199873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood} 200873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood 201873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwoodvoid MtpServer::sendObjectRemoved(MtpObjectHandle handle) { 20273ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood if (mSessionOpen) { 20373ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("sendObjectRemoved %d\n", handle); 20473ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setEventCode(MTP_EVENT_OBJECT_REMOVED); 20573ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setTransactionID(mRequest.getTransactionID()); 20673ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood mEvent.setParameter(1, handle); 20773ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood int ret = mEvent.write(mFD); 20873ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood LOGD("mEvent.write returned %d\n", ret); 20973ecd23cc2ebadb8e1fae1cc21ac559524c6b2bbMike Lockwood } 210873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood} 211873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood 212916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwoodbool MtpServer::handleRequest() { 21316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpOperationCode operation = mRequest.getOperationCode(); 21416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpResponseCode response; 21516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 21616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.reset(); 21716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 21816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mSendObjectHandle != kInvalidObjectHandle && operation != MTP_OPERATION_SEND_OBJECT) { 21916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - need to delete mSendObjectHandle from the database 220b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("expected SendObject after SendObjectInfo"); 22116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectHandle = kInvalidObjectHandle; 22216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 22316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 22416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood switch (operation) { 22516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_DEVICE_INFO: 22616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetDeviceInfo(); 22716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 22816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_OPEN_SESSION: 22916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doOpenSession(); 23016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 23116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_CLOSE_SESSION: 23216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doCloseSession(); 23316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 23416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_STORAGE_IDS: 23516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetStorageIDs(); 23616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 23716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_STORAGE_INFO: 23816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetStorageInfo(); 23916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 24016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED: 24116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectPropsSupported(); 24216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 24316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_HANDLES: 24416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectHandles(); 24516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 246343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood case MTP_OPERATION_GET_NUM_OBJECTS: 247343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood response = doGetNumObjects(); 248343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood break; 249438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood case MTP_OPERATION_GET_OBJECT_REFERENCES: 250438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood response = doGetObjectReferences(); 251438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood break; 252438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood case MTP_OPERATION_SET_OBJECT_REFERENCES: 253438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood response = doSetObjectReferences(); 254438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood break; 25516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_PROP_VALUE: 25616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectPropValue(); 25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 2588277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_SET_OBJECT_PROP_VALUE: 2598277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doSetObjectPropValue(); 2608277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 2618277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_GET_DEVICE_PROP_VALUE: 2628277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doGetDevicePropValue(); 2638277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 2648277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_SET_DEVICE_PROP_VALUE: 2658277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doSetDevicePropValue(); 2668277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 2678277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood case MTP_OPERATION_RESET_DEVICE_PROP_VALUE: 2688277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood response = doResetDevicePropValue(); 2698277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood break; 27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_INFO: 27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObjectInfo(); 27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 27316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT: 27416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doGetObject(); 27516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 27616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_SEND_OBJECT_INFO: 27716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doSendObjectInfo(); 27816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 27916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_SEND_OBJECT: 28016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doSendObject(); 28116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 28216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_DELETE_OBJECT: 28316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = doDeleteObject(); 28416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 28516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MTP_OPERATION_GET_OBJECT_PROP_DESC: 28621ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood response = doGetObjectPropDesc(); 28721ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood break; 28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood default: 28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood response = MTP_RESPONSE_OPERATION_NOT_SUPPORTED; 29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 293916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (response == MTP_RESPONSE_TRANSACTION_CANCELLED) 294916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return false; 29516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setResponseCode(response); 296916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return true; 29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 29916864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetDeviceInfo() { 30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer string; 301c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood char prop_value[PROPERTY_VALUE_MAX]; 30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 303782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood MtpObjectFormatList* playbackFormats = mDatabase->getSupportedPlaybackFormats(); 304782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood MtpObjectFormatList* captureFormats = mDatabase->getSupportedCaptureFormats(); 305782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood MtpDevicePropertyList* deviceProperties = mDatabase->getSupportedDeviceProperties(); 306782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood 30716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // fill in device info 30816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(MTP_STANDARD_VERSION); 30916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(6); // MTP Vendor Extension ID 31016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(MTP_STANDARD_VERSION); 31116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set("microsoft.com: 1.0;"); 31216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // MTP Extensions 31316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(0); //Functional Mode 31416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putAUInt16(kSupportedOperationCodes, 31516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood sizeof(kSupportedOperationCodes) / sizeof(uint16_t)); // Operations Supported 316873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood mData.putAUInt16(kSupportedEventCodes, 317873871f3e75831bcda6c3f75bb4d53355ca5c53aMike Lockwood sizeof(kSupportedEventCodes) / sizeof(uint16_t)); // Events Supported 318782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(deviceProperties); // Device Properties Supported 319782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(captureFormats); // Capture Formats 320782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(playbackFormats); // Playback Formats 32116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME 32216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set("Google, Inc."); 32316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Manufacturer 324c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood 325c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood property_get("ro.product.model", prop_value, "MTP Device"); 326c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood string.set(prop_value); 32716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Model 32816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set("1.0"); 32916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Device Version 330c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood 331c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood property_get("ro.serialno", prop_value, "????????"); 332c42aa12f73edf79bc9cb0dbf6b74a7f1af11c683Mike Lockwood string.set(prop_value); 33316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); // Serial Number 33416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 335782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood delete playbackFormats; 336782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood delete captureFormats; 337782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood delete deviceProperties; 338782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood 33916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 34016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 34116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 34216864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doOpenSession() { 34316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mSessionOpen) { 34416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setParameter(1, mSessionID); 34516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_ALREADY_OPEN; 34616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 34716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionID = mRequest.getParameter(1); 34816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionOpen = true; 34916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 35016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 35116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 35216864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doCloseSession() { 35316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 35416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 35516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionID = 0; 35616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSessionOpen = false; 35716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 35816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 35916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 36016864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetStorageIDs() { 36116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 36216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 36316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 36416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int count = mStorages.size(); 36516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(count); 36616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 36716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(mStorages[i]->getStorageID()); 36816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 36916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 37016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 37116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 37216864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetStorageInfo() { 37316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer string; 37416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 37516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 37616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 37716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorageID id = mRequest.getParameter(1); 37816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorage* storage = getStorage(id); 37916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!storage) 38016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_INVALID_STORAGE_ID; 38116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 38216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(storage->getType()); 38316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(storage->getFileSystemType()); 38416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt16(storage->getAccessCapability()); 38516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt64(storage->getMaxCapacity()); 38616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt64(storage->getFreeSpace()); 38716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putUInt32(1024*1024*1024); // Free Space in Objects 38816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.set(storage->getDescription()); 38916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putString(string); 39016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putEmptyString(); // Volume Identifier 39116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 39216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 39316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 39416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 39516864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectPropsSupported() { 39616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 39716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 39816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectFormat format = mRequest.getParameter(1); 399782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood MtpDevicePropertyList* properties = mDatabase->getSupportedObjectProperties(format); 400782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood mData.putAUInt16(properties); 401bf9b2052d207f8f2a23470f1c4dfe464f430f387Mike Lockwood delete properties; 40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 40416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 40516864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectHandles() { 40616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mSessionOpen) 40716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 40816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage 409e13401bf532c7e4bf9ab82c7e9b13642838a927dMike Lockwood MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats 41016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent 41116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // 0x00000000 for all objects? 4121865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood if (parent == 0xFFFFFFFF) 4131865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood parent = 0; 41416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 41516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandleList* handles = mDatabase->getObjectList(storageID, format, parent); 41616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.putAUInt32(handles); 41716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood delete handles; 41816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 41916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 42016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 421343af4ef512869695456a91519e73ed3c3d82101Mike LockwoodMtpResponseCode MtpServer::doGetNumObjects() { 422343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood if (!mSessionOpen) 423343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 424343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage 425343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats 426343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent 427343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood // 0x00000000 for all objects? 428343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood if (parent == 0xFFFFFFFF) 429343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood parent = 0; 430343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood 431343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood int count = mDatabase->getNumObjects(storageID, format, parent); 432343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood if (count >= 0) { 433343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood mResponse.setParameter(1, count); 434343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood return MTP_RESPONSE_OK; 435343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood } else { 436343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood mResponse.setParameter(1, 0); 437343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood return MTP_RESPONSE_INVALID_OBJECT_HANDLE; 438343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood } 439343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood} 440343af4ef512869695456a91519e73ed3c3d82101Mike Lockwood 441438344fba74ddd6b931ac733fa48643f27b63de3Mike LockwoodMtpResponseCode MtpServer::doGetObjectReferences() { 442438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood if (!mSessionOpen) 443438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 444438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpStorageID handle = mRequest.getParameter(1); 4458277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4468277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood // FIXME - check for invalid object handle 447438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpObjectHandleList* handles = mDatabase->getObjectReferences(handle); 4488277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood if (handles) { 4498277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood mData.putAUInt32(handles); 4508277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood delete handles; 4518277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood } else { 452438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood mData.putEmptyArray(); 453438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood } 454438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return MTP_RESPONSE_OK; 455438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood} 456438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood 457438344fba74ddd6b931ac733fa48643f27b63de3Mike LockwoodMtpResponseCode MtpServer::doSetObjectReferences() { 458438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood if (!mSessionOpen) 459438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return MTP_RESPONSE_SESSION_NOT_OPEN; 460438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpStorageID handle = mRequest.getParameter(1); 461438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpObjectHandleList* references = mData.getAUInt32(); 462438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood MtpResponseCode result = mDatabase->setObjectReferences(handle, references); 463438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood delete references; 464438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood return result; 465438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood} 466438344fba74ddd6b931ac733fa48643f27b63de3Mike Lockwood 46716864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectPropValue() { 46816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 46916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectProperty property = mRequest.getParameter(2); 4708277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetObjectPropValue %d %s\n", handle, 4718277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getObjectPropCodeName(property)); 47216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4738277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->getObjectPropertyValue(handle, property, mData); 4748277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 4758277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4768277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doSetObjectPropValue() { 4778277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 4788277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpObjectProperty property = mRequest.getParameter(2); 4798277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("SetObjectPropValue %d %s\n", handle, 4808277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getObjectPropCodeName(property)); 4818277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4828277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->setObjectPropertyValue(handle, property, mData); 4838277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 4848277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4858277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doGetDevicePropValue() { 4868277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty property = mRequest.getParameter(1); 4878277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetDevicePropValue %s\n", 4888277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getDevicePropCodeName(property)); 4898277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4908277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->getDevicePropertyValue(property, mData); 4918277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 4928277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4938277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doSetDevicePropValue() { 4948277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty property = mRequest.getParameter(1); 4958277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("SetDevicePropValue %s\n", 4968277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getDevicePropCodeName(property)); 4978277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 4988277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->setDevicePropertyValue(property, mData); 4998277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 5008277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5018277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doResetDevicePropValue() { 5028277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty property = mRequest.getParameter(1); 5038277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("ResetDevicePropValue %s\n", 5048277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getDevicePropCodeName(property)); 5058277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 5068277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return mDatabase->resetDeviceProperty(property); 50716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 50816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 50916864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectInfo() { 51016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 51116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return mDatabase->getObjectInfo(handle, mData); 51216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 51316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 51416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObject() { 51516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 516c6588763ddc20541688e426a24b1b070527c051fMike Lockwood MtpString pathBuf; 51716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int64_t fileLength; 5189c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength); 5199c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood if (result != MTP_RESPONSE_OK) 5209c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return result; 52116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 5229c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood const char* filePath = (const char *)pathBuf; 52316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mtp_file_range mfr; 524c6588763ddc20541688e426a24b1b070527c051fMike Lockwood mfr.fd = open(filePath, O_RDONLY); 525c6588763ddc20541688e426a24b1b070527c051fMike Lockwood if (mfr.fd < 0) { 526c6588763ddc20541688e426a24b1b070527c051fMike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 527c6588763ddc20541688e426a24b1b070527c051fMike Lockwood } 52816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.offset = 0; 52916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.length = fileLength; 53016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 53116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // send data header 53216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.setOperationCode(mRequest.getOperationCode()); 53316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.setTransactionID(mRequest.getTransactionID()); 53416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.writeDataHeader(mFD, fileLength); 53516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 53616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // then transfer the file 53716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr); 538c6588763ddc20541688e426a24b1b070527c051fMike Lockwood close(mfr.fd); 539916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (ret < 0) { 540916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) 541916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return MTP_RESPONSE_TRANSACTION_CANCELLED; 542916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood else 543916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 544916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 54516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 54616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 54716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 54816864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doSendObjectInfo() { 54916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpString path; 55016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorageID storageID = mRequest.getParameter(1); 55116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStorage* storage = getStorage(storageID); 55216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle parent = mRequest.getParameter(2); 55316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!storage) 55416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_INVALID_STORAGE_ID; 55516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 55616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // special case the root 5571865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood if (parent == MTP_PARENT_ROOT) { 55816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood path = storage->getPath(); 5591865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood parent = 0; 5601865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood } else { 56116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int64_t dummy; 5629c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood int result = mDatabase->getObjectFilePath(parent, path, dummy); 5639c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood if (result != MTP_RESPONSE_OK) 5649c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return result; 56516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 56616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 56716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // read only the fields we need 56816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // storage ID 56916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectFormat format = mData.getUInt16(); 57016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt16(); // protection status 57116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectFileSize = mData.getUInt32(); 57216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt16(); // thumb format 57316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // thumb compressed size 57416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // thumb pix width 57516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // thumb pix height 57616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // image pix width 57716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // image pix height 57816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // image bit depth 57916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // parent 58016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood uint16_t associationType = mData.getUInt16(); 58116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood uint32_t associationDesc = mData.getUInt32(); // association desc 58216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getUInt32(); // sequence number 58316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer name, created, modified; 58416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getString(name); // file name 58516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getString(created); // date created 58616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.getString(modified); // date modified 58716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // keywords follow 58816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 589fceef46513db3507b413f604cea89e3c7f352663Mike Lockwood time_t modifiedTime; 59016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!parseDateTime(modified, modifiedTime)) 59116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood modifiedTime = 0; 59216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 59316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (path[path.size() - 1] != '/') 59416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood path += "/"; 59516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood path += (const char *)name; 59616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 5974714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path, 5984714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood format, parent, storageID, mSendObjectFileSize, modifiedTime); 599fceef46513db3507b413f604cea89e3c7f352663Mike Lockwood if (handle == kInvalidObjectHandle) { 60016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 601fceef46513db3507b413f604cea89e3c7f352663Mike Lockwood } 60216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 60316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (format == MTP_FORMAT_ASSOCIATION) { 60416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mode_t mask = umask(0); 6058e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood int ret = mkdir((const char *)path, mDirectoryPermission); 60616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood umask(mask); 60716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (ret && ret != -EEXIST) 60816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 6098e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood chown((const char *)path, getuid(), mFileGroup); 61016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } else { 61116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectFilePath = path; 61216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // save the handle for the SendObject call, which should follow 61316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSendObjectHandle = handle; 6144714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectFormat = format; 61516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 61616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 61716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setParameter(1, storageID); 6188277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood mResponse.setParameter(2, parent); 61916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResponse.setParameter(3, handle); 62016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 62116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return MTP_RESPONSE_OK; 62216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 62316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 62416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doSendObject() { 6254714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood MtpResponseCode result = MTP_RESPONSE_OK; 6264714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mode_t mask; 6274714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood int ret; 6284714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood 62916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mSendObjectHandle == kInvalidObjectHandle) { 630b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("Expected SendObjectInfo before SendObject"); 6314714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_NO_VALID_OBJECT_INFO; 6324714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood goto done; 63316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 63416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 63516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // read the header 6364714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood ret = mData.readDataHeader(mFD); 63716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - check for errors here. 63816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 63916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // reset so we don't attempt to send this back 64016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mData.reset(); 64116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 64216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mtp_file_range mfr; 643c6588763ddc20541688e426a24b1b070527c051fMike Lockwood mfr.fd = open(mSendObjectFilePath, O_RDWR | O_CREAT | O_TRUNC); 644c6588763ddc20541688e426a24b1b070527c051fMike Lockwood if (mfr.fd < 0) { 6454714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_GENERAL_ERROR; 6464714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood goto done; 647c6588763ddc20541688e426a24b1b070527c051fMike Lockwood } 6488e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood fchown(mfr.fd, getuid(), mFileGroup); 6498e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood // set permissions 6504714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mask = umask(0); 6518e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood fchmod(mfr.fd, mFilePermission); 6528e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood umask(mask); 6538e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood 65416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.offset = 0; 65516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mfr.length = mSendObjectFileSize; 65616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 65716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // transfer the file 65816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); 659c6588763ddc20541688e426a24b1b070527c051fMike Lockwood close(mfr.fd); 6608e2a280ab7f98bf00ff2651f1f93c8f8bd46c08dMike Lockwood 661b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("MTP_RECEIVE_FILE returned %d", ret); 66216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 663916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (ret < 0) { 664916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood unlink(mSendObjectFilePath); 665916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood if (errno == ECANCELED) 6664714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_TRANSACTION_CANCELLED; 667916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood else 6684714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result = MTP_RESPONSE_GENERAL_ERROR; 669916076c6d84dac9b104fbdf94af5dcd7bce669fdMike Lockwood } 6704714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood 6714714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwooddone: 6724714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mDatabase->endSendObject(mSendObjectFilePath, mSendObjectHandle, mSendObjectFormat, 6734714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood result == MTP_RESPONSE_OK); 6744714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectHandle = kInvalidObjectHandle; 6754714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood mSendObjectFormat = 0; 6764714b0766ecf48f09f39b4781a5c4deafc092d49Mike Lockwood return result; 67716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 67816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 67916864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doDeleteObject() { 68016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectHandle handle = mRequest.getParameter(1); 68116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectFormat format = mRequest.getParameter(1); 68216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - support deleting all objects if handle is 0xFFFFFFFF 68316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - implement deleting objects by format 68416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // FIXME - handle non-empty directories 68516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 68616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpString filePath; 68716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int64_t fileLength; 6889c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood int result = mDatabase->getObjectFilePath(handle, filePath, fileLength); 6899c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood if (result == MTP_RESPONSE_OK) { 6909c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood LOGV("deleting %s", (const char *)filePath); 6919c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood // one of these should work 6929c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood rmdir((const char *)filePath); 6939c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood unlink((const char *)filePath); 6949c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return mDatabase->deleteFile(handle); 6959c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood } else { 6969c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood return result; 6979c04c4cc038f924d9cb98798e1c07fe6017e85d0Mike Lockwood } 69816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 69916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 70016864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpResponseCode MtpServer::doGetObjectPropDesc() { 70121ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood MtpObjectProperty propCode = mRequest.getParameter(1); 70216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpObjectFormat format = mRequest.getParameter(2); 7038277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetObjectPropDesc %s %s\n", MtpDebug::getObjectPropCodeName(propCode), 7048277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDebug::getFormatCodeName(format)); 7058277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpProperty* property = mDatabase->getObjectPropertyDesc(propCode, format); 70621ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood if (!property) 70721ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; 7088277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood property->write(mData); 7098277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood delete property; 7108277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return MTP_RESPONSE_OK; 7118277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 71216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 7138277cec96ffa55082962591bca1c55abbeec8c26Mike LockwoodMtpResponseCode MtpServer::doGetDevicePropDesc() { 7148277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpDeviceProperty propCode = mRequest.getParameter(1); 7158277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood LOGD("GetDevicePropDesc %s\n", MtpDebug::getDevicePropCodeName(propCode)); 7168277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode); 7178277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood if (!property) 7188277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 71921ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood property->write(mData); 7208277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood delete property; 72121ef7d0e70c5ad599bc2602cb484f8cd647055caMike Lockwood return MTP_RESPONSE_OK; 72216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 7237850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 7247850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood} // namespace android 725