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