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 #include "usbfn_mtp_impl.h"
17 #include <unistd.h>
18 #include <cinttypes>
19 #include <sys/mman.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include "hdf_base.h"
24 #include "hdf_device_desc.h"
25 #include "hdf_log.h"
26 
27 #define HDF_LOG_TAG usbfn_mtp_impl
28 #define UDC_NAME "invalid_udc_name"
29 
30 /* Compatible: Microsoft MTP OS String */
31 static uint8_t g_mtpOsString[] = {18, /* sizeof(mtp_os_string) */
32     USB_DDK_DT_STRING,
33     /* Signature field: "MSFT100" (4D00530046005400310030003000) */
34     'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0,
35     /* Vendor code to fetch other OS feature descriptors */
36     1,
37     /* padding */
38     0};
39 
40 /* Microsoft Extended Configuration Descriptor Header Section */
41 struct UsbMtpExtConfigDescHeader {
42     uint32_t dwLength;
43     uint16_t bcdVersion;
44     uint16_t wIndex;
45     uint8_t bCount;
46     uint8_t reserved[7]; /* reserved */
47 };
48 
49 /* Microsoft Extended Configuration Descriptor Function Section */
50 struct UsbMtpExtConfigDescFunction {
51     uint8_t bFirstInterfaceNumber;
52     uint8_t bInterfaceCount;
53     uint8_t compatibleID[8];    /* The function’s compatible ID */
54     uint8_t subCompatibleID[8]; /* The function’s subcompatible ID */
55     uint8_t reserved[6];        /* reserved */
56 };
57 
58 /* Compatible: MTP Extended Configuration Descriptor */
59 static struct {
60     struct UsbMtpExtConfigDescHeader header;
61     struct UsbMtpExtConfigDescFunction function;
62 } g_mtpExtConfigDesc = {
63     .header = {
64         .dwLength = CPU_TO_LE32(sizeof(g_mtpExtConfigDesc)),
65         /* The descriptor’s version number in Binary Coded Decimal (for example, version 1.00 is 0100H) */
66         .bcdVersion = CPU_TO_LE16(0x0100),
67         /* set to 0x04 for extended compat ID descriptors */
68         .wIndex = CPU_TO_LE16(4),
69         /* Number of function sections */
70         .bCount = CPU_TO_LE16(1),
71         .reserved = {0},
72     },
73     .function = {
74         .bFirstInterfaceNumber = 0,
75         .bInterfaceCount = 1,
76         /* Media Transfer Protocol */
77         .compatibleID = {'M', 'T', 'P'},
78         .subCompatibleID = {0},
79         .reserved = {0},
80     },
81 };
82 
83 struct UsbMtpDeviceStatus {
84     uint16_t wLength;
85     uint16_t wCode;
86 };
87 
88 namespace OHOS {
89 namespace HDI {
90 namespace Usb {
91 namespace Gadget {
92 namespace Mtp {
93 namespace V1_0 {
94 sptr<IUsbfnMtpInterface> g_instance = nullptr;
95 std::mutex g_instanceLock;
UsbfnMtpInterfaceImplGetInstance(void)96 extern "C" void *UsbfnMtpInterfaceImplGetInstance(void)
97 {
98     std::lock_guard<std::mutex> guard(g_instanceLock);
99     if (g_instance == nullptr) {
100         sptr<IUsbfnMtpInterface> tmp(new (std::nothrow) UsbfnMtpImpl);
101         g_instance = tmp;
102     }
103 
104     return g_instance;
105 }
106 
107 struct UsbMtpDevice *UsbfnMtpImpl::mtpDev_ = nullptr;
108 struct UsbMtpPort *UsbfnMtpImpl::mtpPort_ = nullptr;
109 std::mutex UsbfnMtpImpl::mtpRunning_;
110 std::mutex UsbfnMtpImpl::asyncMutex_;
111 sem_t UsbfnMtpImpl::asyncReq_ {0};
112 
113 constexpr uint32_t BULK_IN_TIMEOUT_JIFFIES = 0;  /* sync timeout, set to 0 means wait forever */
114 constexpr uint32_t BULK_OUT_TIMEOUT_JIFFIES = 0; /* sync timeout, set to 0 means wait forever */
115 constexpr uint32_t INTR_IN_TIMEOUT_JIFFIES = 0;  /* sync timeout, set to 0 means wait forever */
116 constexpr uint64_t MTP_MAX_FILE_SIZE = 0xFFFFFFFFULL;
117 constexpr uint32_t WRITE_FILE_TEMP_SLICE = 100 * 1024; /* 100KB */
118 static constexpr int32_t WAIT_UDC_MAX_LOOP = 3;
119 static constexpr uint32_t WAIT_UDC_TIME = 100000;
120 enum UsbMtpNeedZeroLengthPacket {
121     ZLP_NO_NEED = 0, /* no need send ZLP */
122     ZLP_NEED,        /* need send ZLP */
123     ZLP_TRY,         /* try send ZLP */
124     ZLP_DONE,        /* send ZLP done */
125 };
126 
127 enum UsbMtpAsyncXferState {
128     ASYNC_XFER_FILE_NORMAL = 0,
129     ASYNC_XFER_FILE_DONE,
130 };
131 
UsbfnMtpImpl()132 UsbfnMtpImpl::UsbfnMtpImpl() : deviceObject_(nullptr) {}
133 
UsbFnRequestReadComplete(uint8_t pipe,struct UsbFnRequest * req)134 void UsbfnMtpImpl::UsbFnRequestReadComplete(uint8_t pipe, struct UsbFnRequest *req)
135 {
136     (void)pipe;
137     if (req == nullptr || req->context == nullptr) {
138         HDF_LOGE("%{public}s: invalid param", __func__);
139         return;
140     }
141     struct UsbMtpPort *mtpPort = static_cast<struct UsbMtpPort *>(req->context);
142     DListRemove(&req->list);
143     DListInsertTail(&req->list, &mtpPort->readPool);
144     mtpPort->readStarted--;
145     if (mtpPort->mtpDev == nullptr) {
146         HDF_LOGE("%{public}s: invalid content", __func__);
147         return;
148     }
149     int32_t ret = UsbMtpPortRxPush(mtpPort, req);
150     if (ret != HDF_SUCCESS) {
151         HDF_LOGW("%{public}s: rx push failed(%{%{public}d/%{public}d}): %{public}d, state=%{public}hhu", __func__,
152             mtpPort->readStarted, mtpPort->readAllocated, ret, mtpPort->mtpDev->mtpState);
153     }
154     if (mtpPort->readStarted == 0 && mtpPort->writeStarted == 0 && mtpPort->mtpDev->mtpState == MTP_STATE_CANCELED) {
155         mtpPort->mtpDev->mtpState = MTP_STATE_READY;
156     }
157 }
158 
UsbFnRequestWriteComplete(uint8_t pipe,struct UsbFnRequest * req)159 void UsbfnMtpImpl::UsbFnRequestWriteComplete(uint8_t pipe, struct UsbFnRequest *req)
160 {
161     (void)pipe;
162     if (req == nullptr || req->context == nullptr) {
163         HDF_LOGE("%{public}s: invalid param", __func__);
164         return;
165     }
166     struct UsbMtpPort *mtpPort = static_cast<struct UsbMtpPort *>(req->context);
167     DListRemove(&req->list);
168     DListInsertTail(&req->list, &mtpPort->writePool);
169     if (mtpPort->mtpDev == nullptr) {
170         HDF_LOGE("%{public}s: invalid content", __func__);
171         return;
172     }
173     mtpPort->writeStarted--;
174     int32_t ret = UsbMtpPortTxReqCheck(mtpPort, req);
175     if (ret != HDF_SUCCESS) {
176         HDF_LOGW("%{public}s: tx check failed(%{%{public}d/%{public}d}): %{public}d, state=%{public}hhu", __func__,
177             mtpPort->readStarted, mtpPort->readAllocated, ret, mtpPort->mtpDev->mtpState);
178     }
179     if (mtpPort->readStarted == 0 && mtpPort->writeStarted == 0 && mtpPort->mtpDev->mtpState == MTP_STATE_CANCELED) {
180         mtpPort->mtpDev->mtpState = MTP_STATE_READY;
181     }
182 }
183 
UsbFnRequestNotifyComplete(uint8_t pipe,struct UsbFnRequest * req)184 void UsbfnMtpImpl::UsbFnRequestNotifyComplete(uint8_t pipe, struct UsbFnRequest *req)
185 {
186     (void)pipe;
187     if (req == nullptr || req->context == nullptr) {
188         HDF_LOGE("%{public}s: invalid param", __func__);
189         return;
190     }
191 }
192 
UsbFnRequestCtrlComplete(uint8_t pipe,struct UsbFnRequest * req)193 void UsbfnMtpImpl::UsbFnRequestCtrlComplete(uint8_t pipe, struct UsbFnRequest *req)
194 {
195     (void)pipe;
196     if (req == nullptr || req->context == nullptr) {
197         HDF_LOGE("%{public}s: invalid param", __func__);
198         return;
199     }
200     struct CtrlInfo *ctrlInfo = static_cast<struct CtrlInfo *>(req->context);
201     struct UsbMtpDevice *mtpDev = ctrlInfo->mtpDev;
202     if (mtpDev == nullptr) {
203         HDF_LOGE("%{public}s: invalid content", __func__);
204         return;
205     }
206     switch (req->status) {
207         case USB_REQUEST_COMPLETED:
208             break;
209         case USB_REQUEST_NO_DEVICE:
210             HDF_LOGV("%{public}s: usb mtpDev device was disconnected", __func__);
211             mtpDev->mtpState = MTP_STATE_OFFLINE;
212             break;
213         default:
214             HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
215             mtpDev->mtpState = MTP_STATE_ERROR;
216             break;
217     }
218     DListInsertTail(&req->list, &mtpDev->ctrlPool);
219 }
220 
UsbMtpPortTxReqCheck(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)221 int32_t UsbfnMtpImpl::UsbMtpPortTxReqCheck(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
222 {
223     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
224     switch (req->status) {
225         case USB_REQUEST_COMPLETED:
226             mtpDev->asyncSendFileActual += static_cast<uint64_t>(req->actual);
227             if (mtpDev->asyncSendFileActual == mtpDev->xferFileLength &&
228                 ((req->actual == 0 && mtpDev->needZLP == ZLP_TRY) || mtpDev->needZLP == ZLP_NO_NEED)) {
229                 HDF_LOGV("%{public}s: async tx done: req(%{public}d/%{public}d)%{public}u/%{public}u, send "
230                     "%{public}" PRIu64 "/%{public}" PRIu64 "/%{public}" PRIu64 ", ZLP=%{public}hhu", __func__,
231                     mtpPort->writeStarted, mtpPort->writeAllocated, req->actual, req->length,
232                     mtpDev->asyncSendFileExpect, mtpDev->asyncSendFileActual, mtpDev->xferFileLength, mtpDev->needZLP);
233                 sem_post(&asyncReq_);
234                 return HDF_SUCCESS;
235             }
236             return UsbMtpPortStartTxAsync(mtpPort, true);
237         case USB_REQUEST_NO_DEVICE:
238             HDF_LOGV("%{public}s: tx req return disconnected", __func__);
239             mtpPort->mtpDev->mtpState = MTP_STATE_OFFLINE;
240             sem_post(&asyncReq_);
241             return HDF_DEV_ERR_NO_DEVICE;
242         default:
243             HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
244             mtpPort->mtpDev->mtpState = MTP_STATE_ERROR;
245             sem_post(&asyncReq_);
246             return HDF_ERR_IO;
247     }
248     return HDF_SUCCESS;
249 }
250 
UsbMtpPortProcessLastTxPacket(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)251 int32_t UsbfnMtpImpl::UsbMtpPortProcessLastTxPacket(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
252 {
253     int32_t ret = HDF_SUCCESS;
254     if (mtpPort->mtpDev->needZLP == ZLP_NEED) {
255         mtpPort->mtpDev->needZLP = ZLP_TRY;
256         req->length = 0;
257         ret = UsbFnSubmitRequestAsync(req);
258         if (ret != HDF_SUCCESS) {
259             HDF_LOGE("%{public}s: submit bulk-in zlp req error: %{public}d", __func__, ret);
260             sem_post(&asyncReq_);
261         }
262         mtpPort->writeStarted++;
263     }
264     return ret;
265 }
266 
UsbMtpPortSubmitAsyncTxReq(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)267 int32_t UsbfnMtpImpl::UsbMtpPortSubmitAsyncTxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
268 {
269     ssize_t readRet = read(mtpPort->mtpDev->xferFd, req->buf, static_cast<size_t>(req->length));
270     if (readRet != static_cast<ssize_t>(req->length)) {
271         HDF_LOGE("%{public}s: read failed: %{public}zd < %{public}u", __func__, readRet, req->length);
272         return HDF_FAILURE;
273     }
274     DListRemove(&req->list);
275     DListInsertTail(&req->list, &mtpPort->writeQueue);
276     int32_t ret = UsbFnSubmitRequestAsync(req);
277     if (ret != HDF_SUCCESS) {
278         HDF_LOGE("%{public}s: submit bulk-in req error: %{public}d", __func__, ret);
279         DListRemove(&req->list);
280         DListInsertTail(&req->list, &mtpPort->writePool);
281         return ret;
282     }
283     mtpPort->writeStarted++;
284     return ret;
285 }
286 
UsbMtpPortStartTxAsync(struct UsbMtpPort * mtpPort,bool callByComplete)287 int32_t UsbfnMtpImpl::UsbMtpPortStartTxAsync(struct UsbMtpPort *mtpPort, bool callByComplete)
288 {
289     if (mtpPort == nullptr || mtpPort->mtpDev == nullptr) {
290         HDF_LOGE("%{public}s: invalid param", __func__);
291         return HDF_ERR_INVALID_PARAM;
292     }
293     std::lock_guard<std::mutex> guard(asyncMutex_);
294 
295     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
296     struct DListHead *pool = &mtpPort->writePool;
297     uint64_t reqMax = static_cast<uint64_t>(mtpDev->dataInPipe.maxPacketSize);
298     while (!DListIsEmpty(pool)) {
299         if (mtpDev->needZLP == ZLP_NO_NEED) {
300             if (mtpDev->asyncSendFileExpect >= mtpDev->xferFileLength) {
301                 return HDF_SUCCESS;
302             }
303         } else {
304             if (mtpDev->needZLP == ZLP_TRY) {
305                 return HDF_SUCCESS;
306             }
307         }
308         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
309         if (mtpDev->asyncSendFileExpect + reqMax < mtpDev->xferFileLength) {
310             req->length = static_cast<uint32_t>(mtpDev->dataInPipe.maxPacketSize);
311         } else {
312             req->length = static_cast<uint32_t>(mtpDev->xferFileLength - mtpDev->asyncSendFileExpect);
313         }
314         if (mtpDev->xferFileLength == mtpDev->asyncSendFileExpect) {
315             return UsbMtpPortProcessLastTxPacket(mtpPort, req);
316         }
317         int32_t ret = UsbMtpPortSubmitAsyncTxReq(mtpPort, req);
318         if (ret != HDF_SUCCESS) {
319             HDF_LOGE("%{public}s: submit bulk-in req error: %{public}d", __func__, ret);
320             sem_post(&asyncReq_);
321             return ret;
322         }
323         mtpDev->asyncSendFileExpect += static_cast<uint64_t>(req->length);
324     }
325     return HDF_SUCCESS;
326 }
327 
UsbMtpDeviceAllocCtrlRequests(int32_t num)328 int32_t UsbfnMtpImpl::UsbMtpDeviceAllocCtrlRequests(int32_t num)
329 {
330     struct DListHead *head = &mtpDev_->ctrlPool;
331     DListHeadInit(head);
332     mtpDev_->ctrlReqNum = 0;
333     for (int32_t i = 0; i < num; ++i) {
334         struct CtrlInfo *ctrlInfo = static_cast<struct CtrlInfo *>(OsalMemCalloc(sizeof(struct CtrlInfo)));
335         if (ctrlInfo == nullptr) {
336             HDF_LOGE("%{public}s: Allocate ctrlInfo failed", __func__);
337             return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
338         }
339         ctrlInfo->mtpDev = mtpDev_;
340         struct UsbFnRequest *req = UsbFnAllocCtrlRequest(mtpDev_->ctrlIface.handle, MTP_CONTROL_XFER_BYTECOUNT);
341         if (req == nullptr) {
342             HDF_LOGE("%{public}s: Allocate ctrl req failed", __func__);
343             (void)OsalMemFree(ctrlInfo);
344             return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
345         }
346         req->complete = UsbFnRequestCtrlComplete;
347         req->context = ctrlInfo;
348         DListInsertTail(&req->list, head);
349         mtpDev_->ctrlReqNum++;
350     }
351     return HDF_SUCCESS;
352 }
353 
UsbMtpDeviceFreeCtrlRequests()354 void UsbfnMtpImpl::UsbMtpDeviceFreeCtrlRequests()
355 {
356     struct DListHead *head = &mtpDev_->ctrlPool;
357     while (!DListIsEmpty(head)) {
358         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
359         DListRemove(&req->list);
360         (void)OsalMemFree(req->context);
361         (void)UsbFnFreeRequest(req);
362         mtpDev_->ctrlReqNum--;
363     }
364 }
365 
UsbMtpPortFreeRequests(struct DListHead * head,int32_t & allocated)366 void UsbfnMtpImpl::UsbMtpPortFreeRequests(struct DListHead *head, int32_t &allocated)
367 {
368     while (!DListIsEmpty(head)) {
369         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
370         DListRemove(&req->list);
371         (void)UsbFnFreeRequest(req);
372         allocated--;
373     }
374 }
375 
UsbMtpPortAllocReadWriteRequests(int32_t readSize,int32_t writeSize)376 int32_t UsbfnMtpImpl::UsbMtpPortAllocReadWriteRequests(int32_t readSize, int32_t writeSize)
377 {
378     struct UsbFnRequest *req = nullptr;
379     int32_t i = 0;
380     for (i = 0; i < readSize; ++i) {
381         req = UsbFnAllocRequest(mtpDev_->dataIface.handle, mtpDev_->dataOutPipe.id, mtpDev_->dataOutPipe.maxPacketSize);
382         if (req == nullptr) {
383             if (DListIsEmpty(&mtpPort_->readPool)) {
384                 HDF_LOGE("%{public}s: alloc read req failed", __func__);
385                 return HDF_ERR_MALLOC_FAIL;
386             }
387             break;
388         }
389         req->complete = UsbFnRequestReadComplete;
390         req->context = mtpPort_;
391         DListInsertTail(&req->list, &mtpPort_->readPool);
392         mtpPort_->readAllocated++;
393     }
394 
395     for (i = 0; i < writeSize; ++i) {
396         req = UsbFnAllocRequest(mtpDev_->dataIface.handle, mtpDev_->dataInPipe.id, mtpDev_->dataInPipe.maxPacketSize);
397         if (req == nullptr) {
398             HDF_LOGE("%{public}s: alloc write req failed", __func__);
399             return HDF_ERR_MALLOC_FAIL;
400         }
401         req->complete = UsbFnRequestWriteComplete;
402         req->context = mtpPort_;
403         DListInsertTail(&req->list, &mtpPort_->writePool);
404         mtpPort_->writeAllocated++;
405     }
406     return HDF_SUCCESS;
407 }
408 
UsbMtpPortInitIo()409 int32_t UsbfnMtpImpl::UsbMtpPortInitIo()
410 {
411     int32_t ret = HDF_SUCCESS;
412     if (mtpPort_->readAllocated == 0 || mtpPort_->writeAllocated == 0) {
413         HDF_LOGI("%{public}s: rx_req=%{public}d tx_req=%{public}d, alloc req", __func__, mtpPort_->readAllocated,
414             mtpPort_->writeAllocated);
415         ret = UsbMtpPortAllocReadWriteRequests(READ_QUEUE_SIZE, WRITE_QUEUE_SIZE);
416         if (ret != HDF_SUCCESS) {
417             HDF_LOGE("%{public}s: allocate requests for read/write failed: %{public}d", __func__, ret);
418             UsbMtpPortFreeRequests(&mtpPort_->readPool, mtpPort_->readAllocated);
419             UsbMtpPortFreeRequests(&mtpPort_->writePool, mtpPort_->writeAllocated);
420             return HDF_ERR_MALLOC_FAIL;
421         }
422     }
423     return ret;
424 }
425 
UsbMtpPortCancelAndFreeReq(struct DListHead * queueHead,struct DListHead * poolHead,int32_t & allocated,bool freeReq)426 int32_t UsbfnMtpImpl::UsbMtpPortCancelAndFreeReq(
427     struct DListHead *queueHead, struct DListHead *poolHead, int32_t &allocated, bool freeReq)
428 {
429     while (!DListIsEmpty(queueHead)) {
430         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(queueHead, struct UsbFnRequest, list);
431         DListRemove(&req->list);
432         DListInsertTail(&req->list, poolHead);
433     }
434     while (!DListIsEmpty(poolHead)) {
435         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(poolHead, struct UsbFnRequest, list);
436         DListRemove(&req->list);
437         (void)UsbFnCancelRequest(req);
438         if (freeReq) {
439             (void)UsbFnFreeRequest(req);
440         }
441         allocated--;
442     }
443     return HDF_SUCCESS;
444 }
445 
UsbMtpPortCancelPlusFreeIo(struct UsbMtpPort * mtpPort,bool freeReq)446 int32_t UsbfnMtpImpl::UsbMtpPortCancelPlusFreeIo(struct UsbMtpPort *mtpPort, bool freeReq)
447 {
448     HDF_LOGI("%{public}s: cancel and free read req: %{public}d/%{public}d", __func__, mtpPort->readStarted,
449         mtpPort->readAllocated);
450     (void)UsbMtpPortCancelAndFreeReq(&mtpPort->readQueue, &mtpPort->readPool, mtpPort->readAllocated, freeReq);
451     HDF_LOGI("%{public}s: cancel and free write req: %{public}d/%{public}d", __func__, mtpPort->writeStarted,
452         mtpPort->writeAllocated);
453     (void)UsbMtpPortCancelAndFreeReq(&mtpPort->writeQueue, &mtpPort->writePool, mtpPort->writeAllocated, freeReq);
454     return HDF_SUCCESS;
455 }
456 
UsbMtpPortReleaseIo()457 int32_t UsbfnMtpImpl::UsbMtpPortReleaseIo()
458 {
459     return UsbMtpPortCancelPlusFreeIo(mtpPort_, true);
460 }
461 
UsbMtpDeviceGetCtrlReq(struct UsbMtpDevice * mtpDev)462 struct UsbFnRequest *UsbfnMtpImpl::UsbMtpDeviceGetCtrlReq(struct UsbMtpDevice *mtpDev)
463 {
464     struct DListHead *pool = &mtpDev->ctrlPool;
465     if (DListIsEmpty(pool)) {
466         return nullptr;
467     }
468     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
469     DListRemove(&req->list);
470     return req;
471 }
472 
UsbMtpDeviceStandardRequest(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup,struct UsbFnRequest * req)473 int32_t UsbfnMtpImpl::UsbMtpDeviceStandardRequest(
474     struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req)
475 {
476     uint16_t wValue = LE16_TO_CPU(setup->value);
477     int32_t responseBytes = 0;
478     uint8_t mtpOsStringReqType = (USB_DDK_DIR_IN | USB_DDK_TYPE_STANDARD | USB_DDK_RECIP_DEVICE);
479     /* wValue specified descriptor type(high 8 bit) and index(low 8 bit) when request is GET_DESCRIPTOR */
480     uint16_t mtpOsStringWValue = (USB_DDK_DT_STRING << 8 | USB_MTP_OS_STRING_ID);
481     if (setup->request == USB_DDK_REQ_GET_DESCRIPTOR && setup->reqType == mtpOsStringReqType &&
482         wValue == mtpOsStringWValue) {
483         /* Handle MTP OS string */
484         HDF_LOGI("%{public}s: Standard Request-Get Descriptor(String)", __func__);
485         responseBytes = (wValue < sizeof(g_mtpOsString)) ? wValue : sizeof(g_mtpOsString);
486         if (memcpy_s(req->buf, responseBytes, g_mtpOsString, responseBytes) != EOK) {
487             HDF_LOGE("%{public}s: memcpy_s failed: Get Descriptor", __func__);
488             return HDF_FAILURE;
489         }
490     } else {
491         HDF_LOGW("%{public}s: Standard Request-unknown: %{public}d", __func__, setup->request);
492     }
493     return responseBytes;
494 }
495 
UsbMtpDeviceClassRequest(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup,struct UsbFnRequest * req)496 int32_t UsbfnMtpImpl::UsbMtpDeviceClassRequest(
497     struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req)
498 {
499     int32_t responseBytes = 0;
500     if (setup->request == USB_MTP_REQ_CANCEL && setup->index == 0 && setup->value == 0) {
501         HDF_LOGI("%{public}s: Class Request-MTP_REQ_CANCEL", __func__);
502         if (mtpDev->mtpState == MTP_STATE_BUSY) {
503             mtpDev->mtpState = MTP_STATE_CANCELED;
504             (void)UsbMtpPortCancelPlusFreeIo(mtpDev->mtpPort, false);
505         }
506     } else if (setup->request == USB_MTP_REQ_GET_DEVICE_STATUS && setup->index == 0 && setup->value == 0) {
507         HDF_LOGI("%{public}s: Class Request-MTP_REQ_GET_DEVICE_STATUS", __func__);
508         struct UsbMtpDeviceStatus mtpStatus;
509         mtpStatus.wLength = CPU_TO_LE16(sizeof(mtpStatus));
510         if (mtpDev->mtpState == MTP_STATE_CANCELED) {
511             mtpStatus.wCode = CPU_TO_LE16(MTP_RESPONSE_DEVICE_BUSY);
512         } else {
513             mtpStatus.wCode = CPU_TO_LE16(MTP_RESPONSE_OK);
514         }
515         responseBytes = static_cast<int32_t>(sizeof(mtpStatus));
516         if (memcpy_s(req->buf, responseBytes, &mtpStatus, responseBytes) != EOK) {
517             HDF_LOGE("%{public}s: memcpy_s failed: MTP_REQ_GET_DEVICE_STATUS", __func__);
518             return HDF_FAILURE;
519         }
520     } else {
521         HDF_LOGW("%{public}s: Class Request-UNKNOWN: %{public}d", __func__, setup->request);
522     }
523     return responseBytes;
524 }
525 
UsbMtpDeviceVendorRequest(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup,struct UsbFnRequest * req)526 int32_t UsbfnMtpImpl::UsbMtpDeviceVendorRequest(
527     struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req)
528 {
529     uint16_t wIndex = LE16_TO_CPU(setup->index);
530     uint16_t wLength = LE16_TO_CPU(setup->length);
531     int32_t responseBytes = 0;
532     if (setup->request == USB_MTP_BMS_VENDORCODE && (setup->reqType & USB_DDK_DIR_IN) &&
533         (wIndex == USB_MTP_EXTENDED_COMPAT_ID || wIndex == USB_MTP_EXTENDED_PROPERTIES)) {
534         /* Handle MTP OS descriptor */
535         HDF_LOGI("%{public}s: Vendor Request-Get Descriptor(MTP OS)", __func__);
536         responseBytes = (wLength < sizeof(g_mtpExtConfigDesc)) ? wLength : sizeof(g_mtpExtConfigDesc);
537         if (memcpy_s(req->buf, responseBytes, &g_mtpExtConfigDesc, responseBytes) != EOK) {
538             HDF_LOGE("%{public}s: memcpy_s failed: Get Descriptor(MTP OS)", __func__);
539             return HDF_FAILURE;
540         }
541     } else {
542         HDF_LOGW("%{public}s: Vendor Request-UNKNOWN: %{public}d", __func__, setup->request);
543     }
544     return responseBytes;
545 }
546 
UsbMtpDeviceSetup(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup)547 int32_t UsbfnMtpImpl::UsbMtpDeviceSetup(struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup)
548 {
549     if (mtpDev == nullptr || mtpDev->mtpPort == nullptr || setup == nullptr) {
550         return HDF_ERR_INVALID_PARAM;
551     }
552     HDF_LOGV(
553         "%{public}s: Setup: reqType=0x%{public}X, req=0x%{public}X, idx=%{public}d, val=%{public}d, len=%{public}d",
554         __func__, setup->reqType, setup->request, LE16_TO_CPU(setup->index), LE16_TO_CPU(setup->value),
555         LE16_TO_CPU(setup->length));
556 
557     struct UsbFnRequest *req = UsbMtpDeviceGetCtrlReq(mtpDev);
558     if (req == nullptr) {
559         HDF_LOGE("%{public}s: control req pool is empty", __func__);
560         return HDF_ERR_INVALID_PARAM;
561     }
562     int32_t responseBytes = 0;
563     switch (setup->reqType & USB_DDK_TYPE_MASK) {
564         case USB_DDK_TYPE_STANDARD:
565             responseBytes = UsbMtpDeviceStandardRequest(mtpDev, setup, req);
566             break;
567         case USB_DDK_TYPE_CLASS:
568             responseBytes = UsbMtpDeviceClassRequest(mtpDev, setup, req);
569             break;
570         case USB_DDK_TYPE_VENDOR:
571             responseBytes = UsbMtpDeviceVendorRequest(mtpDev, setup, req);
572             break;
573         default:
574             HDF_LOGW("%{public}s: Reserved Request: %{public}d", __func__, (setup->reqType & USB_DDK_TYPE_MASK));
575             break;
576     }
577 
578     struct CtrlInfo *ctrlInfo = static_cast<struct CtrlInfo *>(req->context);
579     ctrlInfo->request = setup->request;
580     ctrlInfo->mtpDev = mtpDev;
581     if (responseBytes >= 0) {
582         req->length = static_cast<uint32_t>(responseBytes);
583         int32_t ret = UsbFnSubmitRequestAsync(req);
584         if (ret != HDF_SUCCESS) {
585             HDF_LOGE("%{public}s: mtpDev send setup response error", __func__);
586             return ret;
587         }
588     }
589     return HDF_SUCCESS;
590 }
591 
UsbMtpDeviceSuspend(struct UsbMtpDevice * mtpDev)592 void UsbfnMtpImpl::UsbMtpDeviceSuspend(struct UsbMtpDevice *mtpDev)
593 {
594     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
595     if (mtpPort == nullptr) {
596         HDF_LOGE("%{public}s: invalid param", __func__);
597         return;
598     }
599 
600     mtpPort->suspended = true;
601     (void)UsbMtpPortCancelPlusFreeIo(mtpPort, false);
602 }
603 
UsbMtpDeviceResume(struct UsbMtpDevice * mtpDev)604 void UsbfnMtpImpl::UsbMtpDeviceResume(struct UsbMtpDevice *mtpDev)
605 {
606     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
607     if (mtpPort == nullptr) {
608         HDF_LOGE("%{public}s: invalid param", __func__);
609         return;
610     }
611     mtpPort->suspended = false;
612     if (!mtpPort->startDelayed) {
613         return;
614     }
615     mtpPort->startDelayed = false;
616 }
617 
UsbMtpDeviceEnable(struct UsbMtpDevice * mtpDev)618 int32_t UsbfnMtpImpl::UsbMtpDeviceEnable(struct UsbMtpDevice *mtpDev)
619 {
620     if (mtpDev == nullptr || mtpDev->initFlag == false) {
621         HDF_LOGE("%{public}s: no init", __func__);
622         return HDF_DEV_ERR_DEV_INIT_FAIL;
623     }
624     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
625     if (mtpPort == nullptr) {
626         HDF_LOGE("%{public}s: no init", __func__);
627         return HDF_DEV_ERR_DEV_INIT_FAIL;
628     }
629 
630     /* the mtpDev is enabled, ready for transfer */
631     mtpDev->mtpState = MTP_STATE_READY;
632     mtpPort->startDelayed = true;
633     return HDF_SUCCESS;
634 }
635 
UsbMtpDeviceDisable(struct UsbMtpDevice * mtpDev)636 int32_t UsbfnMtpImpl::UsbMtpDeviceDisable(struct UsbMtpDevice *mtpDev)
637 {
638     if (mtpDev == nullptr || mtpDev->initFlag == false) {
639         HDF_LOGE("%{public}s: no init", __func__);
640         return HDF_DEV_ERR_DEV_INIT_FAIL;
641     }
642     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
643     if (mtpPort == nullptr) {
644         HDF_LOGE("%{public}s: no init", __func__);
645         return HDF_DEV_ERR_DEV_INIT_FAIL;
646     }
647 
648     /* Disable event: The USB Device Controller has been disabled due to some problem */
649     mtpPort->startDelayed = false;
650     mtpDev->mtpState = MTP_STATE_OFFLINE;
651     return HDF_SUCCESS;
652 }
653 
UsbMtpDeviceEp0EventDispatch(struct UsbFnEvent * event)654 void UsbfnMtpImpl::UsbMtpDeviceEp0EventDispatch(struct UsbFnEvent *event)
655 {
656     if (event == nullptr || event->context == nullptr) {
657         HDF_LOGE("%{public}s: invalid param event", __func__);
658         return;
659     }
660 
661     struct UsbMtpDevice *mtpDev = static_cast<struct UsbMtpDevice *>(event->context);
662     HDF_LOGI("%{public}s EP0 event: [%{public}d], state=%{public}hhu", __func__, event->type, mtpDev->mtpState);
663     switch (event->type) {
664         case USBFN_STATE_BIND:
665             HDF_LOGI("%{public}s: EP0 [bind] ignore", __func__);
666             break;
667         case USBFN_STATE_UNBIND:
668             HDF_LOGI("%{public}s: EP0 [unbind] ignore", __func__);
669             break;
670         case USBFN_STATE_ENABLE:
671             HDF_LOGI("%{public}s: EP0 [enable]", __func__);
672             (void)UsbMtpDeviceEnable(mtpDev);
673             break;
674         case USBFN_STATE_DISABLE:
675             HDF_LOGI("%{public}s: EP0 [disable]", __func__);
676             (void)UsbMtpDeviceDisable(mtpDev);
677             break;
678         case USBFN_STATE_SETUP:
679             HDF_LOGI("%{public}s: EP0 [setup]", __func__);
680             if (event->setup != nullptr) {
681                 (void)UsbMtpDeviceSetup(mtpDev, event->setup);
682             }
683             break;
684         case USBFN_STATE_SUSPEND:
685             HDF_LOGI("%{public}s: EP0 [suspend]", __func__);
686             UsbMtpDeviceSuspend(mtpDev);
687             break;
688         case USBFN_STATE_RESUME:
689             HDF_LOGI("%{public}s: EP0 [resume]", __func__);
690             UsbMtpDeviceResume(mtpDev);
691             break;
692         default:
693             HDF_LOGI("%{public}s: EP0 ignore or unknown: %{public}d", __func__, event->type);
694             break;
695     }
696 }
697 
UsbMtpDeviceParseEachPipe(struct UsbMtpInterface & iface)698 int32_t UsbfnMtpImpl::UsbMtpDeviceParseEachPipe(struct UsbMtpInterface &iface)
699 {
700     struct UsbFnInterface *fnIface = iface.fn;
701     if (fnIface == nullptr || fnIface->info.numPipes == 0) {
702         HDF_LOGE("%{public}s: ifce is invalid", __func__);
703         return HDF_ERR_INVALID_PARAM;
704     }
705     HDF_LOGI("%{public}s: interface: idx=%{public}hhu numPipes=%{public}hhu ifClass=%{public}hhu subclass=%{public}hhu "
706         "protocol=%{public}hhu cfgIndex=%{public}hhu", __func__, fnIface->info.index, fnIface->info.numPipes,
707         fnIface->info.interfaceClass, fnIface->info.subclass, fnIface->info.protocol, fnIface->info.configIndex);
708     uint32_t repetIdx = 0;
709     for (int32_t i = 0; i < fnIface->info.numPipes; ++i) {
710         struct UsbFnPipeInfo pipeInfo;
711         (void)memset_s(&pipeInfo, sizeof(pipeInfo), 0, sizeof(pipeInfo));
712         int32_t ret = UsbFnGetInterfacePipeInfo(fnIface, static_cast<uint8_t>(i), &pipeInfo);
713         if (ret != HDF_SUCCESS) {
714             HDF_LOGE("%{public}s: get pipe info error", __func__);
715             return ret;
716         }
717         HDF_LOGI("%{public}s: pipe: id=%{public}d type=%{public}d dir=%{public}d max=%{public}d interval=%{public}d",
718             __func__, pipeInfo.id, pipeInfo.type, pipeInfo.dir, pipeInfo.maxPacketSize, pipeInfo.interval);
719         switch (pipeInfo.type) {
720             case USB_PIPE_TYPE_INTERRUPT:
721                 mtpDev_->notifyPipe.id = pipeInfo.id;
722                 mtpDev_->notifyPipe.maxPacketSize = pipeInfo.maxPacketSize;
723                 mtpDev_->ctrlIface = iface; /* MTP device only have one interface, record here */
724                 mtpDev_->intrIface = iface;
725                 break;
726             case USB_PIPE_TYPE_BULK:
727                 if (pipeInfo.dir == USB_PIPE_DIRECTION_IN) {
728                     mtpDev_->dataInPipe.id = pipeInfo.id;
729                     mtpDev_->dataInPipe.maxPacketSize = pipeInfo.maxPacketSize;
730                     mtpDev_->dataIface = iface;
731                 } else {
732                     mtpDev_->dataOutPipe.id = pipeInfo.id;
733                     mtpDev_->dataOutPipe.maxPacketSize = pipeInfo.maxPacketSize;
734                 }
735                 break;
736             default:
737                 if (repetIdx < WAIT_UDC_MAX_LOOP) {
738                     usleep(WAIT_UDC_TIME);
739                     i--;
740                 }
741                 repetIdx++;
742                 HDF_LOGE("%{public}s: pipe type %{public}d don't support", __func__, pipeInfo.type);
743                 break;
744         }
745     }
746     return HDF_SUCCESS;
747 }
748 
UsbMtpDeviceParseMtpIface(struct UsbFnInterface * fnIface)749 int32_t UsbfnMtpImpl::UsbMtpDeviceParseMtpIface(struct UsbFnInterface *fnIface)
750 {
751     UsbFnInterfaceHandle handle = UsbFnOpenInterface(fnIface);
752     if (handle == nullptr) {
753         HDF_LOGE("%{public}s: open interface failed", __func__);
754         return HDF_ERR_INVALID_PARAM;
755     }
756     struct UsbMtpInterface iface;
757     iface.fn = fnIface;
758     iface.handle = handle;
759     int32_t ret = UsbMtpDeviceParseEachPipe(iface);
760     if (ret != HDF_SUCCESS) {
761         HDF_LOGE("%{public}s: parse each pipe failed", __func__);
762     }
763     return ret;
764 }
765 
UsbFnInterfaceIsUsbMtpPtpDevice(struct UsbFnInterface * iface)766 bool UsbfnMtpImpl::UsbFnInterfaceIsUsbMtpPtpDevice(struct UsbFnInterface *iface)
767 {
768     HDF_LOGI("%{public}s: iIf=%{public}d ifClass=%{public}d, subclass=%{public}d, protocol=%{public}d", __func__,
769         iface->info.configIndex, iface->info.interfaceClass, iface->info.subclass, iface->info.protocol);
770     if (iface->info.interfaceClass == USB_MTP_DEVICE_CLASS && iface->info.subclass == USB_MTP_DEVICE_SUBCLASS &&
771         iface->info.protocol == USB_MTP_DEVICE_PROTOCOL) {
772         HDF_LOGI("%{public}s: this is mtp device", __func__);
773         return true;
774     }
775     if (iface->info.interfaceClass == USB_PTP_DEVICE_CLASS && iface->info.subclass == USB_PTP_DEVICE_SUBCLASS &&
776         iface->info.protocol == USB_PTP_DEVICE_PROTOCOL) {
777         HDF_LOGI("%{public}s: this is ptp device", __func__);
778         return true;
779     }
780     return false;
781 }
782 
UsbMtpDeviceParseEachIface(struct UsbFnDevice * fnDev)783 int32_t UsbfnMtpImpl::UsbMtpDeviceParseEachIface(struct UsbFnDevice *fnDev)
784 {
785     for (int32_t i = 0; i < fnDev->numInterfaces; ++i) {
786         struct UsbFnInterface *fnIface = const_cast<struct UsbFnInterface *>(UsbFnGetInterface(fnDev, i));
787         if (fnIface == nullptr) {
788             HDF_LOGE("%{public}s: get interface failed: %{public}d/%{public}d", __func__, i, fnDev->numInterfaces);
789             return HDF_ERR_INVALID_PARAM;
790         }
791         if (UsbFnInterfaceIsUsbMtpPtpDevice(fnIface)) {
792             /* MTP/PTP device only have one interface, only parse once */
793             HDF_LOGI("%{public}s: found mtp/ptp interface: %{public}d/%{public}d", __func__, i, fnDev->numInterfaces);
794             (void)UsbMtpDeviceParseMtpIface(fnIface);
795             return HDF_SUCCESS;
796         }
797     }
798     return HDF_FAILURE;
799 }
800 
UsbMtpDeviceCreateFuncDevice()801 int32_t UsbfnMtpImpl::UsbMtpDeviceCreateFuncDevice()
802 {
803     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
804     if (iface == NULL) {
805         HDF_LOGE("%{public}s: DeviceResourceGetIfaceInstance failed", __func__);
806         return HDF_FAILURE;
807     }
808     const char *udcName = nullptr;
809     if (deviceObject_ != nullptr) {
810         if (iface->GetString(deviceObject_->property, "udc_name", &udcName, UDC_NAME) != HDF_SUCCESS) {
811             HDF_LOGE("%{public}s: read udc_name failed, use default: %{public}s", __func__, UDC_NAME);
812             return HDF_ERR_INVALID_PARAM;
813         }
814     }
815     struct UsbFnDevice *fnDev = nullptr;
816     if (udcName != nullptr) {
817         fnDev = const_cast<struct UsbFnDevice *>(UsbFnGetDevice(udcName));
818     } else {
819         HDF_LOGW("%{public}s: udcName invalid, use default", __func__);
820         fnDev = const_cast<struct UsbFnDevice *>(UsbFnGetDevice(UDC_NAME));
821     }
822     if (fnDev == NULL) {
823         HDF_LOGE("%{public}s: create usb function device failed", __func__);
824         return HDF_DEV_ERR_DEV_INIT_FAIL;
825     }
826     HDF_LOGI("%{public}s: getDevice interface count=%{public}d", __func__, fnDev->numInterfaces);
827     int32_t ret = UsbMtpDeviceParseEachIface(fnDev);
828     if (ret != HDF_SUCCESS) {
829         HDF_LOGE("%{public}s: get pipes failed", __func__);
830         return ret;
831     }
832     mtpDev_->fnDev = fnDev;
833     return HDF_SUCCESS;
834 }
835 
UsbMtpDeviceReleaseFuncDevice()836 int32_t UsbfnMtpImpl::UsbMtpDeviceReleaseFuncDevice()
837 {
838     if (mtpDev_->fnDev == nullptr) {
839         HDF_LOGE("%{public}s: fnDev is null", __func__);
840         return HDF_ERR_INVALID_PARAM;
841     }
842     (void)UsbMtpDeviceFreeCtrlRequests();
843     (void)UsbMtpDeviceFreeNotifyRequest();
844     int32_t finalRet = HDF_SUCCESS;
845     /* mtp/ptp have one interface include bulk/intr, ctrl is default, release once */
846     int32_t ret = UsbFnCloseInterface(mtpDev_->ctrlIface.handle);
847     if (ret != HDF_SUCCESS) {
848         finalRet = ret;
849         HDF_LOGW("%{public}s: close usb ctrl/bulk/intr interface failed", __func__);
850     }
851     ret = UsbFnStopRecvInterfaceEvent(mtpDev_->ctrlIface.fn);
852     if (ret != HDF_SUCCESS) {
853         finalRet = ret;
854         HDF_LOGW("%{public}s: stop usb ep0 event handle failed", __func__);
855     }
856     return finalRet;
857 }
858 
UsbMtpDeviceAlloc()859 int32_t UsbfnMtpImpl::UsbMtpDeviceAlloc()
860 {
861     struct UsbMtpPort *mtpPort = static_cast<struct UsbMtpPort *>(OsalMemCalloc(sizeof(struct UsbMtpPort)));
862     if (mtpPort == nullptr) {
863         HDF_LOGE("%{public}s: Alloc usb mtpDev mtpPort failed", __func__);
864         return HDF_ERR_INVALID_PARAM;
865     }
866     DListHeadInit(&mtpPort->readPool);
867     DListHeadInit(&mtpPort->readQueue);
868     DListHeadInit(&mtpPort->writePool);
869     DListHeadInit(&mtpPort->writeQueue);
870     mtpDev_->mtpPort = mtpPort;
871     mtpPort->mtpDev = mtpDev_;
872     mtpPort_ = mtpPort;
873     return HDF_SUCCESS;
874 }
875 
UsbMtpDeviceAllocNotifyRequest()876 int32_t UsbfnMtpImpl::UsbMtpDeviceAllocNotifyRequest()
877 {
878     mtpDev_->notifyReq =
879         UsbFnAllocRequest(mtpDev_->intrIface.handle, mtpDev_->notifyPipe.id, MTP_EVENT_PACKET_MAX_BYTES);
880     if (mtpDev_->notifyReq == nullptr) {
881         HDF_LOGE("%{public}s: allocate notify request failed", __func__);
882         return HDF_ERR_INVALID_PARAM;
883     }
884     mtpDev_->notifyReq->complete = UsbFnRequestNotifyComplete;
885     mtpDev_->notifyReq->context = mtpDev_;
886     return HDF_SUCCESS;
887 }
888 
UsbMtpDeviceFreeNotifyRequest()889 void UsbfnMtpImpl::UsbMtpDeviceFreeNotifyRequest()
890 {
891     int32_t ret = UsbFnFreeRequest(mtpDev_->notifyReq);
892     if (ret != HDF_SUCCESS) {
893         HDF_LOGE("%{public}s: free notify request failed", __func__);
894         return;
895     }
896     mtpDev_->notifyReq = nullptr;
897 }
898 
UsbMtpDeviceFree()899 int32_t UsbfnMtpImpl::UsbMtpDeviceFree()
900 {
901     if (mtpDev_->mtpPort == nullptr) {
902         HDF_LOGE("%{public}s: invalid param", __func__);
903         return HDF_ERR_INVALID_PARAM;
904     }
905     (void)OsalMemFree(mtpDev_->mtpPort);
906     mtpDev_->mtpPort = nullptr;
907     return HDF_SUCCESS;
908 }
909 
Init()910 int32_t UsbfnMtpImpl::Init()
911 {
912     HDF_LOGI("%{public}s: Init", __func__);
913     mtpDev_ = static_cast<struct UsbMtpDevice *>(OsalMemCalloc(sizeof(struct UsbMtpDevice)));
914     if (mtpDev_ == nullptr) {
915         HDF_LOGE("%{public}s: Alloc usb mtpDev device failed", __func__);
916         return HDF_ERR_MALLOC_FAIL;
917     }
918     if (mtpDev_->initFlag) {
919         HDF_LOGE("%{public}s: usb mtpDev is already initialized", __func__);
920         return HDF_FAILURE;
921     }
922     int32_t ret = UsbfnMtpImpl::UsbMtpDeviceCreateFuncDevice();
923     if (ret != HDF_SUCCESS) {
924         HDF_LOGE("%{public}s: UsbMtpDeviceCreateFuncDevice failed", __func__);
925         (void)OsalMemFree(mtpDev_);
926         mtpDev_ = nullptr;
927         return ret;
928     }
929     /* init mtpPort */
930     ret = UsbMtpDeviceAlloc();
931     if (ret != HDF_SUCCESS) {
932         HDF_LOGE("%{public}s: UsbMtpDeviceAlloc failed", __func__);
933         goto ERR;
934     }
935     ret = UsbMtpDeviceAllocCtrlRequests(MTP_CTRL_REQUEST_NUM);
936     if (ret != HDF_SUCCESS) {
937         HDF_LOGE("%{public}s: UsbMtpDeviceAllocCtrlRequests failed: %{public}d", __func__, MTP_CTRL_REQUEST_NUM);
938         goto ERR;
939     }
940     ret = UsbMtpDeviceAllocNotifyRequest();
941     if (ret != HDF_SUCCESS) {
942         HDF_LOGE("%{public}s: UsbMtpDeviceAllocNotifyRequest failed", __func__);
943         goto ERR;
944     }
945     ret = UsbFnStartRecvInterfaceEvent(mtpDev_->ctrlIface.fn, 0xff, UsbMtpDeviceEp0EventDispatch, mtpDev_);
946     if (ret != HDF_SUCCESS) {
947         HDF_LOGE("%{public}s: register event callback failed", __func__);
948         goto ERR;
949     }
950     mtpDev_->initFlag = true;
951     HDF_LOGI("%{public}s: Init success", __func__);
952     return HDF_SUCCESS;
953 ERR:
954     (void)UsbMtpDeviceReleaseFuncDevice();
955     (void)UsbMtpDeviceFree();
956     (void)OsalMemFree(mtpDev_);
957     mtpDev_ = nullptr;
958     return ret;
959 }
960 
Release()961 int32_t UsbfnMtpImpl::Release()
962 {
963     HDF_LOGI("%{public}s: Release", __func__);
964     if (mtpPort_ == nullptr || mtpDev_ == nullptr) {
965         HDF_LOGE("%{public}s: no init", __func__);
966         return HDF_DEV_ERR_DEV_INIT_FAIL;
967     }
968     int32_t ret = UsbMtpDeviceReleaseFuncDevice();
969     if (ret != HDF_SUCCESS) {
970         HDF_LOGE("%{public}s: release device failed: %{public}d", __func__, ret);
971         return ret;
972     }
973     ret = UsbMtpDeviceFree();
974     if (ret != HDF_SUCCESS) {
975         HDF_LOGE("%{public}s: free device failed: %{public}d", __func__, ret);
976         return ret;
977     }
978     (void)OsalMemFree(mtpDev_);
979     mtpDev_ = nullptr;
980     HDF_LOGI("%{public}s: Release success", __func__);
981     return HDF_SUCCESS;
982 }
983 
Start()984 int32_t UsbfnMtpImpl::Start()
985 {
986     if (mtpPort_ == nullptr || mtpDev_ == nullptr || mtpDev_->initFlag == false) {
987         HDF_LOGE("%{public}s: no init", __func__);
988         return HDF_DEV_ERR_DEV_INIT_FAIL;
989     }
990     std::lock_guard<std::mutex> guard(mtpRunning_);
991 
992     mtpDev_->mtpState = MTP_STATE_READY;
993     mtpPort_->startDelayed = true;
994     return UsbMtpPortInitIo();
995 }
996 
Stop()997 int32_t UsbfnMtpImpl::Stop()
998 {
999     if (mtpPort_ == nullptr || mtpDev_ == nullptr || mtpDev_->initFlag == false) {
1000         HDF_LOGE("%{public}s: no init", __func__);
1001         return HDF_DEV_ERR_DEV_INIT_FAIL;
1002     }
1003     std::lock_guard<std::mutex> guard(mtpRunning_);
1004 
1005     (void)UsbMtpPortReleaseIo();
1006     mtpPort_->startDelayed = false;
1007     mtpDev_->mtpState = MTP_STATE_OFFLINE;
1008     return HDF_SUCCESS;
1009 }
1010 
BufCopyToVector(void * buf,uint32_t bufSize,std::vector<uint8_t> & vectorData)1011 uint32_t UsbfnMtpImpl::BufCopyToVector(void *buf, uint32_t bufSize, std::vector<uint8_t> &vectorData)
1012 {
1013     uint8_t *addr = static_cast<uint8_t *>(buf);
1014     vectorData.assign(addr, addr + bufSize);
1015     return bufSize;
1016 }
1017 
BufCopyFromVector(void * buf,uint32_t bufSize,const std::vector<uint8_t> & vectorData,uint32_t vectorOffset)1018 uint32_t UsbfnMtpImpl::BufCopyFromVector(
1019     void *buf, uint32_t bufSize, const std::vector<uint8_t> &vectorData, uint32_t vectorOffset)
1020 {
1021     uint32_t count = (bufSize + vectorOffset) < vectorData.size() ? bufSize : vectorData.size() - vectorOffset;
1022     uint8_t *addr = static_cast<uint8_t *>(buf);
1023     for (size_t i = 0; i < count; i++) {
1024         addr[i] = vectorData.at(vectorOffset + i);
1025     }
1026     return count;
1027 }
1028 
Read(std::vector<uint8_t> & data)1029 int32_t UsbfnMtpImpl::Read(std::vector<uint8_t> &data)
1030 {
1031     if (mtpPort_ == nullptr || mtpDev_ == nullptr || mtpDev_->initFlag == false) {
1032         HDF_LOGE("%{public}s: no init", __func__);
1033         return HDF_DEV_ERR_DEV_INIT_FAIL;
1034     }
1035     std::lock_guard<std::mutex> guard(mtpRunning_);
1036 
1037     if (mtpDev_->mtpState == MTP_STATE_OFFLINE) {
1038         HDF_LOGE("%{public}s: device disconnect, no-operation", __func__);
1039         return HDF_DEV_ERR_NO_DEVICE;
1040     }
1041     struct DListHead *pool = &mtpPort_->readPool;
1042     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1043     if (req == nullptr) {
1044         HDF_LOGE("%{public}s: req invalid", __func__);
1045         return HDF_DEV_ERR_DEV_INIT_FAIL;
1046     }
1047     DListRemove(&req->list);
1048     req->length = static_cast<uint32_t>(mtpDev_->dataOutPipe.maxPacketSize);
1049     int32_t ret = UsbFnSubmitRequestSync(req, BULK_OUT_TIMEOUT_JIFFIES);
1050     DListInsertTail(&req->list, pool);
1051     if (ret != HDF_SUCCESS) {
1052         HDF_LOGE("%{public}s: send bulk-out sync req failed: %{public}d", __func__, ret);
1053         return ret;
1054     }
1055     switch (req->status) {
1056         case USB_REQUEST_COMPLETED:
1057             (void)BufCopyToVector(req->buf, req->actual, data);
1058             break;
1059         case USB_REQUEST_NO_DEVICE:
1060             HDF_LOGE("%{public}s: device disconnect", __func__);
1061             mtpDev_->mtpState = MTP_STATE_OFFLINE;
1062             return HDF_DEV_ERR_NO_DEVICE;
1063         default:
1064             HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
1065             mtpDev_->mtpState = MTP_STATE_ERROR;
1066             return HDF_ERR_IO;
1067     }
1068     return ret;
1069 }
1070 
WriteEx(const std::vector<uint8_t> & data,uint8_t needZLP,uint32_t & xferActual)1071 int32_t UsbfnMtpImpl::WriteEx(const std::vector<uint8_t> &data, uint8_t needZLP, uint32_t &xferActual)
1072 {
1073     uint32_t needXferCount = data.size();
1074     int32_t ret = HDF_SUCCESS;
1075     while (needXferCount > 0 || needZLP == ZLP_NEED) {
1076         struct DListHead *pool = &mtpPort_->writePool;
1077         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1078         if (req == nullptr) {
1079             HDF_LOGE("%{public}s: req invalid", __func__);
1080             return HDF_DEV_ERR_DEV_INIT_FAIL;
1081         }
1082         DListRemove(&req->list);
1083         uint32_t reqMax = static_cast<uint32_t>(mtpDev_->dataInPipe.maxPacketSize);
1084         req->length = reqMax > needXferCount ? needXferCount : reqMax;
1085         if (needXferCount == 0) {
1086             needZLP = ZLP_TRY;
1087             req->length = 0;
1088         }
1089         (void)BufCopyFromVector(req->buf, req->length, data, xferActual);
1090         ret = UsbFnSubmitRequestSync(req, BULK_IN_TIMEOUT_JIFFIES);
1091         DListInsertTail(&req->list, pool);
1092         if (needZLP == ZLP_TRY) {
1093             HDF_LOGV("%{public}s: send zero packet done: %{public}d", __func__, ret);
1094             return ret;
1095         }
1096         if (ret != HDF_SUCCESS) {
1097             HDF_LOGE("%{public}s: bulk-in req failed: %{public}d", __func__, ret);
1098             break;
1099         }
1100         switch (req->status) {
1101             case USB_REQUEST_COMPLETED:
1102                 needXferCount -= req->actual;
1103                 xferActual += req->actual;
1104                 break;
1105             case USB_REQUEST_NO_DEVICE:
1106                 HDF_LOGV("%{public}s: device disconnected", __func__);
1107                 mtpDev_->mtpState = MTP_STATE_OFFLINE;
1108                 return HDF_DEV_ERR_NO_DEVICE;
1109             default:
1110                 HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
1111                 mtpDev_->mtpState = MTP_STATE_ERROR;
1112                 return HDF_ERR_IO;
1113         }
1114     }
1115     return ret;
1116 }
1117 
Write(const std::vector<uint8_t> & data)1118 int32_t UsbfnMtpImpl::Write(const std::vector<uint8_t> &data)
1119 {
1120     if (mtpPort_ == nullptr || mtpDev_ == nullptr || mtpDev_->initFlag == false) {
1121         HDF_LOGE("%{public}s: no init", __func__);
1122         return HDF_DEV_ERR_DEV_INIT_FAIL;
1123     }
1124     std::lock_guard<std::mutex> guard(mtpRunning_);
1125 
1126     if (mtpDev_->mtpState == MTP_STATE_OFFLINE) {
1127         HDF_LOGE("%{public}s: device disconnect", __func__);
1128         return HDF_DEV_ERR_NO_DEVICE;
1129     }
1130     if (data.size() == 0) {
1131         HDF_LOGW("%{public}s: no data need to send", __func__);
1132         return HDF_SUCCESS;
1133     }
1134     uint32_t needXferCount = data.size();
1135     uint32_t xferActual = 0;
1136     uint8_t needZLP = ZLP_NO_NEED;
1137     if ((needXferCount & (mtpDev_->dataInPipe.maxPacketSize - 1)) == 0) {
1138         needZLP = ZLP_NEED;
1139     }
1140     return WriteEx(data, needZLP, xferActual);
1141 }
1142 
UsbMtpPortRxCheckReq(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req,bool & writeToFile)1143 int32_t UsbfnMtpImpl::UsbMtpPortRxCheckReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req, bool &writeToFile)
1144 {
1145     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1146     switch (req->status) {
1147         case USB_REQUEST_NO_DEVICE:
1148             mtpDev->mtpState = MTP_STATE_OFFLINE;
1149             HDF_LOGV("%{public}s: rx req return disconnected", __func__);
1150             return HDF_DEV_ERR_NO_DEVICE;
1151         case USB_REQUEST_COMPLETED:
1152             break;
1153         default:
1154             HDF_LOGE("%{public}s: unexpected status %{public}d", __func__, req->status);
1155             mtpDev->mtpState = MTP_STATE_ERROR;
1156             return HDF_FAILURE;
1157     }
1158     if (req->actual == 0) {
1159         HDF_LOGV("%{public}s: recv ZLP packet, end xfer", __func__);
1160         mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1161         return HDF_SUCCESS;
1162     }
1163     if (mtpDev->xferFileLength == MTP_MAX_FILE_SIZE) {
1164         /* no specific length */
1165         writeToFile = true;
1166         if (req->actual < req->length) {
1167             /* short packet indicate transfer end */
1168             mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1169         }
1170         /* normal full packet, also write to file */
1171         return HDF_SUCCESS;
1172     }
1173     /* specific length */
1174     if (req->actual < req->length) {
1175         HDF_LOGE("%{public}s: normal packet(error): %{public}u < %{public}u", __func__, req->actual, req->length);
1176         return HDF_FAILURE;
1177     }
1178     if (req->actual != 0) {
1179         writeToFile = true;
1180     }
1181     if (mtpDev->asyncRecvFileActual + static_cast<uint64_t>(req->actual) == mtpDev->xferFileLength) {
1182         mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1183         HDF_LOGV("%{public}s: last packet: req(%{public}d/%{public}d)%{public}u/%{public}u, recv %{public}" PRIu64
1184             "/%{public}" PRIu64 "/%{public}" PRIu64 "", __func__, mtpPort->readStarted, mtpPort->readAllocated,
1185             req->actual, req->length, mtpDev->asyncRecvFileExpect, mtpDev->asyncRecvFileActual, mtpDev->xferFileLength);
1186     }
1187     return HDF_SUCCESS;
1188 }
1189 
UsbMtpPortProcessAsyncRxDone(struct UsbMtpPort * mtpPort)1190 int32_t UsbfnMtpImpl::UsbMtpPortProcessAsyncRxDone(struct UsbMtpPort *mtpPort)
1191 {
1192     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1193     HDF_LOGV("%{public}s: recv done, ignore other packet(%{public}d/%{public}d):%{public}" PRIu64 "/%{public}" PRIu64
1194         "/%{public}" PRIu64 "", __func__, mtpPort->readStarted, mtpPort->readAllocated, mtpDev->asyncRecvFileExpect,
1195         mtpDev->asyncRecvFileActual, mtpDev->xferFileLength);
1196     if (mtpPort->readStarted == 0) {
1197         sem_post(&asyncReq_);
1198     } else if (mtpDev->xferFileLength == MTP_MAX_FILE_SIZE) {
1199         HDF_LOGV("%{public}s: cancel redundant req", __func__);
1200         while (!DListIsEmpty(&mtpPort->readQueue)) {
1201             struct UsbFnRequest *req = DLIST_FIRST_ENTRY(&mtpPort->readQueue, struct UsbFnRequest, list);
1202             (void)UsbFnCancelRequest(req);
1203             DListRemove(&req->list);
1204             DListInsertTail(&req->list, &mtpPort->readPool);
1205         }
1206     }
1207     return HDF_SUCCESS;
1208 }
1209 
UsbMtpPortRxPush(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)1210 int32_t UsbfnMtpImpl::UsbMtpPortRxPush(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
1211 {
1212     if (mtpPort == nullptr || mtpPort->mtpDev == nullptr) {
1213         HDF_LOGE("%{public}s: invalid param", __func__);
1214         return HDF_ERR_INVALID_PARAM;
1215     }
1216     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1217     bool writeToFile = false;
1218     int32_t ret = UsbMtpPortRxCheckReq(mtpPort, req, writeToFile);
1219     if (ret != HDF_SUCCESS) {
1220         HDF_LOGE("%{public}s: req failed: %{public}d", __func__, ret);
1221         sem_post(&asyncReq_);
1222         return HDF_ERR_IO;
1223     }
1224     if (writeToFile && mtpDev->asyncRecvWriteTempContent) {
1225         uint8_t *bufOff = mtpDev->asyncRecvWriteTempContent + mtpDev->asyncRecvWriteTempCount;
1226         if (memcpy_s(bufOff, req->actual, req->buf, req->actual) != EOK) {
1227             HDF_LOGE("%{public}s: memcpy_s failed", __func__);
1228             return HDF_FAILURE;
1229         }
1230         mtpDev->asyncRecvWriteTempCount += req->actual;
1231         if (mtpDev->asyncRecvWriteTempCount >= WRITE_FILE_TEMP_SLICE) {
1232             ssize_t writeRet = write(mtpDev->xferFd, static_cast<void *>(mtpDev->asyncRecvWriteTempContent),
1233                 static_cast<size_t>(WRITE_FILE_TEMP_SLICE));
1234             if (writeRet != static_cast<ssize_t>(WRITE_FILE_TEMP_SLICE)) {
1235                 HDF_LOGE("%{public}s: write temp failed: %{public}zd", __func__, writeRet);
1236                 mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1237                 sem_post(&asyncReq_);
1238                 return HDF_FAILURE;
1239             }
1240             mtpDev->asyncRecvWriteTempCount = 0;
1241         }
1242         mtpDev->asyncRecvFileActual += static_cast<uint64_t>(req->actual);
1243     }
1244     if (mtpDev->asyncXferFile == ASYNC_XFER_FILE_DONE) {
1245         ssize_t writeRet = write(mtpDev->xferFd, static_cast<void *>(mtpDev->asyncRecvWriteTempContent),
1246             static_cast<size_t>(mtpDev->asyncRecvWriteTempCount));
1247         if (writeRet != static_cast<ssize_t>(mtpDev->asyncRecvWriteTempCount)) {
1248             HDF_LOGE("%{public}s: write last failed: %{public}d", __func__, mtpDev->asyncRecvWriteTempCount);
1249             mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1250             sem_post(&asyncReq_);
1251             return HDF_FAILURE;
1252         }
1253         return UsbMtpPortProcessAsyncRxDone(mtpPort);
1254     }
1255     if (mtpDev->xferFileLength != MTP_MAX_FILE_SIZE && mtpDev->asyncRecvFileExpect != mtpDev->xferFileLength) {
1256         ret = UsbMtpPortStartRxAsync(mtpPort);
1257     }
1258     return ret;
1259 }
1260 
UsbMtpPortStartSubmitRxReq(struct UsbMtpPort * mtpPort,bool needZLP)1261 int32_t UsbfnMtpImpl::UsbMtpPortStartSubmitRxReq(struct UsbMtpPort *mtpPort, bool needZLP)
1262 {
1263     struct DListHead *pool = &mtpPort->readPool;
1264     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1265     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1266     uint64_t reqMax = static_cast<uint64_t>(mtpDev->dataOutPipe.maxPacketSize);
1267     if (mtpDev->asyncRecvFileExpect + reqMax < mtpDev->xferFileLength) {
1268         req->length = static_cast<uint32_t>(mtpDev->dataOutPipe.maxPacketSize);
1269     } else {
1270         req->length = static_cast<uint32_t>(mtpDev->xferFileLength - mtpDev->asyncRecvFileExpect);
1271     }
1272     if (mtpDev->xferFileLength == MTP_MAX_FILE_SIZE) {
1273         req->length = static_cast<uint32_t>(mtpDev->dataOutPipe.maxPacketSize);
1274     }
1275     if (needZLP) {
1276         req->length = 0;
1277     }
1278     DListRemove(&req->list);
1279     DListInsertTail(&req->list, &mtpPort->readQueue);
1280     int32_t ret = UsbFnSubmitRequestAsync(req);
1281     if (ret != HDF_SUCCESS) {
1282         HDF_LOGE("%{public}s: submit bulk-out req error %{public}d", __func__, ret);
1283         DListRemove(&req->list);
1284         DListInsertTail(&req->list, pool);
1285         return ret;
1286     }
1287     mtpPort->readStarted++;
1288     mtpDev->asyncRecvFileExpect += static_cast<uint64_t>(req->length);
1289     return HDF_SUCCESS;
1290 }
1291 
UsbMtpPortStartRxAsync(struct UsbMtpPort * mtpPort)1292 int32_t UsbfnMtpImpl::UsbMtpPortStartRxAsync(struct UsbMtpPort *mtpPort)
1293 {
1294     struct DListHead *pool = &mtpPort->readPool;
1295     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1296     int32_t ret = HDF_SUCCESS;
1297     std::lock_guard<std::mutex> guard(asyncMutex_);
1298     while (!DListIsEmpty(pool)) {
1299         if (mtpPort->readStarted >= mtpPort->readAllocated) {
1300             HDF_LOGW("%{public}s no idle read req(BULK-OUT): %{public}d/%{public}d", __func__, mtpPort->readStarted,
1301                 mtpPort->readAllocated);
1302             ret = HDF_ERR_DEVICE_BUSY;
1303             break;
1304         }
1305         if (mtpDev->mtpState == MTP_STATE_OFFLINE) {
1306             HDF_LOGE("%{public}s: device disconnect, stop rx", __func__);
1307             ret = HDF_DEV_ERR_NO_DEVICE;
1308             break;
1309         }
1310         if ((mtpDev->xferFileLength != MTP_MAX_FILE_SIZE && mtpDev->asyncRecvFileExpect >= mtpDev->xferFileLength) ||
1311             mtpDev->asyncXferFile == ASYNC_XFER_FILE_DONE) {
1312             HDF_LOGV("%{public}s: no need rx req[%{public}d/%{public}d]:%{public}" PRIu64 "/%{public}" PRIu64
1313                 "/%{public}" PRIu64 ", xfer=%{public}hhu", __func__, mtpPort->readStarted, mtpPort->readAllocated,
1314                 mtpDev->asyncRecvFileExpect, mtpDev->asyncRecvFileActual, mtpDev->xferFileLength,
1315                 mtpDev->asyncXferFile);
1316             return ret;
1317         }
1318         ret = UsbMtpPortStartSubmitRxReq(mtpPort, false);
1319         if (ret != HDF_SUCCESS) {
1320             HDF_LOGE("%{public}s: submit bulk-out req error %{public}d", __func__, ret);
1321             break;
1322         }
1323     }
1324     return ret;
1325 }
1326 
ReceiveFileEx()1327 int32_t UsbfnMtpImpl::ReceiveFileEx()
1328 {
1329     sem_init(&asyncReq_, 1, 0);
1330     mtpDev_->asyncXferFile = ASYNC_XFER_FILE_NORMAL;
1331     mtpDev_->asyncRecvWriteTempContent = static_cast<uint8_t *>(OsalMemCalloc(WRITE_FILE_TEMP_SLICE));
1332     mtpDev_->asyncRecvWriteTempCount = 0;
1333     int32_t ret = UsbMtpPortStartRxAsync(mtpPort_);
1334     if (ret != HDF_SUCCESS) {
1335         HDF_LOGE("%{public}s: start async tx failed: %{public}d", __func__, ret);
1336         (void)OsalMemFree(mtpDev_->asyncRecvWriteTempContent);
1337         mtpDev_->asyncRecvWriteTempContent = nullptr;
1338         return HDF_ERR_IO;
1339     }
1340     HDF_LOGV("%{public}s: wait async rx", __func__);
1341     sem_wait(&asyncReq_);
1342     (void)OsalMemFree(mtpDev_->asyncRecvWriteTempContent);
1343     mtpDev_->asyncRecvWriteTempContent = nullptr;
1344     if (syncfs(mtpDev_->xferFd) != 0) {
1345         HDF_LOGE("%{public}s: failed: commit filesystem caches to disk", __func__);
1346         return HDF_ERR_IO;
1347     }
1348     if (mtpDev_->xferFileLength == MTP_MAX_FILE_SIZE) {
1349         HDF_LOGV("%{public}s: no specific length, reset state", __func__);
1350         mtpDev_->mtpState = MTP_STATE_READY;
1351         return mtpDev_->asyncXferFile == ASYNC_XFER_FILE_DONE ? HDF_SUCCESS : HDF_ERR_IO;
1352     }
1353     return mtpDev_->asyncRecvFileActual == mtpDev_->xferFileLength ? HDF_SUCCESS : HDF_ERR_IO;
1354 }
1355 
ReceiveFile(const UsbFnMtpFileSlice & mfs)1356 int32_t UsbfnMtpImpl::ReceiveFile(const UsbFnMtpFileSlice &mfs)
1357 {
1358     if (mtpPort_ == nullptr || mtpDev_ == nullptr || mtpDev_->initFlag == false) {
1359         HDF_LOGE("%{public}s: no init", __func__);
1360         return HDF_DEV_ERR_DEV_INIT_FAIL;
1361     }
1362     std::lock_guard<std::mutex> guard(mtpRunning_);
1363     HDF_LOGV("%{public}s: info: cmd=%{public}d, transid=%{public}d, len=%{public}" PRId64 " offset=%{public}" PRId64
1364         ", state=%{public}hhu", __func__, mfs.command, mfs.transactionId, mfs.length, mfs.offset, mtpDev_->mtpState);
1365 
1366     if (mtpDev_->mtpState == MTP_STATE_OFFLINE) {
1367         HDF_LOGE("%{public}s: device disconnect", __func__);
1368         return HDF_DEV_ERR_NO_DEVICE;
1369     }
1370     if (mfs.length <= 0) {
1371         HDF_LOGW("%{public}s: no data need to recv", __func__);
1372         return HDF_SUCCESS;
1373     }
1374     mtpDev_->xferFd = mfs.fd;
1375     mtpDev_->xferFileOffset = mfs.offset;
1376     mtpDev_->xferFileLength = static_cast<uint64_t>(mfs.length);
1377     lseek(mfs.fd, mfs.offset, SEEK_SET);
1378     mtpDev_->asyncRecvFileActual = 0;
1379     mtpDev_->asyncRecvFileExpect = 0;
1380     mtpDev_->needZLP = ZLP_NO_NEED;
1381     if ((mtpDev_->xferFileLength & (mtpDev_->dataInPipe.maxPacketSize - 1)) == 0) {
1382         mtpDev_->needZLP = ZLP_NEED;
1383     }
1384     int32_t ret = ReceiveFileEx();
1385     if (ret != HDF_SUCCESS) {
1386         HDF_LOGE("%{public}s: failed: recvfile %{public}d", __func__, ret);
1387     }
1388     return ret;
1389 }
1390 
UsbMtpPortSendFileFillFirstReq(struct UsbFnRequest * req,uint64_t & oneReqLeft)1391 int32_t UsbfnMtpImpl::UsbMtpPortSendFileFillFirstReq(struct UsbFnRequest *req, uint64_t &oneReqLeft)
1392 {
1393     uint64_t hdrSize = static_cast<uint64_t>((mtpDev_->xferSendHeader == 1) ? sizeof(struct UsbMtpDataHeader) : 0);
1394     uint64_t needXferCount = mtpDev_->xferFileLength + hdrSize;
1395     uint64_t reqMax = static_cast<uint64_t>(mtpDev_->dataInPipe.maxPacketSize);
1396     req->length = (reqMax > needXferCount) ? static_cast<uint32_t>(needXferCount) : static_cast<uint32_t>(reqMax);
1397     if (hdrSize != 0) {
1398         /* write MTP header first */
1399         struct UsbMtpDataHeader *header = static_cast<struct UsbMtpDataHeader *>(req->buf);
1400         /* set file size with header according to MTP Specification v1.0 */
1401         header->length =
1402             static_cast<uint32_t>(needXferCount > MTP_MAX_FILE_SIZE ? MTP_MAX_FILE_SIZE : CPU_TO_LE32(needXferCount));
1403         /* type value 2 specified data packet */
1404         header->type = CPU_TO_LE16(2);
1405         header->cmdCode = CPU_TO_LE16(mtpDev_->xferCommand);
1406         header->transactionId = CPU_TO_LE32(mtpDev_->xferTransactionId);
1407     }
1408     uint8_t *bufOffset = static_cast<uint8_t *>(req->buf) + hdrSize;
1409     oneReqLeft = (hdrSize + mtpDev_->xferFileLength < reqMax) ? mtpDev_->xferFileLength : reqMax - hdrSize;
1410     ssize_t readRet = read(mtpDev_->xferFd, static_cast<void *>(bufOffset), static_cast<size_t>(oneReqLeft));
1411     if (readRet != static_cast<ssize_t>(oneReqLeft)) {
1412         HDF_LOGE("%{public}s: read failed: %{public}zd vs %{public}" PRId64 "", __func__, readRet, oneReqLeft);
1413         return HDF_FAILURE;
1414     }
1415     return HDF_SUCCESS;
1416 }
1417 
UsbMtpPortSendFileEx()1418 int32_t UsbfnMtpImpl::UsbMtpPortSendFileEx()
1419 {
1420     struct DListHead *pool = &mtpPort_->writePool;
1421     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1422     if (req == nullptr) {
1423         HDF_LOGE("%{public}s: req invalid", __func__);
1424         return HDF_DEV_ERR_DEV_INIT_FAIL;
1425     }
1426     DListRemove(&req->list);
1427     uint64_t oneReqLeft = 0;
1428     int32_t ret = UsbMtpPortSendFileFillFirstReq(req, oneReqLeft);
1429     if (ret != HDF_SUCCESS) {
1430         HDF_LOGE("%{public}s: fill first sync bulk-in req failed: %{public}d", __func__, ret);
1431         DListInsertTail(&req->list, pool);
1432         return ret;
1433     }
1434     ret = UsbFnSubmitRequestSync(req, BULK_IN_TIMEOUT_JIFFIES);
1435     DListInsertTail(&req->list, pool);
1436     if (ret != HDF_SUCCESS) {
1437         HDF_LOGE("%{public}s: bulk-in req failed: %{public}d", __func__, ret);
1438         return ret;
1439     }
1440     switch (req->status) {
1441         case USB_REQUEST_COMPLETED:
1442             break;
1443         case USB_REQUEST_NO_DEVICE:
1444             HDF_LOGV("%{public}s: device disconnected", __func__);
1445             mtpDev_->mtpState = MTP_STATE_OFFLINE;
1446             return HDF_DEV_ERR_NO_DEVICE;
1447         default:
1448             HDF_LOGV("%{public}s: unexpected status %{public}d", __func__, req->status);
1449             mtpDev_->mtpState = MTP_STATE_ERROR;
1450             return HDF_ERR_IO;
1451     }
1452     if (oneReqLeft != mtpDev_->xferFileLength) {
1453         ret = UsbMtpPortSendFileLeftAsync(oneReqLeft);
1454     }
1455     return ret;
1456 }
1457 
UsbMtpPortSendFileLeftAsync(uint64_t oneReqLeft)1458 int32_t UsbfnMtpImpl::UsbMtpPortSendFileLeftAsync(uint64_t oneReqLeft)
1459 {
1460     mtpDev_->xferFileLength -= oneReqLeft;
1461     mtpDev_->asyncSendFileActual = 0;
1462     mtpDev_->asyncSendFileExpect = 0;
1463     sem_init(&asyncReq_, 1, 0);
1464     mtpDev_->asyncXferFile = ASYNC_XFER_FILE_NORMAL;
1465     if (UsbMtpPortStartTxAsync(mtpPort_, false) != HDF_SUCCESS) {
1466         HDF_LOGE("%{public}s: start async tx failed", __func__);
1467         return HDF_ERR_IO;
1468     }
1469     HDF_LOGV("%{public}s: wait async tx", __func__);
1470     sem_wait(&asyncReq_);
1471     return (mtpDev_->mtpState == MTP_STATE_ERROR) ? HDF_ERR_IO : HDF_SUCCESS;
1472 }
1473 
SendFile(const UsbFnMtpFileSlice & mfs)1474 int32_t UsbfnMtpImpl::SendFile(const UsbFnMtpFileSlice &mfs)
1475 {
1476     if (mtpPort_ == nullptr || mtpDev_ == nullptr || mtpDev_->initFlag == false) {
1477         HDF_LOGE("%{public}s: no init", __func__);
1478         return HDF_DEV_ERR_DEV_INIT_FAIL;
1479     }
1480     std::lock_guard<std::mutex> guard(mtpRunning_);
1481 
1482     mtpDev_->xferFd = mfs.fd;
1483     mtpDev_->xferFileOffset = static_cast<uint64_t>(mfs.offset);
1484     mtpDev_->xferFileLength = static_cast<uint64_t>(mfs.length);
1485     mtpDev_->xferCommand = mfs.command;
1486     mtpDev_->xferTransactionId = mfs.transactionId;
1487     mtpDev_->xferSendHeader = (mfs.command == 0 && mfs.transactionId == 0) ? 0 : 1;
1488     uint64_t hdrSize = (mtpDev_->xferSendHeader == 1) ? static_cast<uint64_t>(sizeof(struct UsbMtpDataHeader)) : 0;
1489     uint64_t needXferCount = mfs.length + hdrSize;
1490     lseek(mfs.fd, mfs.offset, SEEK_SET);
1491     HDF_LOGV("%{public}s: info: cmd=%{public}d, transid=%{public}d, len=%{public}" PRId64 " offset=%{public}" PRId64
1492         "; Xfer=%{public}" PRIu64 "(header=%{public}" PRIu64 "), state=%{public}hhu", __func__, mfs.command,
1493         mfs.transactionId, mfs.length, mfs.offset, needXferCount, hdrSize, mtpDev_->mtpState);
1494 
1495     if (needXferCount == 0 || mfs.length < 0) {
1496         HDF_LOGW("%{public}s: no data need to send", __func__);
1497         return HDF_SUCCESS;
1498     }
1499     if (mtpDev_->mtpState == MTP_STATE_OFFLINE) {
1500         HDF_LOGE("%{public}s: device disconnect", __func__);
1501         return HDF_DEV_ERR_NO_DEVICE;
1502     }
1503     mtpDev_->needZLP = ZLP_NO_NEED;
1504     if ((needXferCount & (mtpDev_->dataInPipe.maxPacketSize - 1)) == 0) {
1505         mtpDev_->needZLP = ZLP_NEED;
1506     }
1507     int32_t ret = UsbMtpPortSendFileEx();
1508     if (ret != HDF_SUCCESS) {
1509         HDF_LOGE("%{public}s: failed: sendfile %{public}d", __func__, ret);
1510     }
1511     return ret;
1512 }
1513 
SendEvent(const std::vector<uint8_t> & eventData)1514 int32_t UsbfnMtpImpl::SendEvent(const std::vector<uint8_t> &eventData)
1515 {
1516     if (mtpPort_ == nullptr || mtpDev_ == nullptr || mtpDev_->initFlag == false) {
1517         HDF_LOGE("%{public}s: no init", __func__);
1518         return HDF_DEV_ERR_DEV_INIT_FAIL;
1519     }
1520     std::lock_guard<std::mutex> guard(mtpRunning_);
1521 
1522     if (eventData.size() > MTP_EVENT_PACKET_MAX_BYTES || eventData.size() == 0) {
1523         HDF_LOGE("%{public}s: length is invald: %{public}zu", __func__, eventData.size());
1524         return HDF_FAILURE;
1525     }
1526     if (mtpDev_->mtpState == MTP_STATE_OFFLINE) {
1527         HDF_LOGE("%{public}s: device disconnect", __func__);
1528         return HDF_DEV_ERR_NO_DEVICE;
1529     }
1530     struct UsbFnRequest *req = mtpDev_->notifyReq;
1531     if (req == nullptr || req->buf == nullptr) {
1532         HDF_LOGE("%{public}s: notify req is null", __func__);
1533         return HDF_ERR_INVALID_PARAM;
1534     }
1535     if (memcpy_s(req->buf, eventData.size(), eventData.data(), eventData.size()) != EOK) {
1536         HDF_LOGE("%{public}s: memcpy_s failed", __func__);
1537         (void)UsbFnFreeRequest(req);
1538         return HDF_FAILURE;
1539     }
1540     req->length = static_cast<uint32_t>(eventData.size());
1541     int32_t ret = UsbFnSubmitRequestSync(req, INTR_IN_TIMEOUT_JIFFIES);
1542     if (ret != HDF_SUCCESS) {
1543         HDF_LOGE("%{public}s: send notify sync request failed: %{public}d", __func__, ret);
1544     }
1545     return ret;
1546 }
1547 } // namespace V1_0
1548 } // namespace Mtp
1549 } // namespace Gadget
1550 } // namespace Usb
1551 } // namespace HDI
1552 } // namespace OHOS
1553