MtpDevice.cpp revision 755fd617258d3f1731b2829d681cab680db0fdd5
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdio.h> 18#include <stdlib.h> 19#include <sys/types.h> 20#include <sys/ioctl.h> 21#include <sys/stat.h> 22#include <fcntl.h> 23#include <errno.h> 24 25#include <usbhost/usbhost.h> 26 27#include "MtpDevice.h" 28#include "MtpDebug.h" 29#include "MtpDeviceInfo.h" 30#include "MtpObjectInfo.h" 31#include "MtpStorageInfo.h" 32#include "MtpStringBuffer.h" 33 34namespace android { 35 36MtpDevice::MtpDevice(struct usb_device* device, int interface, 37 struct usb_endpoint *ep_in, struct usb_endpoint *ep_out, 38 struct usb_endpoint *ep_intr) 39 : mDevice(device), 40 mInterface(interface), 41 mEndpointIn(ep_in), 42 mEndpointOut(ep_out), 43 mEndpointIntr(ep_intr), 44 mDeviceInfo(NULL), 45 mID(usb_device_get_unique_id(device)), 46 mSessionID(0), 47 mTransactionID(0) 48{ 49} 50 51MtpDevice::~MtpDevice() { 52 close(); 53} 54 55void MtpDevice::initialize() { 56 openSession(); 57 mDeviceInfo = getDeviceInfo(); 58 if (mDeviceInfo) { 59 mDeviceInfo->print(); 60 } 61} 62 63void MtpDevice::close() { 64 if (mDevice) { 65 usb_device_release_interface(mDevice, mInterface); 66 usb_device_close(mDevice); 67 mDevice = NULL; 68 } 69} 70 71const char* MtpDevice::getDeviceName() { 72 if (mDevice) 73 return usb_device_get_name(mDevice); 74 else 75 return "???"; 76} 77 78bool MtpDevice::openSession() { 79printf("openSession\n"); 80 mSessionID = 0; 81 mTransactionID = 0; 82 MtpSessionID newSession = 1; 83 mRequest.reset(); 84 mRequest.setParameter(1, newSession); 85 if (!sendRequest(MTP_OPERATION_OPEN_SESSION)) 86 return false; 87 MtpResponseCode ret = readResponse(); 88 if (ret == MTP_RESPONSE_SESSION_ALREADY_OPEN) 89 newSession = mResponse.getParameter(1); 90 else if (ret != MTP_RESPONSE_OK) 91 return false; 92 93 mSessionID = newSession; 94 mTransactionID = 1; 95 return true; 96} 97 98bool MtpDevice::closeSession() { 99 // FIXME 100 return true; 101} 102 103MtpDeviceInfo* MtpDevice::getDeviceInfo() { 104 mRequest.reset(); 105 if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO)) 106 return NULL; 107 if (!readData()) 108 return NULL; 109 MtpResponseCode ret = readResponse(); 110printf("getDeviceInfo returned %04X\n", ret); 111 if (ret == MTP_RESPONSE_OK) { 112 MtpDeviceInfo* info = new MtpDeviceInfo; 113 info->read(mData); 114 return info; 115 } 116 return NULL; 117} 118 119MtpStorageIDList* MtpDevice::getStorageIDs() { 120 mRequest.reset(); 121 if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS)) 122 return NULL; 123 if (!readData()) 124 return NULL; 125 MtpResponseCode ret = readResponse(); 126 if (ret == MTP_RESPONSE_OK) { 127 return mData.getAUInt32(); 128 } 129 return NULL; 130} 131 132MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) { 133 mRequest.reset(); 134 mRequest.setParameter(1, storageID); 135 if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO)) 136 return NULL; 137 if (!readData()) 138 return NULL; 139 MtpResponseCode ret = readResponse(); 140printf("getStorageInfo returned %04X\n", ret); 141 if (ret == MTP_RESPONSE_OK) { 142 MtpStorageInfo* info = new MtpStorageInfo(storageID); 143 info->read(mData); 144 return info; 145 } 146 return NULL; 147} 148 149MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID, 150 MtpObjectFormat format, MtpObjectHandle parent) { 151 mRequest.reset(); 152 mRequest.setParameter(1, storageID); 153 mRequest.setParameter(2, format); 154 mRequest.setParameter(3, parent); 155 if (!sendRequest(MTP_OPERATION_GET_OBJECT_HANDLES)) 156 return NULL; 157 if (!readData()) 158 return NULL; 159 MtpResponseCode ret = readResponse(); 160printf("getObjectHandles returned %04X\n", ret); 161 if (ret == MTP_RESPONSE_OK) { 162 return mData.getAUInt32(); 163 } 164 return NULL; 165} 166 167MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) { 168 mRequest.reset(); 169 mRequest.setParameter(1, handle); 170 if (!sendRequest(MTP_OPERATION_GET_OBJECT_INFO)) 171 return NULL; 172 if (!readData()) 173 return NULL; 174 MtpResponseCode ret = readResponse(); 175printf("getObjectInfo returned %04X\n", ret); 176 if (ret == MTP_RESPONSE_OK) { 177 MtpObjectInfo* info = new MtpObjectInfo(handle); 178 info->read(mData); 179 return info; 180 } 181 return NULL; 182} 183 184bool MtpDevice::sendRequest(MtpOperationCode operation) { 185 printf("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation)); 186 mRequest.setOperationCode(operation); 187 if (mTransactionID > 0) 188 mRequest.setTransactionID(mTransactionID++); 189 int ret = mRequest.write(mEndpointOut); 190 mRequest.dump(); 191 return (ret > 0); 192} 193 194bool MtpDevice::sendData(MtpOperationCode operation) { 195 printf("sendData\n"); 196 mData.setOperationCode(mRequest.getOperationCode()); 197 mData.setTransactionID(mRequest.getTransactionID()); 198 int ret = mData.write(mEndpointOut); 199 mData.dump(); 200 return (ret > 0); 201} 202 203bool MtpDevice::readData() { 204 mData.reset(); 205 int ret = mData.read(mEndpointIn); 206 printf("readData returned %d\n", ret); 207 if (ret >= MTP_CONTAINER_HEADER_SIZE) { 208 mData.dump(); 209 return true; 210 } 211 else { 212 printf("readResponse failed\n"); 213 return false; 214 } 215} 216 217MtpResponseCode MtpDevice::readResponse() { 218 printf("readResponse\n"); 219 int ret = mResponse.read(mEndpointIn); 220 if (ret >= MTP_CONTAINER_HEADER_SIZE) { 221 mResponse.dump(); 222 return mResponse.getResponseCode(); 223 } 224 else { 225 printf("readResponse failed\n"); 226 return -1; 227 } 228} 229 230} // namespace android 231