1 /* 2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef OHOS_HDI_USB_GADGET_MTP_V1_0_USBFNMTPIMPL_H 17 #define OHOS_HDI_USB_GADGET_MTP_V1_0_USBFNMTPIMPL_H 18 19 #include <semaphore.h> 20 #include <mutex> 21 #include <semaphore.h> 22 #include <pthread.h> 23 24 #include "data_fifo.h" 25 #include "hdf_base.h" 26 #include "hdf_device_desc.h" 27 #include "usbfn_device.h" 28 #include "usbfn_interface.h" 29 #include "usbfn_request.h" 30 #include "v1_0/iusbfn_mtp_interface.h" 31 32 // MTP interface descriptor 33 #define USB_MTP_DEVICE_CLASS USB_DDK_CLASS_VENDOR_SPEC 34 #define USB_MTP_DEVICE_SUBCLASS USB_DDK_SUBCLASS_VENDOR_SPEC 35 #define USB_MTP_DEVICE_PROTOCOL 0 36 37 // PTP interface descriptor 38 #define USB_PTP_DEVICE_CLASS USB_DDK_CLASS_STILL_IMAGE 39 #define USB_PTP_DEVICE_SUBCLASS 1 40 #define USB_PTP_DEVICE_PROTOCOL 1 41 #define MTP_CONTROL_XFER_BYTECOUNT 512 42 43 /* req count for control xfer */ 44 #define MTP_CTRL_REQUEST_NUM 2 45 46 /* req count for bulk-out xfer */ 47 #define READ_QUEUE_SIZE 8 48 49 /* req count for bulk-in xfer */ 50 #define WRITE_QUEUE_SIZE 8 51 #define BULK_WRITE_BUF_SIZE 8192 52 #define BULK_READ_BUF_SIZE 8192 53 #define USB_HS_INTR_PACKET_MAX_BYTES 1024 54 55 /* MTP event packet max length */ 56 #define MTP_EVENT_PACKET_MAX_BYTES 28 57 58 /* values for UsbMtpDevice.mtpState */ 59 enum UsbMtpDeviceState { 60 MTP_STATE_OFFLINE = 0, /* initial state, disconnected */ 61 MTP_STATE_READY, /* ready for userspace calls */ 62 MTP_STATE_BUSY, /* processing userspace calls */ 63 MTP_STATE_CANCELED, /* transaction canceled by host */ 64 MTP_STATE_ERROR, /* error from completion routine */ 65 }; 66 67 /* Compatible: ID for Microsoft MTP OS String */ 68 #define USB_MTP_OS_STRING_ID 0xEE 69 #define USB_MTP_BMS_VENDORCODE 0x01 70 #define USB_MTP_EXTENDED_COMPAT_ID 0x0004 71 #define USB_MTP_EXTENDED_PROPERTIES 0x0005 72 73 /* MTP class reqeusts */ 74 #define USB_MTP_REQ_CANCEL 0x64 75 #define USB_MTP_REQ_GET_EXT_EVENT_DATA 0x65 76 #define USB_MTP_REQ_RESET 0x66 77 #define USB_MTP_REQ_GET_DEVICE_STATUS 0x67 78 79 /* constants for device status */ 80 #define MTP_RESPONSE_OK 0x2001 81 #define MTP_RESPONSE_DEVICE_BUSY 0x2019 82 83 struct UsbMtpDataHeader { 84 uint32_t length; 85 uint16_t type; /* defined mtp data type */ 86 uint16_t cmdCode; /* Operation, Response or Event Code in mtp */ 87 uint32_t transactionId; 88 }; 89 90 struct UsbMtpPipe { 91 uint8_t id; 92 uint16_t maxPacketSize; 93 struct UsbFnInterface *ctrlIface; 94 }; 95 96 struct UsbMtpInterface { 97 struct UsbFnInterface *fn; 98 UsbFnInterfaceHandle handle; 99 }; 100 101 struct UsbMtpPort { 102 struct UsbMtpDevice *mtpDev; 103 struct DListHead readPool; /* ready/idle read(bulk-out) req */ 104 struct DListHead readQueue; /* working async read(bulk-out) req */ 105 struct UsbFnRequest *standbyReq; 106 int32_t readStarted; 107 int32_t readAllocated; 108 struct DataFifo readFifo; 109 struct DListHead writePool; /* ready/idle write(bulk-in) req */ 110 struct DListHead writeQueue; /* working async write(bulk-in) req */ 111 int32_t writeStarted; 112 int32_t writeAllocated; 113 struct DataFifo writeFifo; 114 bool writeBusy; 115 bool suspended; 116 bool startDelayed; 117 int32_t refCount; 118 }; 119 120 struct UsbMtpDevice { 121 struct UsbFnDevice *fnDev; 122 struct UsbMtpInterface ctrlIface; 123 struct UsbMtpInterface intrIface; 124 struct UsbMtpInterface dataIface; 125 struct UsbMtpPipe notifyPipe; /* intr-in */ 126 struct UsbMtpPipe dataInPipe; /* bulk-in */ 127 struct UsbMtpPipe dataOutPipe; /* bulk-out */ 128 struct DListHead ctrlPool; 129 int32_t ctrlReqNum; 130 struct UsbFnRequest *notifyReq; 131 struct UsbMtpPort *mtpPort; 132 const char *udcName; 133 uint64_t asyncRecvFileActual; 134 uint64_t asyncRecvFileExpect; 135 uint64_t asyncSendFileActual; /* already send actual */ 136 uint64_t asyncSendFileExpect; /* already send expect */ 137 uint8_t asyncXferFile; 138 uint8_t needZLP; 139 uint32_t asyncRecvWriteTempCount; 140 uint8_t *asyncRecvWriteTempContent; 141 bool initFlag; 142 uint8_t mtpState; /* record mtp state, example: MTP_STATE_OFFLINE */ 143 uint8_t xferSendHeader; /* two value: 0 1 */ 144 uint16_t xferCommand; /* refer to struct UsbMtpFileRange.command */ 145 uint32_t xferTransactionId; /* refer to struct UsbMtpFileRange.transactionId */ 146 int32_t xferFd; 147 uint64_t xferFileOffset; 148 uint64_t xferFileLength; 149 }; 150 151 struct CtrlInfo { 152 uint8_t request; 153 struct UsbMtpDevice *mtpDev; 154 }; 155 156 namespace OHOS { 157 namespace HDI { 158 namespace Usb { 159 namespace Gadget { 160 namespace Mtp { 161 namespace V1_0 { 162 class UsbfnMtpImpl : public IUsbfnMtpInterface { 163 public: 164 UsbfnMtpImpl(); 165 virtual ~UsbfnMtpImpl() = default; 166 167 HdfDeviceObject *deviceObject_; 168 169 /* Return 0 if operation is successful */ 170 int32_t Start() override; 171 /* Return 0 if operation is successful */ 172 int32_t Stop() override; 173 /* Return 0 if operation is successful */ 174 int32_t Read(std::vector<uint8_t> &data) override; 175 /* Return 0 if operation is successful */ 176 int32_t Write(const std::vector<uint8_t> &data) override; 177 /* Return 0 if send/receive is successful */ 178 int32_t ReceiveFile(const UsbFnMtpFileSlice &mfs) override; 179 /* Return 0 if send/receive is successful */ 180 int32_t SendFile(const UsbFnMtpFileSlice &mfs) override; 181 /* Return 0 if send/receive is successful */ 182 int32_t SendEvent(const std::vector<uint8_t> &eventData) override; 183 184 int32_t Init() override; 185 int32_t Release() override; 186 187 private: 188 static void UsbFnRequestReadComplete(uint8_t pipe, struct UsbFnRequest *req); 189 static void UsbFnRequestWriteComplete(uint8_t pipe, struct UsbFnRequest *req); 190 static void UsbFnRequestNotifyComplete(uint8_t pipe, struct UsbFnRequest *req); 191 static void UsbFnRequestCtrlComplete(uint8_t pipe, struct UsbFnRequest *req); 192 193 static int32_t UsbMtpPortTxReqCheck(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 194 static int32_t UsbMtpPortProcessLastTxPacket(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 195 static int32_t UsbMtpPortSubmitAsyncTxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 196 static int32_t UsbMtpPortStartTxAsync(struct UsbMtpPort *mtpPort, bool callByComplete); 197 static int32_t UsbMtpPortProcessAsyncRxDone(struct UsbMtpPort *mtpPort); 198 static int32_t UsbMtpPortRxPush(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 199 static int32_t UsbMtpPortStartSubmitRxReq(struct UsbMtpPort *mtpPort, bool needZLP); 200 static int32_t UsbMtpPortStartRxAsync(struct UsbMtpPort *mtpPort); 201 static int32_t UsbMtpPortRxCheckReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req, bool &writeToFile); 202 static void UsbMtpPortReleaseRxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 203 static void UsbMtpPortReleaseTxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 204 static int32_t UsbMtpPortCancelAndFreeReq( 205 struct DListHead *queueHead, struct DListHead *poolHead, int32_t &allocated, bool freeReq); 206 static int32_t UsbMtpPortCancelPlusFreeIo(struct UsbMtpPort *mtpPort, bool freeReq); 207 static int32_t UsbMtpPortCancelRequest(struct UsbMtpPort *mtpPort); 208 static struct UsbFnRequest *UsbMtpDeviceGetCtrlReq(struct UsbMtpDevice *mtpDev); 209 static int32_t UsbMtpDeviceStandardRequest( 210 struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req); 211 static int32_t UsbMtpDeviceClassRequest( 212 struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req); 213 static int32_t UsbMtpDeviceVendorRequest( 214 struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req); 215 static int32_t UsbMtpDeviceSetup(struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup); 216 static void UsbMtpDeviceSuspend(struct UsbMtpDevice *mtpDev); 217 static void UsbMtpDeviceResume(struct UsbMtpDevice *mtpDev); 218 static int32_t UsbMtpDeviceEnable(struct UsbMtpDevice *mtpDev); 219 static int32_t UsbMtpDeviceDisable(struct UsbMtpDevice *mtpDev); 220 static void UsbMtpDeviceEp0EventDispatch(struct UsbFnEvent *event); 221 static void CopyReqToStandbyReqPool(const struct UsbFnRequest *req, struct UsbFnRequest *standbyReq); 222 int32_t UsbMtpDeviceAllocCtrlRequests(int32_t num); 223 void UsbMtpDeviceFreeCtrlRequests(); 224 void UsbMtpPortFreeRequests(struct DListHead *head, int32_t &allocated); 225 int32_t UsbMtpPortAllocReadWriteRequests(int32_t readSize, int32_t writeSize); 226 int32_t UsbMtpPortInitIo(); 227 int32_t UsbMtpPortReleaseIo(); 228 int32_t UsbMtpDeviceParseEachPipe(struct UsbMtpInterface &iface); 229 int32_t UsbMtpDeviceParseMtpIface(struct UsbFnInterface *fnIface); 230 bool UsbFnInterfaceIsUsbMtpPtpDevice(struct UsbFnInterface *iface); 231 int32_t UsbMtpDeviceParseEachIface(struct UsbFnDevice *fnDev); 232 int32_t UsbMtpDeviceCreateFuncDevice(); 233 int32_t UsbMtpDeviceReleaseFuncDevice(); 234 int32_t UsbMtpDeviceAlloc(); 235 int32_t UsbMtpDeviceFree(); 236 int32_t UsbMtpDeviceAllocNotifyRequest(); 237 void UsbMtpDeviceFreeNotifyRequest(); 238 int32_t InitMtpPort(); 239 int32_t WriteEx(const std::vector<uint8_t> &data, uint8_t sendZLP, uint32_t &xferActual); 240 int32_t WriteSplitPacket(const std::vector<uint8_t> &data); 241 uint32_t getActualLength(const std::vector<uint8_t> &data); 242 int32_t ReadImpl(std::vector<uint8_t> &data); 243 int32_t UsbMtpPortSendFileFillFirstReq(struct UsbFnRequest *req, uint64_t &oneReqLeft); 244 int32_t UsbMtpPortSendFileEx(); 245 int32_t UsbMtpPortSendFileLeftAsync(uint64_t oneReqLeft); 246 int32_t ReceiveFileEx(); 247 248 uint32_t BufCopyToVector(void *buf, uint32_t bufSize, std::vector<uint8_t> &vectorData); 249 uint32_t BufCopyFromVector( 250 void *buf, uint32_t bufSize, const std::vector<uint8_t> &vectorData, uint32_t vectorOffset); 251 void UsbMtpSendFileParamSet(const UsbFnMtpFileSlice &mfs); 252 static struct UsbMtpDevice *mtpDev_; 253 static struct UsbMtpPort *mtpPort_; 254 static std::mutex startMutex_; 255 static std::mutex readMutex_; 256 static std::mutex writeMutex_; 257 static std::mutex eventMutex_; 258 static std::mutex asyncMutex_; 259 static sem_t asyncReq_; 260 static pthread_rwlock_t mtpRunrwLock_; 261 std::vector<uint8_t> vectorSplited_; 262 uint32_t writeActualLen_; 263 }; 264 } // namespace V1_0 265 } // namespace Mtp 266 } // namespace Gadget 267 } // namespace Usb 268 } // namespace HDI 269 } // namespace OHOS 270 271 #endif // OHOS_HDI_USB_GADGET_MTP_V1_0_USBFNMTPIMPL_H 272