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 */
31static 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 */
41struct 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 */
50struct 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 */
59static 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
83struct UsbMtpDeviceStatus {
84    uint16_t wLength;
85    uint16_t wCode;
86};
87
88namespace OHOS {
89namespace HDI {
90namespace Usb {
91namespace Gadget {
92namespace Mtp {
93namespace V1_0 {
94sptr<IUsbfnMtpInterface> g_instance = nullptr;
95std::mutex g_instanceLock;
96extern "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
107struct UsbMtpDevice *UsbfnMtpImpl::mtpDev_ = nullptr;
108struct UsbMtpPort *UsbfnMtpImpl::mtpPort_ = nullptr;
109std::mutex UsbfnMtpImpl::mtpRunning_;
110std::mutex UsbfnMtpImpl::asyncMutex_;
111sem_t UsbfnMtpImpl::asyncReq_ {0};
112
113constexpr uint32_t BULK_IN_TIMEOUT_JIFFIES = 0;  /* sync timeout, set to 0 means wait forever */
114constexpr uint32_t BULK_OUT_TIMEOUT_JIFFIES = 0; /* sync timeout, set to 0 means wait forever */
115constexpr uint32_t INTR_IN_TIMEOUT_JIFFIES = 0;  /* sync timeout, set to 0 means wait forever */
116constexpr uint64_t MTP_MAX_FILE_SIZE = 0xFFFFFFFFULL;
117constexpr uint32_t WRITE_FILE_TEMP_SLICE = 100 * 1024; /* 100KB */
118static constexpr int32_t WAIT_UDC_MAX_LOOP = 3;
119static constexpr uint32_t WAIT_UDC_TIME = 100000;
120enum 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
127enum UsbMtpAsyncXferState {
128    ASYNC_XFER_FILE_NORMAL = 0,
129    ASYNC_XFER_FILE_DONE,
130};
131
132UsbfnMtpImpl::UsbfnMtpImpl() : deviceObject_(nullptr) {}
133
134void 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
159void 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
184void 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
193void 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
221int32_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
251int32_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
267int32_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
287int32_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
328int32_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
354void 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
366void 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
376int32_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
409int32_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
426int32_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
446int32_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
457int32_t UsbfnMtpImpl::UsbMtpPortReleaseIo()
458{
459    return UsbMtpPortCancelPlusFreeIo(mtpPort_, true);
460}
461
462struct 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
473int32_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
496int32_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
526int32_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
547int32_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
592void 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
604void 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
618int32_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
636int32_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
654void 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
698int32_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
749int32_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
766bool 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
783int32_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
801int32_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
836int32_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
859int32_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
876int32_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
889void 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
899int32_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
910int32_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;
953ERR:
954    (void)UsbMtpDeviceReleaseFuncDevice();
955    (void)UsbMtpDeviceFree();
956    (void)OsalMemFree(mtpDev_);
957    mtpDev_ = nullptr;
958    return ret;
959}
960
961int32_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
984int32_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
997int32_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
1011uint32_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
1018uint32_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
1029int32_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
1071int32_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
1118int32_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
1143int32_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
1190int32_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
1210int32_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) {
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
1261int32_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
1292int32_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
1327int32_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
1356int32_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
1391int32_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
1418int32_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
1458int32_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
1474int32_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
1514int32_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