• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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