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