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 #ifndef _MTP_DEVICE_H 18 #define _MTP_DEVICE_H 19 20 #include "MtpEventPacket.h" 21 #include "MtpDataPacket.h" 22 #include "MtpRequestPacket.h" 23 #include "MtpResponsePacket.h" 24 #include "MtpTypes.h" 25 26 #include <mutex> 27 28 struct usb_device; 29 struct usb_request; 30 struct usb_endpoint_descriptor; 31 32 namespace android { 33 34 class MtpDeviceInfo; 35 class MtpEventPacket; 36 class MtpObjectInfo; 37 class MtpStorageInfo; 38 39 class MtpDevice { 40 private: 41 struct usb_device* mDevice; 42 int mInterface; 43 struct usb_request* mRequestIn1; 44 struct usb_request* mRequestIn2; 45 struct usb_request* mRequestOut; 46 struct usb_request* mRequestIntr; 47 MtpDeviceInfo* mDeviceInfo; 48 MtpPropertyList mDeviceProperties; 49 50 // current session ID 51 MtpSessionID mSessionID; 52 // current transaction ID 53 MtpTransactionID mTransactionID; 54 55 MtpRequestPacket mRequest; 56 MtpDataPacket mData; 57 MtpResponsePacket mResponse; 58 MtpEventPacket mEventPacket; 59 60 // set to true if we received a response packet instead of a data packet 61 bool mReceivedResponse; 62 bool mProcessingEvent; 63 int mCurrentEventHandle; 64 65 // to check if a sendObject request follows the last sendObjectInfo request. 66 MtpTransactionID mLastSendObjectInfoTransactionID; 67 MtpObjectHandle mLastSendObjectInfoObjectHandle; 68 69 // to ensure only one MTP transaction at a time 70 std::mutex mMutex; 71 std::mutex mEventMutex; 72 std::mutex mEventMutexForInterrupt; 73 74 // Remember the device's packet division mode. 75 UrbPacketDivisionMode mPacketDivisionMode; 76 77 public: 78 typedef bool (*ReadObjectCallback) 79 (void* data, uint32_t offset, uint32_t length, void* clientData); 80 81 MtpDevice(struct usb_device* device, 82 int interface, 83 const struct usb_endpoint_descriptor *ep_in, 84 const struct usb_endpoint_descriptor *ep_out, 85 const struct usb_endpoint_descriptor *ep_intr); 86 87 static MtpDevice* open(const char* deviceName, int fd); 88 89 virtual ~MtpDevice(); 90 91 void initialize(); 92 void close(); 93 void print(); 94 const char* getDeviceName(); 95 96 bool openSession(); 97 bool closeSession(); 98 99 MtpDeviceInfo* getDeviceInfo(); 100 MtpStorageIDList* getStorageIDs(); 101 MtpStorageInfo* getStorageInfo(MtpStorageID storageID); 102 MtpObjectHandleList* getObjectHandles(MtpStorageID storageID, MtpObjectFormat format, 103 MtpObjectHandle parent); 104 MtpObjectInfo* getObjectInfo(MtpObjectHandle handle); 105 void* getThumbnail(MtpObjectHandle handle, int& outLength); 106 MtpObjectHandle sendObjectInfo(MtpObjectInfo* info); 107 bool sendObject(MtpObjectHandle handle, uint32_t size, int srcFD); 108 bool deleteObject(MtpObjectHandle handle); 109 MtpObjectHandle getParent(MtpObjectHandle handle); 110 MtpStorageID getStorageID(MtpObjectHandle handle); 111 112 MtpObjectPropertyList* getObjectPropsSupported(MtpObjectFormat format); 113 114 MtpProperty* getDevicePropDesc(MtpDeviceProperty code); 115 MtpProperty* getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format); 116 117 // Reads value of |property| for |handle|. Returns true on success. 118 bool getObjectPropValue(MtpObjectHandle handle, MtpProperty* property); 119 120 bool readObject(MtpObjectHandle handle, ReadObjectCallback callback, 121 uint32_t objectSize, void* clientData); 122 bool readObject(MtpObjectHandle handle, const char* destPath, int group, 123 int perm); 124 bool readObject(MtpObjectHandle handle, int fd); 125 bool readPartialObject(MtpObjectHandle handle, 126 uint32_t offset, 127 uint32_t size, 128 uint32_t *writtenSize, 129 ReadObjectCallback callback, 130 void* clientData); 131 bool readPartialObject64(MtpObjectHandle handle, 132 uint64_t offset, 133 uint32_t size, 134 uint32_t *writtenSize, 135 ReadObjectCallback callback, 136 void* clientData); 137 // Starts a request to read MTP event from MTP device. It returns a request handle that 138 // can be used for blocking read or cancel. If other thread has already been processing an 139 // event returns -1. 140 int submitEventRequest(); 141 // Waits for MTP event from the device and returns MTP event code. It blocks the current thread 142 // until it receives an event from the device. |handle| should be a request handle returned 143 // by |submitEventRequest|. The function writes event parameters to |parameters|. Returns 0 for 144 // cancellations. Returns -1 for errors. 145 int reapEventRequest(int handle, uint32_t (*parameters)[3]); 146 // Cancels an event request. |handle| should be request handle returned by 147 // |submitEventRequest|. If there is a thread blocked by |reapEventRequest| with the same 148 // |handle|, the thread will resume. 149 void discardEventRequest(int handle); 150 151 private: 152 // If |objectSize| is not NULL, it checks object size before reading data bytes. 153 bool readObjectInternal(MtpObjectHandle handle, 154 ReadObjectCallback callback, 155 const uint32_t* objectSize, 156 void* clientData); 157 // If |objectSize| is not NULL, it checks object size before reading data bytes. 158 bool readData(ReadObjectCallback callback, 159 const uint32_t* objectSize, 160 uint32_t* writtenData, 161 void* clientData); 162 bool sendRequest(MtpOperationCode operation); 163 bool sendData(); 164 bool readData(); 165 bool writeDataHeader(MtpOperationCode operation, int dataLength); 166 MtpResponseCode readResponse(); 167 }; 168 169 }; // namespace android 170 171 #endif // _MTP_DEVICE_H 172