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 bool isActive; 119 }; 120 121 struct UsbMtpDevice { 122 struct UsbFnDevice *fnDev; 123 struct UsbMtpInterface ctrlIface; 124 struct UsbMtpInterface intrIface; 125 struct UsbMtpInterface dataIface; 126 struct UsbMtpPipe notifyPipe; /* intr-in */ 127 struct UsbMtpPipe dataInPipe; /* bulk-in */ 128 struct UsbMtpPipe dataOutPipe; /* bulk-out */ 129 struct DListHead ctrlPool; 130 int32_t ctrlReqNum; 131 struct UsbFnRequest *notifyReq; 132 struct UsbMtpPort *mtpPort; 133 const char *udcName; 134 uint64_t asyncRecvFileActual; 135 uint64_t asyncRecvFileExpect; 136 uint64_t asyncSendFileActual; /* already send actual */ 137 uint64_t asyncSendFileExpect; /* already send expect */ 138 uint8_t asyncXferFile; 139 uint8_t needZLP; 140 uint32_t asyncRecvWriteTempCount; 141 uint8_t *asyncRecvWriteTempContent; 142 bool initFlag; 143 uint8_t mtpState; /* record mtp state, example: MTP_STATE_OFFLINE */ 144 uint8_t xferSendHeader; /* two value: 0 1 */ 145 uint16_t xferCommand; /* refer to struct UsbMtpFileRange.command */ 146 uint32_t xferTransactionId; /* refer to struct UsbMtpFileRange.transactionId */ 147 int32_t xferFd; 148 uint64_t xferFileOffset; 149 uint64_t xferFileLength; 150 }; 151 152 struct CtrlInfo { 153 uint8_t request; 154 struct UsbMtpDevice *mtpDev; 155 }; 156 157 namespace OHOS { 158 namespace HDI { 159 namespace Usb { 160 namespace Gadget { 161 namespace Mtp { 162 namespace V1_0 { 163 class UsbfnMtpImpl : public IUsbfnMtpInterface { 164 public: 165 UsbfnMtpImpl(); 166 virtual ~UsbfnMtpImpl() = default; 167 168 HdfDeviceObject *deviceObject_; 169 170 /* Return 0 if operation is successful */ 171 int32_t Start() override; 172 /* Return 0 if operation is successful */ 173 int32_t Stop() override; 174 /* Return 0 if operation is successful */ 175 int32_t Read(std::vector<uint8_t> &data) override; 176 /* Return 0 if operation is successful */ 177 int32_t Write(const std::vector<uint8_t> &data) override; 178 /* Return 0 if send/receive is successful */ 179 int32_t ReceiveFile(const UsbFnMtpFileSlice &mfs) override; 180 /* Return 0 if send/receive is successful */ 181 int32_t SendFile(const UsbFnMtpFileSlice &mfs) override; 182 /* Return 0 if send/receive is successful */ 183 int32_t SendEvent(const std::vector<uint8_t> &eventData) override; 184 185 int32_t Init() override; 186 int32_t Release() override; 187 188 private: 189 static void UsbFnRequestReadComplete(uint8_t pipe, struct UsbFnRequest *req); 190 static void UsbFnRequestWriteComplete(uint8_t pipe, struct UsbFnRequest *req); 191 static void UsbFnRequestNotifyComplete(uint8_t pipe, struct UsbFnRequest *req); 192 static void UsbFnRequestCtrlComplete(uint8_t pipe, struct UsbFnRequest *req); 193 194 static int32_t UsbMtpPortTxReqCheck(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 195 static int32_t UsbMtpPortProcessLastTxPacket(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 196 static int32_t UsbMtpPortSubmitAsyncTxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 197 static int32_t UsbMtpPortStartTxAsync(struct UsbMtpPort *mtpPort, bool callByComplete); 198 static int32_t UsbMtpPortProcessAsyncRxDone(struct UsbMtpPort *mtpPort); 199 static int32_t UsbMtpPortRxPush(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 200 static int32_t UsbMtpPortStartSubmitRxReq(struct UsbMtpPort *mtpPort, bool needZLP); 201 static int32_t UsbMtpPortStartRxAsync(struct UsbMtpPort *mtpPort); 202 static int32_t UsbMtpPortRxCheckReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req, bool &writeToFile); 203 static void UsbMtpPortReleaseRxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 204 static void UsbMtpPortReleaseTxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req); 205 static int32_t UsbMtpPortCancelAndFreeReq( 206 struct DListHead *queueHead, struct DListHead *poolHead, int32_t &allocated, bool freeReq); 207 static int32_t UsbMtpPortCancelPlusFreeIo(struct UsbMtpPort *mtpPort, bool freeReq); 208 static int32_t UsbMtpPortCancelRequest(struct UsbMtpPort *mtpPort); 209 static struct UsbFnRequest *UsbMtpDeviceGetCtrlReq(struct UsbMtpDevice *mtpDev); 210 static int32_t UsbMtpDeviceStandardRequest( 211 struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req); 212 static int32_t UsbMtpDeviceClassRequest( 213 struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req); 214 static int32_t UsbMtpDeviceVendorRequest( 215 struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req); 216 static int32_t UsbMtpDeviceSetup(struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup); 217 static void UsbMtpDeviceSuspend(struct UsbMtpDevice *mtpDev); 218 static void UsbMtpDeviceResume(struct UsbMtpDevice *mtpDev); 219 static int32_t UsbMtpDeviceEnable(struct UsbMtpDevice *mtpDev); 220 static int32_t UsbMtpDeviceDisable(struct UsbMtpDevice *mtpDev); 221 static void UsbMtpDeviceEp0EventDispatch(struct UsbFnEvent *event); 222 static void CopyReqToStandbyReqPool(const struct UsbFnRequest *req, struct UsbFnRequest *standbyReq); 223 int32_t UsbMtpDeviceAllocCtrlRequests(int32_t num); 224 void UsbMtpDeviceFreeCtrlRequests(); 225 void UsbMtpPortFreeRequests(struct DListHead *head, int32_t &allocated); 226 int32_t UsbMtpPortAllocReadWriteRequests(int32_t readSize, int32_t writeSize); 227 int32_t UsbMtpPortInitIo(); 228 int32_t UsbMtpPortReleaseIo(); 229 int32_t UsbMtpDeviceParseEachPipe(struct UsbMtpInterface &iface); 230 int32_t UsbMtpDeviceParseMtpIface(struct UsbFnInterface *fnIface); 231 bool UsbFnInterfaceIsUsbMtpPtpDevice(struct UsbFnInterface *iface); 232 int32_t UsbMtpDeviceParseEachIface(struct UsbFnDevice *fnDev); 233 int32_t UsbMtpDeviceCreateFuncDevice(); 234 int32_t UsbMtpDeviceReleaseFuncDevice(); 235 int32_t UsbMtpDeviceAlloc(); 236 int32_t UsbMtpDeviceFree(); 237 int32_t UsbMtpDeviceAllocNotifyRequest(); 238 void UsbMtpDeviceFreeNotifyRequest(); 239 int32_t InitMtpPort(); 240 int32_t WriteEx(const std::vector<uint8_t> &data, uint8_t sendZLP, uint32_t &xferActual); 241 int32_t WriteSplitPacket(const std::vector<uint8_t> &data); 242 uint32_t getActualLength(const std::vector<uint8_t> &data); 243 int32_t ReadImpl(std::vector<uint8_t> &data); 244 int32_t UsbMtpPortSendFileFillFirstReq(struct UsbFnRequest *req, uint64_t &oneReqLeft); 245 int32_t UsbMtpPortSendFileEx(); 246 int32_t UsbMtpPortSendFileLeftAsync(uint64_t oneReqLeft); 247 int32_t ReceiveFileEx(); 248 void ReadZLP(uint32_t length, uint32_t actual); 249 uint32_t BufCopyToVector(void *buf, uint32_t bufSize, std::vector<uint8_t> &vectorData); 250 uint32_t BufCopyFromVector( 251 void *buf, uint32_t bufSize, const std::vector<uint8_t> &vectorData, uint32_t vectorOffset); 252 void UsbMtpSendFileParamSet(const UsbFnMtpFileSlice &mfs); 253 static struct UsbMtpDevice *mtpDev_; 254 static struct UsbMtpPort *mtpPort_; 255 static std::mutex startMutex_; 256 static std::mutex readMutex_; 257 static std::mutex writeMutex_; 258 static std::mutex eventMutex_; 259 static std::mutex asyncMutex_; 260 static sem_t asyncReq_; 261 static pthread_rwlock_t mtpRunrwLock_; 262 std::vector<uint8_t> vectorSplited_; 263 uint32_t writeActualLen_ = 0; 264 }; 265 } // namespace V1_0 266 } // namespace Mtp 267 } // namespace Gadget 268 } // namespace Usb 269 } // namespace HDI 270 } // namespace OHOS 271 272 #endif // OHOS_HDI_USB_GADGET_MTP_V1_0_USBFNMTPIMPL_H 273