• 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 #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 #include "scope_guard.h"
27 
28 #define HDF_LOG_TAG usbfn_mtp_impl
29 #define UDC_NAME "invalid_udc_name"
30 #undef  LOG_DOMAIN
31 #define LOG_DOMAIN 0xD002518
32 
33 /* Compatible: Microsoft MTP OS String */
34 static uint8_t g_mtpOsString[] = {18, /* sizeof(mtp_os_string) */
35     USB_DDK_DT_STRING,
36     /* Signature field: "MSFT100" (4D00530046005400310030003000) */
37     'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0,
38     /* Vendor code to fetch other OS feature descriptors */
39     1,
40     /* padding */
41     0};
42 
43 /* Microsoft Extended Configuration Descriptor Header Section */
44 struct UsbMtpExtConfigDescHeader {
45     uint32_t dwLength;
46     uint16_t bcdVersion;
47     uint16_t wIndex;
48     uint8_t bCount;
49     uint8_t reserved[7]; /* reserved */
50 };
51 
52 /* Microsoft Extended Configuration Descriptor Function Section */
53 struct UsbMtpExtConfigDescFunction {
54     uint8_t bFirstInterfaceNumber;
55     uint8_t bInterfaceCount;
56     uint8_t compatibleID[8];    /* The function’s compatible ID */
57     uint8_t subCompatibleID[8]; /* The function’s subcompatible ID */
58     uint8_t reserved[6];        /* reserved */
59 };
60 
61 /* Compatible: MTP Extended Configuration Descriptor */
62 static struct {
63     struct UsbMtpExtConfigDescHeader header;
64     struct UsbMtpExtConfigDescFunction function;
65 } g_mtpExtConfigDesc = {
66     .header = {
67         .dwLength = CPU_TO_LE32(sizeof(g_mtpExtConfigDesc)),
68         /* The descriptor’s version number in Binary Coded Decimal (for example, version 1.00 is 0100H) */
69         .bcdVersion = CPU_TO_LE16(0x0100),
70         /* set to 0x04 for extended compat ID descriptors */
71         .wIndex = CPU_TO_LE16(4),
72         /* Number of function sections */
73         .bCount = CPU_TO_LE16(1),
74         .reserved = {0},
75     },
76     .function = {
77         .bFirstInterfaceNumber = 0,
78         .bInterfaceCount = 1,
79         /* Media Transfer Protocol */
80         .compatibleID = {'M', 'T', 'P'},
81         .subCompatibleID = {0},
82         .reserved = {0},
83     },
84 };
85 
86 struct UsbMtpDeviceStatus {
87     uint16_t wLength;
88     uint16_t wCode;
89 };
90 
91 namespace OHOS {
92 namespace HDI {
93 namespace Usb {
94 namespace Gadget {
95 namespace Mtp {
96 namespace V1_0 {
97 sptr<IUsbfnMtpInterface> g_instance = nullptr;
98 std::mutex g_instanceLock;
UsbfnMtpInterfaceImplGetInstance(void)99 extern "C" void *UsbfnMtpInterfaceImplGetInstance(void)
100 {
101     std::lock_guard<std::mutex> guard(g_instanceLock);
102     if (g_instance == nullptr) {
103         sptr<IUsbfnMtpInterface> tmp(new (std::nothrow) UsbfnMtpImpl);
104         g_instance = tmp;
105     }
106 
107     return g_instance;
108 }
109 
110 struct UsbMtpDevice *UsbfnMtpImpl::mtpDev_ = nullptr;
111 struct UsbMtpPort *UsbfnMtpImpl::mtpPort_ = nullptr;
112 pthread_rwlock_t UsbfnMtpImpl::mtpRunrwLock_ = PTHREAD_RWLOCK_INITIALIZER;
113 std::mutex UsbfnMtpImpl::startMutex_;
114 std::mutex UsbfnMtpImpl::readMutex_;
115 std::mutex UsbfnMtpImpl::writeMutex_;
116 std::mutex UsbfnMtpImpl::eventMutex_;
117 std::mutex UsbfnMtpImpl::asyncMutex_;
118 sem_t UsbfnMtpImpl::asyncReq_ {0};
119 
120 constexpr uint32_t BULK_IN_TIMEOUT_JIFFIES = 0;  /* sync timeout, set to 0 means wait forever */
121 constexpr uint32_t BULK_OUT_TIMEOUT_JIFFIES = 0; /* sync timeout, set to 0 means wait forever */
122 constexpr uint32_t INTR_IN_TIMEOUT_JIFFIES = 0;  /* sync timeout, set to 0 means wait forever */
123 constexpr uint64_t MTP_MAX_FILE_SIZE = 0xFFFFFFFFULL;
124 constexpr uint32_t WRITE_FILE_TEMP_SLICE = 16 * 100 * 1024; /* 16*100KB */
125 constexpr uint32_t ZERO_LENGTH_PACKET_JIFFIES = 100;  /* sync timeout, set to 0 means wait forever */
126 constexpr uint32_t ZERO_LENGTH_PACKET = 0;
127 static constexpr int32_t WAIT_UDC_MAX_LOOP = 3;
128 static constexpr uint32_t WAIT_UDC_TIME = 300000;
129 static constexpr uint32_t REQ_ACTUAL_DEFAULT_LENGTH = 0;
130 static constexpr uint32_t REQ_ACTUAL_MAX_LENGTH = 128;
131 static constexpr uint32_t REQ_ACTUAL_MININUM_LENGTH = 5;
132 static constexpr int32_t  HDF_ERROR_ECANCEL = -20;
133 static constexpr int32_t  WRITE_SPLIT_MININUM_LENGTH = 81920;
134 static constexpr int32_t  MTP_PROTOCOL_PACKET_SIZE = 4;
135 static constexpr int32_t  MTP_BUFFER_SIZE = 16384;
136 enum UsbMtpNeedZeroLengthPacket {
137     ZLP_NO_NEED = 0, /* no need send ZLP */
138     ZLP_NEED,        /* need send ZLP */
139     ZLP_TRY,         /* try send ZLP */
140     ZLP_DONE,        /* send ZLP done */
141 };
142 
143 enum UsbMtpAsyncXferState {
144     ASYNC_XFER_FILE_NORMAL = 0,
145     ASYNC_XFER_FILE_DONE,
146 };
147 
UsbfnMtpImpl()148 UsbfnMtpImpl::UsbfnMtpImpl() : deviceObject_(nullptr) {}
149 
UsbFnRequestReadComplete(uint8_t pipe,struct UsbFnRequest * req)150 void UsbfnMtpImpl::UsbFnRequestReadComplete(uint8_t pipe, struct UsbFnRequest *req)
151 {
152     (void)pipe;
153     if (req == nullptr || req->context == nullptr) {
154         HDF_LOGE("%{public}s: invalid param", __func__);
155         return;
156     }
157     pthread_rwlock_rdlock(&mtpRunrwLock_);
158     struct UsbMtpPort *mtpPort = static_cast<struct UsbMtpPort *>(req->context);
159     if (mtpPort_ == nullptr || mtpDev_ == nullptr ||
160         mtpPort == nullptr || mtpPort->mtpDev == nullptr) {
161         pthread_rwlock_unlock(&mtpRunrwLock_);
162         HDF_LOGE("%{public}s: invalid content", __func__);
163         return;
164     }
165     UsbMtpPortReleaseRxReq(mtpPort, req);
166     if (mtpPort->mtpDev->mtpState == MTP_STATE_CANCELED) {
167         CopyReqToStandbyReqPool(req, mtpPort->standbyReq);
168         pthread_rwlock_unlock(&mtpRunrwLock_);
169         HDF_LOGD("%{public}s, mtpState: %{public}d.", __func__, mtpPort->mtpDev->mtpState);
170         return;
171     }
172     if (!mtpDev_->initFlag) {
173         pthread_rwlock_unlock(&mtpRunrwLock_);
174         HDF_LOGE("%{public}s: dev is release", __func__);
175         return;
176     }
177     int32_t ret = UsbMtpPortRxPush(mtpPort, req);
178     if (ret != HDF_SUCCESS) {
179         HDF_LOGW("%{public}s: rx push failed: %{public}d, state=%{public}d", __func__, ret, mtpPort->mtpDev->mtpState);
180     }
181     pthread_rwlock_unlock(&mtpRunrwLock_);
182 }
183 
RemoveReqFromList(struct UsbFnRequest * req)184 static void RemoveReqFromList(struct UsbFnRequest *req)
185 {
186     if (req->list.prev != NULL && req->list.next != NULL) {
187         DListRemove(&req->list);
188     } else {
189         HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
190     }
191 }
192 
UsbMtpPortReleaseRxReq(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)193 void UsbfnMtpImpl::UsbMtpPortReleaseRxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
194 {
195     std::lock_guard<std::mutex> guard(asyncMutex_);
196 
197     if (mtpPort->suspended) {
198         return;
199     }
200     if (req->list.prev != NULL && req->list.next != NULL) {
201         DListRemove(&req->list);
202     } else {
203         HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
204     }
205     DListInsertTail(&req->list, &mtpPort->readPool);
206     mtpPort->readStarted--;
207 }
208 
UsbMtpPortReleaseTxReq(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)209 void UsbfnMtpImpl::UsbMtpPortReleaseTxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
210 {
211     std::lock_guard<std::mutex> guard(asyncMutex_);
212 
213     if (mtpPort->suspended) {
214         return;
215     }
216     if (req->list.prev != NULL && req->list.next != NULL) {
217         DListRemove(&req->list);
218     } else {
219         HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
220     }
221     DListInsertTail(&req->list, &mtpPort->writePool);
222     mtpPort->writeStarted--;
223 }
224 
UsbFnRequestWriteComplete(uint8_t pipe,struct UsbFnRequest * req)225 void UsbfnMtpImpl::UsbFnRequestWriteComplete(uint8_t pipe, struct UsbFnRequest *req)
226 {
227     (void)pipe;
228     if (req == nullptr || req->context == nullptr) {
229         HDF_LOGE("%{public}s: invalid param", __func__);
230         return;
231     }
232     pthread_rwlock_rdlock(&mtpRunrwLock_);
233     struct UsbMtpPort *mtpPort = static_cast<struct UsbMtpPort *>(req->context);
234     if (mtpPort_ == nullptr || mtpDev_ == nullptr ||
235         mtpPort == nullptr || mtpPort->mtpDev == nullptr) {
236         pthread_rwlock_unlock(&mtpRunrwLock_);
237         HDF_LOGE("%{public}s: invalid content", __func__);
238         return;
239     }
240     UsbMtpPortReleaseTxReq(mtpPort, req);
241     if (mtpPort->mtpDev->mtpState == MTP_STATE_CANCELED || !mtpDev_->initFlag) {
242         pthread_rwlock_unlock(&mtpRunrwLock_);
243         HDF_LOGD("%{public}s, mtpState: %{public}d.", __func__, mtpPort->mtpDev->mtpState);
244         return;
245     }
246     int32_t ret = UsbMtpPortTxReqCheck(mtpPort, req);
247     if (ret != HDF_SUCCESS) {
248         HDF_LOGW("%{public}s: tx check failed(%{%{public}d/%{public}d}): %{public}d, state=%{public}hhu", __func__,
249             mtpPort->readStarted, mtpPort->readAllocated, ret, mtpPort->mtpDev->mtpState);
250     }
251     pthread_rwlock_unlock(&mtpRunrwLock_);
252 }
253 
UsbFnRequestNotifyComplete(uint8_t pipe,struct UsbFnRequest * req)254 void UsbfnMtpImpl::UsbFnRequestNotifyComplete(uint8_t pipe, struct UsbFnRequest *req)
255 {
256     (void)pipe;
257     if (req == nullptr || req->context == nullptr) {
258         HDF_LOGE("%{public}s: invalid param", __func__);
259         return;
260     }
261 }
262 
UsbFnRequestCtrlComplete(uint8_t pipe,struct UsbFnRequest * req)263 void UsbfnMtpImpl::UsbFnRequestCtrlComplete(uint8_t pipe, struct UsbFnRequest *req)
264 {
265     (void)pipe;
266     if (req == nullptr || req->context == nullptr) {
267         HDF_LOGE("%{public}s: invalid param", __func__);
268         return;
269     }
270     pthread_rwlock_rdlock(&mtpRunrwLock_);
271     struct CtrlInfo *ctrlInfo = static_cast<struct CtrlInfo *>(req->context);
272     if (mtpPort_ == nullptr || mtpDev_ == nullptr ||
273         ctrlInfo == nullptr || ctrlInfo->mtpDev == nullptr) {
274         pthread_rwlock_unlock(&mtpRunrwLock_);
275         HDF_LOGE("%{public}s: invalid content", __func__);
276         return;
277     }
278     struct UsbMtpDevice *mtpDev = ctrlInfo->mtpDev;
279     switch (req->status) {
280         case USB_REQUEST_COMPLETED:
281             break;
282         case USB_REQUEST_NO_DEVICE:
283             HDF_LOGW("%{public}s: usb mtpDev device was disconnected", __func__);
284             mtpDev->mtpState = MTP_STATE_OFFLINE;
285             break;
286         default:
287             HDF_LOGW("%{public}s: unexpected status %{public}d", __func__, req->status);
288             break;
289     }
290     DListInsertTail(&req->list, &mtpDev->ctrlPool);
291     pthread_rwlock_unlock(&mtpRunrwLock_);
292 }
293 
UsbMtpPortTxReqCheck(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)294 int32_t UsbfnMtpImpl::UsbMtpPortTxReqCheck(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
295 {
296     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
297     switch (req->status) {
298         case USB_REQUEST_COMPLETED:
299             mtpDev->asyncSendFileActual += static_cast<uint64_t>(req->actual);
300             if (mtpDev->asyncSendFileActual == mtpDev->xferFileLength &&
301                 ((req->actual == 0 && mtpDev->needZLP == ZLP_TRY) || mtpDev->needZLP == ZLP_NO_NEED)) {
302                 HDF_LOGD("%{public}s: async tx done: req(%{public}d/%{public}d)%{public}u/%{public}u, send "
303                     "%{public}" PRIu64 "/%{public}" PRIu64 "/%{public}" PRIu64 ", ZLP=%{public}hhu", __func__,
304                     mtpPort->writeStarted, mtpPort->writeAllocated, req->actual, req->length,
305                     mtpDev->asyncSendFileExpect, mtpDev->asyncSendFileActual, mtpDev->xferFileLength, mtpDev->needZLP);
306                 sem_post(&asyncReq_);
307                 return HDF_SUCCESS;
308             }
309             return UsbMtpPortStartTxAsync(mtpPort, true);
310         case USB_REQUEST_NO_DEVICE:
311             HDF_LOGW("%{public}s: tx req return disconnected", __func__);
312             mtpPort->mtpDev->mtpState = MTP_STATE_OFFLINE;
313             sem_post(&asyncReq_);
314             return HDF_DEV_ERR_NO_DEVICE;
315         default:
316             HDF_LOGW("%{public}s: unexpected status %{public}d", __func__, req->status);
317             sem_post(&asyncReq_);
318             return HDF_ERR_IO;
319     }
320     return HDF_SUCCESS;
321 }
322 
UsbMtpPortProcessLastTxPacket(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)323 int32_t UsbfnMtpImpl::UsbMtpPortProcessLastTxPacket(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
324 {
325     int32_t ret = HDF_SUCCESS;
326     if (mtpPort->mtpDev->needZLP == ZLP_NEED) {
327         mtpPort->mtpDev->needZLP = ZLP_TRY;
328         req->length = 0;
329         ret = UsbFnSubmitRequestAsync(req);
330         if (ret != HDF_SUCCESS) {
331             HDF_LOGE("%{public}s: submit bulk-in zlp req error: %{public}d", __func__, ret);
332             sem_post(&asyncReq_);
333         }
334         mtpPort->writeStarted++;
335     }
336     return ret;
337 }
338 
UsbMtpPortSubmitAsyncTxReq(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)339 int32_t UsbfnMtpImpl::UsbMtpPortSubmitAsyncTxReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
340 {
341     ssize_t readRet = read(mtpPort->mtpDev->xferFd, req->buf, static_cast<size_t>(req->length));
342     if (readRet != static_cast<ssize_t>(req->length)) {
343         HDF_LOGE("%{public}s: read failed: %{public}zd < %{public}u", __func__, readRet, req->length);
344         return HDF_FAILURE;
345     }
346     if (req->list.prev != NULL && req->list.next != NULL) {
347         DListRemove(&req->list);
348     } else {
349         HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
350     }
351     DListInsertTail(&req->list, &mtpPort->writeQueue);
352     int32_t ret = UsbFnSubmitRequestAsync(req);
353     if (ret != HDF_SUCCESS) {
354         HDF_LOGE("%{public}s: submit bulk-in req error: %{public}d", __func__, ret);
355         if (req->list.prev != NULL && req->list.next != NULL) {
356             DListRemove(&req->list);
357         } else {
358             HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
359         }
360         DListInsertTail(&req->list, &mtpPort->writePool);
361         return ret;
362     }
363     mtpPort->writeStarted++;
364     return ret;
365 }
366 
UsbMtpPortStartTxAsync(struct UsbMtpPort * mtpPort,bool callByComplete)367 int32_t UsbfnMtpImpl::UsbMtpPortStartTxAsync(struct UsbMtpPort *mtpPort, bool callByComplete)
368 {
369     if (mtpPort == nullptr || mtpPort->mtpDev == nullptr) {
370         HDF_LOGE("%{public}s: invalid param", __func__);
371         return HDF_ERR_INVALID_PARAM;
372     }
373     std::lock_guard<std::mutex> guard(asyncMutex_);
374 
375     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
376     struct DListHead *pool = &mtpPort->writePool;
377     uint64_t reqMax = static_cast<uint64_t>(MTP_BUFFER_SIZE);
378     while (!DListIsEmpty(pool)) {
379         if (mtpDev->needZLP == ZLP_NO_NEED) {
380             if (mtpDev->asyncSendFileExpect >= mtpDev->xferFileLength) {
381                 return HDF_SUCCESS;
382             }
383         } else {
384             if (mtpDev->needZLP == ZLP_TRY) {
385                 return HDF_SUCCESS;
386             }
387         }
388         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
389         if (mtpDev->asyncSendFileExpect + reqMax < mtpDev->xferFileLength) {
390             req->length = static_cast<uint32_t>(MTP_BUFFER_SIZE);
391         } else {
392             req->length = static_cast<uint32_t>(mtpDev->xferFileLength - mtpDev->asyncSendFileExpect);
393         }
394         if (mtpDev->xferFileLength == mtpDev->asyncSendFileExpect) {
395             return UsbMtpPortProcessLastTxPacket(mtpPort, req);
396         }
397         int32_t ret = UsbMtpPortSubmitAsyncTxReq(mtpPort, req);
398         if (ret != HDF_SUCCESS) {
399             HDF_LOGE("%{public}s: submit bulk-in req error: %{public}d", __func__, ret);
400             sem_post(&asyncReq_);
401             return ret;
402         }
403         mtpDev->asyncSendFileExpect += static_cast<uint64_t>(req->length);
404     }
405     return HDF_SUCCESS;
406 }
407 
UsbMtpDeviceAllocCtrlRequests(int32_t num)408 int32_t UsbfnMtpImpl::UsbMtpDeviceAllocCtrlRequests(int32_t num)
409 {
410     struct DListHead *head = &mtpDev_->ctrlPool;
411     DListHeadInit(head);
412     mtpDev_->ctrlReqNum = 0;
413     for (int32_t i = 0; i < num; ++i) {
414         struct CtrlInfo *ctrlInfo = static_cast<struct CtrlInfo *>(OsalMemCalloc(sizeof(struct CtrlInfo)));
415         if (ctrlInfo == nullptr) {
416             HDF_LOGE("%{public}s: Allocate ctrlInfo failed", __func__);
417             return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
418         }
419         ctrlInfo->mtpDev = mtpDev_;
420         struct UsbFnRequest *req = UsbFnAllocCtrlRequest(mtpDev_->ctrlIface.handle, MTP_CONTROL_XFER_BYTECOUNT);
421         if (req == nullptr) {
422             HDF_LOGE("%{public}s: Allocate ctrl req failed", __func__);
423             (void)OsalMemFree(ctrlInfo);
424             return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
425         }
426         req->complete = UsbFnRequestCtrlComplete;
427         req->context = ctrlInfo;
428         DListInsertTail(&req->list, head);
429         mtpDev_->ctrlReqNum++;
430     }
431     return HDF_SUCCESS;
432 }
433 
UsbMtpDeviceFreeCtrlRequests()434 void UsbfnMtpImpl::UsbMtpDeviceFreeCtrlRequests()
435 {
436     struct DListHead *head = &mtpDev_->ctrlPool;
437     while (!DListIsEmpty(head)) {
438         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
439         if (req->list.prev != NULL && req->list.next != NULL) {
440             DListRemove(&req->list);
441         } else {
442             HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
443         }
444         (void)OsalMemFree(req->context);
445         (void)UsbFnFreeRequest(req);
446         mtpDev_->ctrlReqNum--;
447     }
448 }
449 
UsbMtpPortFreeRequests(struct DListHead * head,int32_t & allocated)450 void UsbfnMtpImpl::UsbMtpPortFreeRequests(struct DListHead *head, int32_t &allocated)
451 {
452     while (!DListIsEmpty(head)) {
453         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
454         if (req->list.prev != NULL && req->list.next != NULL) {
455             DListRemove(&req->list);
456         } else {
457             HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
458         }
459         (void)UsbFnFreeRequest(req);
460         allocated--;
461     }
462 }
463 
UsbMtpPortAllocReadWriteRequests(int32_t readSize,int32_t writeSize)464 int32_t UsbfnMtpImpl::UsbMtpPortAllocReadWriteRequests(int32_t readSize, int32_t writeSize)
465 {
466     struct UsbFnRequest *req = nullptr;
467     int32_t i = 0;
468     for (i = 0; i < readSize; ++i) {
469         req = UsbFnAllocRequest(mtpDev_->dataIface.handle, mtpDev_->dataOutPipe.id, MTP_BUFFER_SIZE);
470         if (req == nullptr) {
471             if (DListIsEmpty(&mtpPort_->readPool)) {
472                 HDF_LOGE("%{public}s: alloc read req failed", __func__);
473                 return HDF_ERR_MALLOC_FAIL;
474             }
475             break;
476         }
477         req->complete = UsbFnRequestReadComplete;
478         req->context = mtpPort_;
479         DListInsertTail(&req->list, &mtpPort_->readPool);
480         mtpPort_->readAllocated++;
481     }
482     mtpPort_->standbyReq = UsbFnAllocRequest(mtpDev_->dataIface.handle,
483         mtpDev_->dataOutPipe.id, MTP_BUFFER_SIZE);
484     if (mtpPort_->standbyReq == nullptr) {
485         HDF_LOGE("%{public}s: alloc standbyReq failed", __func__);
486         return HDF_ERR_MALLOC_FAIL;
487     }
488     mtpPort_->standbyReq->actual = REQ_ACTUAL_DEFAULT_LENGTH;
489     for (i = 0; i < writeSize; ++i) {
490         req = UsbFnAllocRequest(mtpDev_->dataIface.handle, mtpDev_->dataInPipe.id, MTP_BUFFER_SIZE);
491         if (req == nullptr) {
492             HDF_LOGE("%{public}s: alloc write req failed", __func__);
493             return HDF_ERR_MALLOC_FAIL;
494         }
495         req->complete = UsbFnRequestWriteComplete;
496         req->context = mtpPort_;
497         DListInsertTail(&req->list, &mtpPort_->writePool);
498         mtpPort_->writeAllocated++;
499     }
500     return HDF_SUCCESS;
501 }
502 
UsbMtpPortInitIo()503 int32_t UsbfnMtpImpl::UsbMtpPortInitIo()
504 {
505     int32_t ret = HDF_SUCCESS;
506     if (mtpPort_->readAllocated == 0 || mtpPort_->writeAllocated == 0) {
507         HDF_LOGI("%{public}s: rx_req=%{public}d tx_req=%{public}d, alloc req", __func__, mtpPort_->readAllocated,
508             mtpPort_->writeAllocated);
509         ret = UsbMtpPortAllocReadWriteRequests(READ_QUEUE_SIZE, WRITE_QUEUE_SIZE);
510         if (ret != HDF_SUCCESS) {
511             HDF_LOGE("%{public}s: allocate requests for read/write failed: %{public}d", __func__, ret);
512             UsbMtpPortFreeRequests(&mtpPort_->readPool, mtpPort_->readAllocated);
513             if (mtpPort_->standbyReq) {
514                 (void)UsbFnFreeRequest(mtpPort_->standbyReq);
515                 mtpPort_->standbyReq = NULL;
516             }
517             UsbMtpPortFreeRequests(&mtpPort_->writePool, mtpPort_->writeAllocated);
518             return HDF_ERR_MALLOC_FAIL;
519         }
520     }
521     return ret;
522 }
523 
UsbMtpPortCancelAndFreeReq(struct DListHead * queueHead,struct DListHead * poolHead,int32_t & allocated,bool freeReq)524 int32_t UsbfnMtpImpl::UsbMtpPortCancelAndFreeReq(
525     struct DListHead *queueHead, struct DListHead *poolHead, int32_t &allocated, bool freeReq)
526 {
527     while (!DListIsEmpty(queueHead)) {
528         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(queueHead, struct UsbFnRequest, list);
529         if (req->list.prev != NULL && req->list.next != NULL) {
530             DListRemove(&req->list);
531         } else {
532             HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
533         }
534         DListInsertTail(&req->list, poolHead);
535     }
536     while (!DListIsEmpty(poolHead)) {
537         struct UsbFnRequest *req = DLIST_FIRST_ENTRY(poolHead, struct UsbFnRequest, list);
538         if (req->list.prev != NULL && req->list.next != NULL) {
539             DListRemove(&req->list);
540         } else {
541             HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
542         }
543         (void)UsbFnCancelRequest(req);
544         if (freeReq) {
545             (void)UsbFnFreeRequest(req);
546         }
547         allocated--;
548     }
549     return HDF_SUCCESS;
550 }
551 
UsbMtpPortCancelPlusFreeIo(struct UsbMtpPort * mtpPort,bool freeReq)552 int32_t UsbfnMtpImpl::UsbMtpPortCancelPlusFreeIo(struct UsbMtpPort *mtpPort, bool freeReq)
553 {
554     if (mtpPort == nullptr) {
555         HDF_LOGE("%{public}s: mtpPort is null", __func__);
556         return HDF_ERR_INVALID_PARAM;
557     }
558     HDF_LOGI("%{public}s: cancel and free read req: %{public}d/%{public}d", __func__, mtpPort->readStarted,
559         mtpPort->readAllocated);
560     (void)UsbMtpPortCancelAndFreeReq(&mtpPort->readQueue, &mtpPort->readPool, mtpPort->readAllocated, freeReq);
561     HDF_LOGI("%{public}s: cancel and free write req: %{public}d/%{public}d", __func__, mtpPort->writeStarted,
562         mtpPort->writeAllocated);
563     (void)UsbMtpPortCancelAndFreeReq(&mtpPort->writeQueue, &mtpPort->writePool, mtpPort->writeAllocated, freeReq);
564 
565     if (mtpPort && mtpPort->standbyReq) {
566         (void)UsbFnCancelRequest(mtpPort->standbyReq);
567         (void)UsbFnFreeRequest(mtpPort->standbyReq);
568         mtpPort->standbyReq = NULL;
569     }
570     return HDF_SUCCESS;
571 }
572 
UsbMtpPortCancelRequest(struct UsbMtpPort * mtpPort)573 int32_t UsbfnMtpImpl::UsbMtpPortCancelRequest(struct UsbMtpPort *mtpPort)
574 {
575     DListHead *queueHead = &(mtpPort->readQueue);
576     if (!DListIsEmpty(queueHead)) {
577         HDF_LOGD("%{public}s: readQueue is not empty", __func__);
578         struct UsbFnRequest *queueReq = nullptr;
579         struct UsbFnRequest *queueReqTmp = nullptr;
580         DLIST_FOR_EACH_ENTRY_SAFE(queueReq, queueReqTmp, queueHead, struct UsbFnRequest, list) {
581             (void)UsbFnCancelRequest(queueReq);
582             HDF_LOGD("%{public}s:cancel read", __func__);
583         }
584     }
585     DListHead *writeQueue = &(mtpPort->writeQueue);
586     if (!DListIsEmpty(writeQueue)) {
587         HDF_LOGD("%{public}s: writeQueue is not empty", __func__);
588         struct UsbFnRequest *queueReq = nullptr;
589         struct UsbFnRequest *queueReqTmp = nullptr;
590         DLIST_FOR_EACH_ENTRY_SAFE(queueReq, queueReqTmp, writeQueue, struct UsbFnRequest, list) {
591             (void)UsbFnCancelRequest(queueReq);
592             HDF_LOGD("%{public}s:cancel write", __func__);
593         }
594     }
595 
596     if (mtpPort->mtpDev != NULL && mtpPort->mtpDev->notifyReq != NULL) {
597         struct UsbFnRequest *notifyReq = mtpPort->mtpDev->notifyReq;
598         (void)UsbFnCancelRequest(notifyReq);
599         HDF_LOGD("%{public}s:cancel notifyReq", __func__);
600     }
601     return HDF_SUCCESS;
602 }
603 
UsbMtpPortReleaseIo()604 int32_t UsbfnMtpImpl::UsbMtpPortReleaseIo()
605 {
606     return UsbMtpPortCancelPlusFreeIo(mtpPort_, true);
607 }
608 
UsbMtpDeviceGetCtrlReq(struct UsbMtpDevice * mtpDev)609 struct UsbFnRequest *UsbfnMtpImpl::UsbMtpDeviceGetCtrlReq(struct UsbMtpDevice *mtpDev)
610 {
611     struct DListHead *pool = &mtpDev->ctrlPool;
612     if (DListIsEmpty(pool)) {
613         return nullptr;
614     }
615     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
616     if (req->list.prev != NULL && req->list.next != NULL) {
617         DListRemove(&req->list);
618     } else {
619         HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
620     }
621     return req;
622 }
623 
UsbMtpDeviceStandardRequest(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup,struct UsbFnRequest * req)624 int32_t UsbfnMtpImpl::UsbMtpDeviceStandardRequest(
625     struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req)
626 {
627     uint16_t wValue = LE16_TO_CPU(setup->value);
628     int32_t responseBytes = 0;
629     uint8_t mtpOsStringReqType = (USB_DDK_DIR_IN | USB_DDK_TYPE_STANDARD | USB_DDK_RECIP_DEVICE);
630     /* wValue specified descriptor type(high 8 bit) and index(low 8 bit) when request is GET_DESCRIPTOR */
631     uint16_t mtpOsStringWValue = (USB_DDK_DT_STRING << 8 | USB_MTP_OS_STRING_ID);
632     if (setup->request == USB_DDK_REQ_GET_DESCRIPTOR && setup->reqType == mtpOsStringReqType &&
633         wValue == mtpOsStringWValue) {
634         /* Handle MTP OS string */
635         HDF_LOGI("%{public}s: Standard Request-Get Descriptor(String)", __func__);
636         responseBytes = (wValue < sizeof(g_mtpOsString)) ? wValue : sizeof(g_mtpOsString);
637         if (memcpy_s(req->buf, responseBytes, g_mtpOsString, responseBytes) != EOK) {
638             HDF_LOGE("%{public}s: memcpy_s failed: Get Descriptor", __func__);
639             return HDF_FAILURE;
640         }
641     } else {
642         HDF_LOGW("%{public}s: Standard Request-unknown: %{public}d", __func__, setup->request);
643     }
644     return responseBytes;
645 }
646 
UsbMtpDeviceClassRequest(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup,struct UsbFnRequest * req)647 int32_t UsbfnMtpImpl::UsbMtpDeviceClassRequest(
648     struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req)
649 {
650     int32_t responseBytes = 0;
651     if (setup->request == USB_MTP_REQ_CANCEL && setup->index == 0 && setup->value == 0) {
652         HDF_LOGI("%{public}s: Class Request-MTP_REQ_CANCEL", __func__);
653         if (mtpDev->mtpState == MTP_STATE_BUSY) {
654             mtpDev->mtpState = MTP_STATE_CANCELED;
655             DListHead *queueHead = &(mtpDev->mtpPort->readQueue);
656             if (!DListIsEmpty(queueHead)) {
657                 HDF_LOGD("%{public}s: readQueue is not empty", __func__);
658                 struct UsbFnRequest *queueReq = nullptr;
659                 struct UsbFnRequest *queueReqTmp = nullptr;
660                 DLIST_FOR_EACH_ENTRY_SAFE(queueReq, queueReqTmp, queueHead, struct UsbFnRequest, list) {
661                     (void)UsbFnCancelRequest(queueReq);
662                     HDF_LOGD("%{public}s:cancel read", __func__);
663                 }
664             }
665             DListHead *writeQueue = &(mtpDev->mtpPort->writeQueue);
666             if (!DListIsEmpty(writeQueue)) {
667                 HDF_LOGD("%{public}s: writeQueue is not empty", __func__);
668                 struct UsbFnRequest *queueReq = nullptr;
669                 struct UsbFnRequest *queueReqTmp = nullptr;
670                 DLIST_FOR_EACH_ENTRY_SAFE(queueReq, queueReqTmp, writeQueue, struct UsbFnRequest, list) {
671                     (void)UsbFnCancelRequest(queueReq);
672                     HDF_LOGD("%{public}s:cancel write", __func__);
673                 }
674             }
675             HDF_LOGD("%{public}s:async post, readStart:%{public}d", __func__, mtpDev->mtpPort->readStarted);
676             sem_post(&asyncReq_);
677         }
678     } else if (setup->request == USB_MTP_REQ_GET_DEVICE_STATUS && setup->index == 0 && setup->value == 0) {
679         HDF_LOGI("%{public}s: Class Request-MTP_REQ_GET_DEVICE_STATUS", __func__);
680         struct UsbMtpDeviceStatus mtpStatus;
681         mtpStatus.wLength = CPU_TO_LE16(sizeof(mtpStatus));
682         if (mtpDev->mtpState == MTP_STATE_CANCELED) {
683             mtpStatus.wCode = CPU_TO_LE16(MTP_RESPONSE_DEVICE_BUSY);
684         } else {
685             mtpStatus.wCode = CPU_TO_LE16(MTP_RESPONSE_OK);
686         }
687         responseBytes = static_cast<int32_t>(sizeof(mtpStatus));
688         if (memcpy_s(req->buf, responseBytes, &mtpStatus, responseBytes) != EOK) {
689             HDF_LOGE("%{public}s: memcpy_s failed: MTP_REQ_GET_DEVICE_STATUS", __func__);
690             return HDF_FAILURE;
691         }
692     } else {
693         HDF_LOGW("%{public}s: Class Request-UNKNOWN: %{public}d", __func__, setup->request);
694     }
695     return responseBytes;
696 }
697 
UsbMtpDeviceVendorRequest(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup,struct UsbFnRequest * req)698 int32_t UsbfnMtpImpl::UsbMtpDeviceVendorRequest(
699     struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup, struct UsbFnRequest *req)
700 {
701     uint16_t wIndex = LE16_TO_CPU(setup->index);
702     uint16_t wLength = LE16_TO_CPU(setup->length);
703     int32_t responseBytes = 0;
704     if (setup->request == USB_MTP_BMS_VENDORCODE && (setup->reqType & USB_DDK_DIR_IN) &&
705         (wIndex == USB_MTP_EXTENDED_COMPAT_ID || wIndex == USB_MTP_EXTENDED_PROPERTIES)) {
706         /* Handle MTP OS descriptor */
707         HDF_LOGI("%{public}s: Vendor Request-Get Descriptor(MTP OS)", __func__);
708         responseBytes = (wLength < sizeof(g_mtpExtConfigDesc)) ? wLength : sizeof(g_mtpExtConfigDesc);
709         if (memcpy_s(req->buf, responseBytes, &g_mtpExtConfigDesc, responseBytes) != EOK) {
710             HDF_LOGE("%{public}s: memcpy_s failed: Get Descriptor(MTP OS)", __func__);
711             return HDF_FAILURE;
712         }
713     } else {
714         HDF_LOGW("%{public}s: Vendor Request-UNKNOWN: %{public}d", __func__, setup->request);
715     }
716     return responseBytes;
717 }
718 
UsbMtpDeviceSetup(struct UsbMtpDevice * mtpDev,struct UsbFnCtrlRequest * setup)719 int32_t UsbfnMtpImpl::UsbMtpDeviceSetup(struct UsbMtpDevice *mtpDev, struct UsbFnCtrlRequest *setup)
720 {
721     if (mtpDev == nullptr || mtpDev->mtpPort == nullptr || setup == nullptr) {
722         return HDF_ERR_INVALID_PARAM;
723     }
724     HDF_LOGD(
725         "%{public}s: Setup: reqType=0x%{public}X, req=0x%{public}X, idx=%{public}d, val=%{public}d, len=%{public}d",
726         __func__, setup->reqType, setup->request, LE16_TO_CPU(setup->index), LE16_TO_CPU(setup->value),
727         LE16_TO_CPU(setup->length));
728 
729     struct UsbFnRequest *req = UsbMtpDeviceGetCtrlReq(mtpDev);
730     if (req == nullptr) {
731         HDF_LOGE("%{public}s: control req pool is empty", __func__);
732         return HDF_ERR_INVALID_PARAM;
733     }
734     int32_t responseBytes = 0;
735     switch (setup->reqType & USB_DDK_TYPE_MASK) {
736         case USB_DDK_TYPE_STANDARD:
737             responseBytes = UsbMtpDeviceStandardRequest(mtpDev, setup, req);
738             break;
739         case USB_DDK_TYPE_CLASS:
740             responseBytes = UsbMtpDeviceClassRequest(mtpDev, setup, req);
741             break;
742         case USB_DDK_TYPE_VENDOR:
743             responseBytes = UsbMtpDeviceVendorRequest(mtpDev, setup, req);
744             break;
745         default:
746             HDF_LOGW("%{public}s: Reserved Request: %{public}d", __func__, (setup->reqType & USB_DDK_TYPE_MASK));
747             break;
748     }
749 
750     struct CtrlInfo *ctrlInfo = static_cast<struct CtrlInfo *>(req->context);
751     ctrlInfo->request = setup->request;
752     ctrlInfo->mtpDev = mtpDev;
753     if (responseBytes >= 0) {
754         req->length = static_cast<uint32_t>(responseBytes);
755         int32_t ret = UsbFnSubmitRequestAsync(req);
756         if (ret != HDF_SUCCESS) {
757             HDF_LOGE("%{public}s: mtpDev send setup response error", __func__);
758             return ret;
759         }
760     }
761     return HDF_SUCCESS;
762 }
763 
UsbMtpDeviceSuspend(struct UsbMtpDevice * mtpDev)764 void UsbfnMtpImpl::UsbMtpDeviceSuspend(struct UsbMtpDevice *mtpDev)
765 {
766     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
767     if (mtpPort == nullptr) {
768         HDF_LOGE("%{public}s: invalid param", __func__);
769         return;
770     }
771     std::lock_guard<std::mutex> guard(asyncMutex_);
772     mtpPort->suspended = true;
773     (void)UsbMtpPortCancelRequest(mtpPort);
774 }
775 
UsbMtpDeviceResume(struct UsbMtpDevice * mtpDev)776 void UsbfnMtpImpl::UsbMtpDeviceResume(struct UsbMtpDevice *mtpDev)
777 {
778     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
779     if (mtpPort == nullptr) {
780         HDF_LOGE("%{public}s: invalid param", __func__);
781         return;
782     }
783     mtpPort->suspended = false;
784     if (!mtpPort->startDelayed) {
785         return;
786     }
787     mtpPort->startDelayed = false;
788 }
789 
UsbMtpDeviceEnable(struct UsbMtpDevice * mtpDev)790 int32_t UsbfnMtpImpl::UsbMtpDeviceEnable(struct UsbMtpDevice *mtpDev)
791 {
792     if (mtpDev == nullptr || !mtpDev->initFlag) {
793         HDF_LOGE("%{public}s: no init", __func__);
794         return HDF_DEV_ERR_DEV_INIT_FAIL;
795     }
796     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
797     if (mtpPort == nullptr) {
798         HDF_LOGE("%{public}s: no init", __func__);
799         return HDF_DEV_ERR_DEV_INIT_FAIL;
800     }
801 
802     /* the mtpDev is enabled, ready for transfer */
803     mtpDev->mtpState = MTP_STATE_READY;
804     mtpPort->startDelayed = true;
805     mtpPort->suspended = false;
806     return HDF_SUCCESS;
807 }
808 
UsbMtpDeviceDisable(struct UsbMtpDevice * mtpDev)809 int32_t UsbfnMtpImpl::UsbMtpDeviceDisable(struct UsbMtpDevice *mtpDev)
810 {
811     if (mtpDev == nullptr || !mtpDev->initFlag) {
812         HDF_LOGE("%{public}s: no init", __func__);
813         return HDF_DEV_ERR_DEV_INIT_FAIL;
814     }
815     struct UsbMtpPort *mtpPort = mtpDev->mtpPort;
816     if (mtpPort == nullptr) {
817         HDF_LOGE("%{public}s: no init", __func__);
818         return HDF_DEV_ERR_DEV_INIT_FAIL;
819     }
820 
821     /* Disable event: The USB Device Controller has been disabled due to some problem */
822     mtpPort->startDelayed = false;
823     mtpDev->mtpState = MTP_STATE_OFFLINE;
824     return HDF_SUCCESS;
825 }
826 
UsbMtpDeviceEp0EventDispatch(struct UsbFnEvent * event)827 void UsbfnMtpImpl::UsbMtpDeviceEp0EventDispatch(struct UsbFnEvent *event)
828 {
829     if (event == nullptr || event->context == nullptr) {
830         HDF_LOGE("%{public}s: invalid param event", __func__);
831         return;
832     }
833 
834     struct UsbMtpDevice *mtpDev = static_cast<struct UsbMtpDevice *>(event->context);
835     HDF_LOGI("%{public}s EP0 event: [%{public}d], state=%{public}hhu", __func__, event->type, mtpDev->mtpState);
836     switch (event->type) {
837         case USBFN_STATE_BIND:
838             HDF_LOGI("%{public}s: EP0 [bind] ignore", __func__);
839             break;
840         case USBFN_STATE_UNBIND:
841             HDF_LOGI("%{public}s: EP0 [unbind] ignore", __func__);
842             break;
843         case USBFN_STATE_ENABLE:
844             HDF_LOGI("%{public}s: EP0 [enable]", __func__);
845             (void)UsbMtpDeviceEnable(mtpDev);
846             break;
847         case USBFN_STATE_DISABLE:
848             HDF_LOGI("%{public}s: EP0 [disable]", __func__);
849             (void)UsbMtpDeviceDisable(mtpDev);
850             break;
851         case USBFN_STATE_SETUP:
852             HDF_LOGI("%{public}s: EP0 [setup]", __func__);
853             if (event->setup != nullptr) {
854                 (void)UsbMtpDeviceSetup(mtpDev, event->setup);
855             }
856             break;
857         case USBFN_STATE_SUSPEND:
858             HDF_LOGI("%{public}s: EP0 [suspend]", __func__);
859             UsbMtpDeviceSuspend(mtpDev);
860             break;
861         case USBFN_STATE_RESUME:
862             HDF_LOGI("%{public}s: EP0 [resume]", __func__);
863             UsbMtpDeviceResume(mtpDev);
864             break;
865         default:
866             HDF_LOGI("%{public}s: EP0 ignore or unknown: %{public}d", __func__, event->type);
867             break;
868     }
869 }
870 
CopyReqToStandbyReqPool(const struct UsbFnRequest * req,struct UsbFnRequest * standbyReq)871 void UsbfnMtpImpl::CopyReqToStandbyReqPool(const struct UsbFnRequest *req, struct UsbFnRequest *standbyReq)
872 {
873     if (req->actual < REQ_ACTUAL_MININUM_LENGTH || req->actual > REQ_ACTUAL_MAX_LENGTH) {
874         HDF_LOGE("%{public}s: actual: %{public}d", __func__, req->actual);
875         return;
876     }
877 
878     standbyReq->actual = req->actual;
879     standbyReq->type = req->type;
880     if (memcpy_s(standbyReq->buf, req->actual, req->buf, req->actual) != EOK) {
881         HDF_LOGE("%{public}s: memcpy_s failed", __func__);
882         return;
883     }
884 }
885 
UsbMtpDeviceParseEachPipe(struct UsbMtpInterface & iface)886 int32_t UsbfnMtpImpl::UsbMtpDeviceParseEachPipe(struct UsbMtpInterface &iface)
887 {
888     struct UsbFnInterface *fnIface = iface.fn;
889     if (fnIface == nullptr || fnIface->info.numPipes == 0) {
890         HDF_LOGE("%{public}s: ifce is invalid", __func__);
891         return HDF_ERR_INVALID_PARAM;
892     }
893     HDF_LOGI("%{public}s: interface: idx=%{public}hhu numPipes=%{public}hhu ifClass=%{public}hhu subclass=%{public}hhu "
894         "protocol=%{public}hhu cfgIndex=%{public}hhu", __func__, fnIface->info.index, fnIface->info.numPipes,
895         fnIface->info.interfaceClass, fnIface->info.subclass, fnIface->info.protocol, fnIface->info.configIndex);
896     uint32_t repetIdx = 0;
897     for (int32_t i = 0; i < fnIface->info.numPipes; ++i) {
898         struct UsbFnPipeInfo pipeInfo;
899         (void)memset_s(&pipeInfo, sizeof(pipeInfo), 0, sizeof(pipeInfo));
900         int32_t ret = UsbFnGetInterfacePipeInfo(fnIface, static_cast<uint8_t>(i), &pipeInfo);
901         if (ret != HDF_SUCCESS) {
902             HDF_LOGE("%{public}s: get pipe info error", __func__);
903             if (repetIdx < WAIT_UDC_MAX_LOOP) {
904                 usleep(WAIT_UDC_TIME);
905                 i--;
906             }
907             repetIdx++;
908             continue;
909         }
910         HDF_LOGI("%{public}s: pipe: id=%{public}d type=%{public}d dir=%{public}d max=%{public}d interval=%{public}d",
911             __func__, pipeInfo.id, pipeInfo.type, pipeInfo.dir, pipeInfo.maxPacketSize, pipeInfo.interval);
912         switch (pipeInfo.type) {
913             case USB_PIPE_TYPE_INTERRUPT:
914                 mtpDev_->notifyPipe.id = pipeInfo.id;
915                 mtpDev_->notifyPipe.maxPacketSize = pipeInfo.maxPacketSize;
916                 mtpDev_->ctrlIface = iface; /* MTP device only have one interface, record here */
917                 mtpDev_->intrIface = iface;
918                 break;
919             case USB_PIPE_TYPE_BULK:
920                 if (pipeInfo.dir == USB_PIPE_DIRECTION_IN) {
921                     mtpDev_->dataInPipe.id = pipeInfo.id;
922                     mtpDev_->dataInPipe.maxPacketSize = pipeInfo.maxPacketSize;
923                     mtpDev_->dataIface = iface;
924                 } else {
925                     mtpDev_->dataOutPipe.id = pipeInfo.id;
926                     mtpDev_->dataOutPipe.maxPacketSize = pipeInfo.maxPacketSize;
927                 }
928                 break;
929             default:
930                 HDF_LOGE("%{public}s: pipe type %{public}d don't support", __func__, pipeInfo.type);
931                 break;
932         }
933     }
934     return HDF_SUCCESS;
935 }
936 
UsbMtpDeviceParseMtpIface(struct UsbFnInterface * fnIface)937 int32_t UsbfnMtpImpl::UsbMtpDeviceParseMtpIface(struct UsbFnInterface *fnIface)
938 {
939     UsbFnInterfaceHandle handle = UsbFnOpenInterface(fnIface);
940     if (handle == nullptr) {
941         HDF_LOGE("%{public}s: open interface failed", __func__);
942         return HDF_ERR_INVALID_PARAM;
943     }
944     struct UsbMtpInterface iface;
945     iface.fn = fnIface;
946     iface.handle = handle;
947     int32_t ret = UsbMtpDeviceParseEachPipe(iface);
948     if (ret != HDF_SUCCESS) {
949         HDF_LOGE("%{public}s: parse each pipe failed", __func__);
950     }
951     return ret;
952 }
953 
UsbFnInterfaceIsUsbMtpPtpDevice(struct UsbFnInterface * iface)954 bool UsbfnMtpImpl::UsbFnInterfaceIsUsbMtpPtpDevice(struct UsbFnInterface *iface)
955 {
956     HDF_LOGI("%{public}s: iIf=%{public}d ifClass=%{public}d, subclass=%{public}d, protocol=%{public}d", __func__,
957         iface->info.configIndex, iface->info.interfaceClass, iface->info.subclass, iface->info.protocol);
958     if (iface->info.interfaceClass == USB_MTP_DEVICE_CLASS && iface->info.subclass == USB_MTP_DEVICE_SUBCLASS &&
959         iface->info.protocol == USB_MTP_DEVICE_PROTOCOL) {
960         HDF_LOGI("%{public}s: this is mtp device", __func__);
961         return true;
962     }
963     if (iface->info.interfaceClass == USB_PTP_DEVICE_CLASS && iface->info.subclass == USB_PTP_DEVICE_SUBCLASS &&
964         iface->info.protocol == USB_PTP_DEVICE_PROTOCOL) {
965         HDF_LOGI("%{public}s: this is ptp device", __func__);
966         return true;
967     }
968     return false;
969 }
970 
UsbMtpDeviceParseEachIface(struct UsbFnDevice * fnDev)971 int32_t UsbfnMtpImpl::UsbMtpDeviceParseEachIface(struct UsbFnDevice *fnDev)
972 {
973     for (int32_t i = 0; i < fnDev->numInterfaces; ++i) {
974         struct UsbFnInterface *fnIface = const_cast<struct UsbFnInterface *>(UsbFnGetInterface(fnDev, i));
975         if (fnIface == nullptr) {
976             HDF_LOGE("%{public}s: get interface failed: %{public}d/%{public}d", __func__, i, fnDev->numInterfaces);
977             return HDF_ERR_INVALID_PARAM;
978         }
979         if (UsbFnInterfaceIsUsbMtpPtpDevice(fnIface)) {
980             /* MTP/PTP device only have one interface, only parse once */
981             HDF_LOGI("%{public}s: found mtp/ptp interface: %{public}d/%{public}d", __func__, i, fnDev->numInterfaces);
982             (void)UsbMtpDeviceParseMtpIface(fnIface);
983             return HDF_SUCCESS;
984         }
985     }
986     return HDF_FAILURE;
987 }
988 
UsbMtpDeviceCreateFuncDevice()989 int32_t UsbfnMtpImpl::UsbMtpDeviceCreateFuncDevice()
990 {
991     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
992     if (iface == NULL) {
993         HDF_LOGE("%{public}s: DeviceResourceGetIfaceInstance failed", __func__);
994         return HDF_FAILURE;
995     }
996     const char *udcName = nullptr;
997     if (deviceObject_ != nullptr) {
998         if (iface->GetString(deviceObject_->property, "udc_name", &udcName, UDC_NAME) != HDF_SUCCESS) {
999             HDF_LOGE("%{public}s: read udc_name failed, use default: %{public}s", __func__, UDC_NAME);
1000             return HDF_ERR_INVALID_PARAM;
1001         }
1002     }
1003     struct UsbFnDevice *fnDev = nullptr;
1004     if (udcName != nullptr) {
1005         fnDev = const_cast<struct UsbFnDevice *>(UsbFnGetDevice(udcName));
1006     } else {
1007         HDF_LOGW("%{public}s: udcName invalid, use default", __func__);
1008         fnDev = const_cast<struct UsbFnDevice *>(UsbFnGetDevice(UDC_NAME));
1009     }
1010     if (fnDev == NULL) {
1011         HDF_LOGE("%{public}s: create usb function device failed", __func__);
1012         return HDF_DEV_ERR_DEV_INIT_FAIL;
1013     }
1014     HDF_LOGI("%{public}s: getDevice interface count=%{public}d", __func__, fnDev->numInterfaces);
1015     int32_t ret = UsbMtpDeviceParseEachIface(fnDev);
1016     if (ret != HDF_SUCCESS) {
1017         HDF_LOGE("%{public}s: get pipes failed", __func__);
1018         return ret;
1019     }
1020     mtpDev_->fnDev = fnDev;
1021     return HDF_SUCCESS;
1022 }
1023 
UsbMtpDeviceReleaseFuncDevice()1024 int32_t UsbfnMtpImpl::UsbMtpDeviceReleaseFuncDevice()
1025 {
1026     if (mtpDev_->fnDev == nullptr) {
1027         HDF_LOGE("%{public}s: fnDev is null", __func__);
1028         return HDF_ERR_INVALID_PARAM;
1029     }
1030     (void)UsbMtpDeviceFreeCtrlRequests();
1031     (void)UsbMtpDeviceFreeNotifyRequest();
1032     int32_t finalRet = HDF_SUCCESS;
1033     /* mtp/ptp have one interface include bulk/intr, ctrl is default, release once */
1034     int32_t ret = UsbFnCloseInterface(mtpDev_->ctrlIface.handle);
1035     if (ret != HDF_SUCCESS) {
1036         finalRet = ret;
1037         HDF_LOGW("%{public}s: close usb ctrl/bulk/intr interface failed", __func__);
1038     }
1039     ret = UsbFnStopRecvInterfaceEvent(mtpDev_->ctrlIface.fn);
1040     if (ret != HDF_SUCCESS) {
1041         finalRet = ret;
1042         HDF_LOGW("%{public}s: stop usb ep0 event handle failed", __func__);
1043     }
1044     return finalRet;
1045 }
1046 
UsbMtpDeviceAlloc()1047 int32_t UsbfnMtpImpl::UsbMtpDeviceAlloc()
1048 {
1049     struct UsbMtpPort *mtpPort = static_cast<struct UsbMtpPort *>(OsalMemCalloc(sizeof(struct UsbMtpPort)));
1050     if (mtpPort == nullptr) {
1051         HDF_LOGE("%{public}s: Alloc usb mtpDev mtpPort failed", __func__);
1052         return HDF_ERR_INVALID_PARAM;
1053     }
1054     mtpPort->isActive = false;
1055     DListHeadInit(&mtpPort->readPool);
1056     DListHeadInit(&mtpPort->readQueue);
1057     DListHeadInit(&mtpPort->writePool);
1058     DListHeadInit(&mtpPort->writeQueue);
1059     mtpDev_->mtpPort = mtpPort;
1060     mtpPort->mtpDev = mtpDev_;
1061     mtpPort_ = mtpPort;
1062     return HDF_SUCCESS;
1063 }
1064 
UsbMtpDeviceAllocNotifyRequest()1065 int32_t UsbfnMtpImpl::UsbMtpDeviceAllocNotifyRequest()
1066 {
1067     mtpDev_->notifyReq =
1068         UsbFnAllocRequest(mtpDev_->intrIface.handle, mtpDev_->notifyPipe.id, MTP_EVENT_PACKET_MAX_BYTES);
1069     if (mtpDev_->notifyReq == nullptr) {
1070         HDF_LOGE("%{public}s: allocate notify request failed", __func__);
1071         return HDF_ERR_INVALID_PARAM;
1072     }
1073     mtpDev_->notifyReq->complete = UsbFnRequestNotifyComplete;
1074     mtpDev_->notifyReq->context = mtpDev_;
1075     return HDF_SUCCESS;
1076 }
1077 
UsbMtpDeviceFreeNotifyRequest()1078 void UsbfnMtpImpl::UsbMtpDeviceFreeNotifyRequest()
1079 {
1080     int32_t ret = UsbFnFreeRequest(mtpDev_->notifyReq);
1081     if (ret != HDF_SUCCESS) {
1082         HDF_LOGE("%{public}s: free notify request failed", __func__);
1083         return;
1084     }
1085     mtpDev_->notifyReq = nullptr;
1086 }
1087 
UsbMtpDeviceFree()1088 int32_t UsbfnMtpImpl::UsbMtpDeviceFree()
1089 {
1090     if (mtpDev_->mtpPort == nullptr) {
1091         HDF_LOGE("%{public}s: invalid param", __func__);
1092         return HDF_ERR_INVALID_PARAM;
1093     }
1094     (void)OsalMemFree(mtpDev_->mtpPort);
1095     mtpDev_->mtpPort = nullptr;
1096     return HDF_SUCCESS;
1097 }
1098 
Init()1099 int32_t UsbfnMtpImpl::Init()
1100 {
1101     HDF_LOGI("%{public}s: Init", __func__);
1102     pthread_rwlock_wrlock(&mtpRunrwLock_);
1103     if (mtpDev_ != nullptr) {
1104         pthread_rwlock_unlock(&mtpRunrwLock_);
1105         HDF_LOGI("%{public}s: mtpDev_ is init success", __func__);
1106         return HDF_SUCCESS;
1107     }
1108     mtpDev_ = static_cast<struct UsbMtpDevice *>(OsalMemCalloc(sizeof(struct UsbMtpDevice)));
1109     if (mtpDev_ == nullptr) {
1110         pthread_rwlock_unlock(&mtpRunrwLock_);
1111         HDF_LOGE("%{public}s: usb mtpDev device failed or not initialized", __func__);
1112         return HDF_ERR_MALLOC_FAIL;
1113     }
1114     mtpDev_->initFlag = false;
1115     int32_t ret = UsbfnMtpImpl::UsbMtpDeviceCreateFuncDevice();
1116     if (ret != HDF_SUCCESS) {
1117         HDF_LOGE("%{public}s: UsbMtpDeviceCreateFuncDevice failed", __func__);
1118         (void)OsalMemFree(mtpDev_);
1119         mtpDev_ = nullptr;
1120         pthread_rwlock_unlock(&mtpRunrwLock_);
1121         return ret;
1122     }
1123     ret = InitMtpPort();
1124     if (ret != HDF_SUCCESS) {
1125         goto ERR;
1126     }
1127     mtpDev_->initFlag = true;
1128     pthread_rwlock_unlock(&mtpRunrwLock_);
1129     HDF_LOGI("%{public}s: Init success", __func__);
1130     return HDF_SUCCESS;
1131 ERR:
1132     (void)UsbMtpDeviceReleaseFuncDevice();
1133     (void)UsbMtpDeviceFree();
1134     (void)OsalMemFree(mtpDev_);
1135     mtpDev_ = nullptr;
1136     pthread_rwlock_unlock(&mtpRunrwLock_);
1137     return ret;
1138 }
1139 
InitMtpPort()1140 int32_t UsbfnMtpImpl::InitMtpPort()
1141 {
1142     /* init mtpPort */
1143     int32_t ret = UsbMtpDeviceAlloc();
1144     if (ret != HDF_SUCCESS) {
1145         HDF_LOGE("%{public}s: UsbMtpDeviceAlloc failed", __func__);
1146         return HDF_FAILURE;
1147     }
1148     ret = UsbMtpDeviceAllocCtrlRequests(MTP_CTRL_REQUEST_NUM);
1149     if (ret != HDF_SUCCESS) {
1150         HDF_LOGE("%{public}s: UsbMtpDeviceAllocCtrlRequests failed: %{public}d", __func__, MTP_CTRL_REQUEST_NUM);
1151         return HDF_FAILURE;
1152     }
1153     ret = UsbMtpDeviceAllocNotifyRequest();
1154     if (ret != HDF_SUCCESS) {
1155         HDF_LOGE("%{public}s: UsbMtpDeviceAllocNotifyRequest failed", __func__);
1156         return HDF_FAILURE;
1157     }
1158     ret = UsbFnStartRecvInterfaceEvent(mtpDev_->ctrlIface.fn, 0xff, UsbMtpDeviceEp0EventDispatch, mtpDev_);
1159     if (ret != HDF_SUCCESS) {
1160         HDF_LOGE("%{public}s: register event callback failed", __func__);
1161         return HDF_FAILURE;
1162     }
1163     return HDF_SUCCESS;
1164 }
1165 
Release()1166 int32_t UsbfnMtpImpl::Release()
1167 {
1168     HDF_LOGI("%{public}s: Release", __func__);
1169     pthread_rwlock_rdlock(&mtpRunrwLock_);
1170     if (mtpPort_ == nullptr || mtpDev_ == nullptr) {
1171         pthread_rwlock_unlock(&mtpRunrwLock_);
1172         HDF_LOGE("%{public}s: no init", __func__);
1173         return HDF_DEV_ERR_DEV_INIT_FAIL;
1174     }
1175     mtpDev_->initFlag = false;
1176     sem_post(&asyncReq_);
1177     {
1178         std::lock_guard<std::mutex> guard(asyncMutex_);
1179         (void)UsbMtpPortCancelRequest(mtpPort_);
1180     }
1181     pthread_rwlock_unlock(&mtpRunrwLock_);
1182     pthread_rwlock_wrlock(&mtpRunrwLock_);
1183     if (mtpPort_ == nullptr || mtpDev_ == nullptr) {
1184         pthread_rwlock_unlock(&mtpRunrwLock_);
1185         HDF_LOGE("%{public}s: no init", __func__);
1186         return HDF_DEV_ERR_DEV_INIT_FAIL;
1187     }
1188     (void)UsbMtpPortReleaseIo();
1189     int32_t ret = UsbMtpDeviceReleaseFuncDevice();
1190     if (ret != HDF_SUCCESS) {
1191         pthread_rwlock_unlock(&mtpRunrwLock_);
1192         HDF_LOGE("%{public}s: release device failed: %{public}d", __func__, ret);
1193         return ret;
1194     }
1195     ret = UsbMtpDeviceFree();
1196     if (ret != HDF_SUCCESS) {
1197         pthread_rwlock_unlock(&mtpRunrwLock_);
1198         HDF_LOGE("%{public}s: free device failed: %{public}d", __func__, ret);
1199         return ret;
1200     }
1201     (void)OsalMemFree(mtpDev_);
1202     mtpDev_ = nullptr;
1203     pthread_rwlock_unlock(&mtpRunrwLock_);
1204     HDF_LOGI("%{public}s: Release success", __func__);
1205     return HDF_SUCCESS;
1206 }
1207 
Start()1208 int32_t UsbfnMtpImpl::Start()
1209 {
1210     HDF_LOGI("%{public}s: start", __func__);
1211     pthread_rwlock_rdlock(&mtpRunrwLock_);
1212     if (mtpPort_ == nullptr || mtpDev_ == nullptr || !mtpDev_->initFlag) {
1213         pthread_rwlock_unlock(&mtpRunrwLock_);
1214         HDF_LOGE("%{public}s: no init", __func__);
1215         return HDF_DEV_ERR_DEV_INIT_FAIL;
1216     }
1217     if (mtpPort_->isActive) {
1218         sem_post(&asyncReq_);
1219         (void)UsbMtpPortCancelRequest(mtpPort_);
1220         pthread_rwlock_unlock(&mtpRunrwLock_);
1221         HDF_LOGI("%{public}s: is active end", __func__);
1222         return HDF_SUCCESS;
1223     }
1224     pthread_rwlock_unlock(&mtpRunrwLock_);
1225 
1226     pthread_rwlock_wrlock(&mtpRunrwLock_);
1227     std::lock_guard<std::mutex> guard(startMutex_);
1228     mtpDev_->mtpState = MTP_STATE_READY;
1229     mtpPort_->startDelayed = true;
1230     mtpPort_->isActive = true;
1231     int32_t ret = UsbMtpPortInitIo();
1232     pthread_rwlock_unlock(&mtpRunrwLock_);
1233     HDF_LOGI("%{public}s: end", __func__);
1234     return ret;
1235 }
1236 
Stop()1237 int32_t UsbfnMtpImpl::Stop()
1238 {
1239     HDF_LOGI("%{public}s: start", __func__);
1240     pthread_rwlock_rdlock(&mtpRunrwLock_);
1241     if (mtpPort_ == nullptr) {
1242         pthread_rwlock_unlock(&mtpRunrwLock_);
1243         HDF_LOGE("%{public}s: no init", __func__);
1244         return HDF_DEV_ERR_DEV_INIT_FAIL;
1245     }
1246     sem_post(&asyncReq_);
1247     (void)UsbMtpPortCancelRequest(mtpPort_);
1248     pthread_rwlock_unlock(&mtpRunrwLock_);
1249 
1250     pthread_rwlock_wrlock(&mtpRunrwLock_);
1251     std::lock_guard<std::mutex> guard(startMutex_);
1252     (void)UsbMtpPortReleaseIo();
1253     mtpPort_->startDelayed = false;
1254     mtpPort_->isActive = false;
1255     if (mtpDev_ != nullptr) {
1256         mtpDev_->mtpState = MTP_STATE_OFFLINE;
1257     }
1258     pthread_rwlock_unlock(&mtpRunrwLock_);
1259     HDF_LOGI("%{public}s: end", __func__);
1260     return HDF_SUCCESS;
1261 }
1262 
BufCopyToVector(void * buf,uint32_t bufSize,std::vector<uint8_t> & vectorData)1263 uint32_t UsbfnMtpImpl::BufCopyToVector(void *buf, uint32_t bufSize, std::vector<uint8_t> &vectorData)
1264 {
1265     uint8_t *addr = static_cast<uint8_t *>(buf);
1266     vectorData.assign(addr, addr + bufSize);
1267     return bufSize;
1268 }
1269 
BufCopyFromVector(void * buf,uint32_t bufSize,const std::vector<uint8_t> & vectorData,uint32_t vectorOffset)1270 uint32_t UsbfnMtpImpl::BufCopyFromVector(
1271     void *buf, uint32_t bufSize, const std::vector<uint8_t> &vectorData, uint32_t vectorOffset)
1272 {
1273     uint32_t count = (bufSize + vectorOffset) < vectorData.size() ? bufSize : vectorData.size() - vectorOffset;
1274     uint8_t *addr = static_cast<uint8_t *>(buf);
1275     for (size_t i = 0; i < count; i++) {
1276         addr[i] = vectorData.at(vectorOffset + i);
1277     }
1278     return count;
1279 }
1280 
Read(std::vector<uint8_t> & data)1281 int32_t UsbfnMtpImpl::Read(std::vector<uint8_t> &data)
1282 {
1283     pthread_rwlock_rdlock(&mtpRunrwLock_);
1284     if (mtpPort_ == nullptr || mtpDev_ == nullptr || !mtpDev_->initFlag) {
1285         pthread_rwlock_unlock(&mtpRunrwLock_);
1286         HDF_LOGE("%{public}s: no init", __func__);
1287         return HDF_DEV_ERR_DEV_INIT_FAIL;
1288     }
1289 
1290     if (mtpDev_->mtpState == MTP_STATE_OFFLINE || mtpDev_->mtpPort == nullptr || mtpDev_->mtpPort->suspended) {
1291         pthread_rwlock_unlock(&mtpRunrwLock_);
1292         HDF_LOGE("%{public}s: device disconnect, no-operation, mtpState is %{public}u", __func__, mtpDev_->mtpState);
1293         return HDF_DEV_ERR_NO_DEVICE;
1294     }
1295     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1296         mtpDev_->mtpState = MTP_STATE_READY;
1297         pthread_rwlock_unlock(&mtpRunrwLock_);
1298         HDF_LOGE("%{public}s: states is ecanceled", __func__);
1299         return HDF_ERROR_ECANCEL;
1300     }
1301     std::lock_guard<std::mutex> guard(readMutex_);
1302     if (!mtpDev_->initFlag) {
1303         pthread_rwlock_unlock(&mtpRunrwLock_);
1304         HDF_LOGE("%{public}s: dev is release", __func__);
1305         return HDF_DEV_ERR_DEV_INIT_FAIL;
1306     }
1307     mtpDev_->mtpState = MTP_STATE_BUSY;
1308     int32_t ret = ReadImpl(data);
1309     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1310         HDF_LOGE("%{public}s: running, states is ecanceled", __func__);
1311         ret = HDF_ERROR_ECANCEL;
1312     } else if (mtpDev_->mtpState != MTP_STATE_OFFLINE) {
1313         mtpDev_->mtpState = MTP_STATE_READY;
1314     }
1315     writeActualLen_ = 0;
1316     vectorSplited_.clear();
1317     pthread_rwlock_unlock(&mtpRunrwLock_);
1318     return ret;
1319 }
1320 
ReadZLP(uint32_t length,uint32_t actual)1321 void UsbfnMtpImpl::ReadZLP(uint32_t length, uint32_t actual)
1322 {
1323     if (actual != length || actual != MTP_BUFFER_SIZE) {
1324         return;
1325     }
1326     struct DListHead *pool = &mtpPort_->readPool;
1327     if (pool == nullptr || DListIsEmpty(pool)) {
1328         HDF_LOGE("%{public}s: invalid readPool", __func__);
1329         return;
1330     }
1331     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1332     if (req == nullptr) {
1333         HDF_LOGE("%{public}s: req invalid", __func__);
1334         return;
1335     }
1336     RemoveReqFromList(req);
1337     DListInsertTail(&req->list, &mtpPort_->readQueue);
1338     req->length = ZERO_LENGTH_PACKET;
1339     (void)UsbFnSubmitRequestSync(req, ZERO_LENGTH_PACKET_JIFFIES);
1340     RemoveReqFromList(req);
1341     DListInsertTail(&req->list, pool);
1342 }
1343 
ReadImpl(std::vector<uint8_t> & data)1344 int32_t UsbfnMtpImpl::ReadImpl(std::vector<uint8_t> &data)
1345 {
1346     int32_t ret = HDF_FAILURE;
1347     struct UsbFnRequest *req = nullptr;
1348     if (mtpPort_->standbyReq != nullptr && mtpPort_->standbyReq->actual >= REQ_ACTUAL_MININUM_LENGTH) {
1349         req = mtpPort_->standbyReq;
1350     } else {
1351         struct DListHead *pool = &mtpPort_->readPool;
1352         if (pool == nullptr || DListIsEmpty(pool)) {
1353             HDF_LOGE("%{public}s: invalid readPool", __func__);
1354             return HDF_DEV_ERR_DEV_INIT_FAIL;
1355         }
1356         req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1357         if (req == nullptr) {
1358             HDF_LOGE("%{public}s: req invalid", __func__);
1359             return HDF_DEV_ERR_DEV_INIT_FAIL;
1360         }
1361         RemoveReqFromList(req);
1362         DListInsertTail(&req->list, &mtpPort_->readQueue);
1363         req->length = static_cast<uint32_t>(MTP_BUFFER_SIZE);
1364         ret = UsbFnSubmitRequestSync(req, BULK_OUT_TIMEOUT_JIFFIES);
1365         RemoveReqFromList(req);
1366         DListInsertTail(&req->list, pool);
1367         if (ret != HDF_SUCCESS) {
1368             HDF_LOGE("%{public}s: send bulk-out sync req failed: %{public}d", __func__, ret);
1369             return ret;
1370         }
1371     }
1372 
1373     switch (req->status) {
1374         case USB_REQUEST_COMPLETED:
1375             (void)BufCopyToVector(req->buf, req->actual, data);
1376             ReadZLP(req->length, getActualLength(data));
1377             break;
1378         case USB_REQUEST_NO_DEVICE:
1379             HDF_LOGE("%{public}s: device disconnect", __func__);
1380             mtpDev_->mtpState = MTP_STATE_OFFLINE;
1381             ret = HDF_DEV_ERR_NO_DEVICE;
1382             break;
1383         default:
1384             HDF_LOGE("%{public}s: unexpected status %{public}d", __func__, req->status);
1385             ret = HDF_ERR_IO;
1386             break;
1387     }
1388     req->actual = REQ_ACTUAL_DEFAULT_LENGTH;
1389     return ret;
1390 }
1391 
WriteEx(const std::vector<uint8_t> & data,uint8_t needZLP,uint32_t & xferActual)1392 int32_t UsbfnMtpImpl::WriteEx(const std::vector<uint8_t> &data, uint8_t needZLP, uint32_t &xferActual)
1393 {
1394     struct DListHead *pool = &mtpPort_->writePool;
1395     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1396     RemoveReqFromList(req);
1397     DListInsertTail(&req->list, &mtpPort_->writeQueue);
1398     uint32_t needXferCount = data.size();
1399     int32_t ret = HDF_SUCCESS;
1400     while (needXferCount > 0 || needZLP == ZLP_NEED) {
1401         req->actual = 0;
1402         uint32_t reqMax = static_cast<uint32_t>(MTP_BUFFER_SIZE);
1403         req->length = reqMax > needXferCount ? needXferCount : reqMax;
1404         if (needXferCount == 0) {
1405             needZLP = ZLP_TRY;
1406             req->length = 0;
1407         }
1408         if (mtpDev_->mtpState != MTP_STATE_BUSY) {
1409             ret = HDF_ERR_IO;
1410             break;
1411         }
1412         (void)BufCopyFromVector(req->buf, req->length, data, xferActual);
1413         ret = UsbFnSubmitRequestSync(req, BULK_IN_TIMEOUT_JIFFIES);
1414         if (needZLP == ZLP_TRY) {
1415             HDF_LOGE("%{public}s: send zero packet done: %{public}d", __func__, ret);
1416             break;
1417         }
1418         switch (req->status) {
1419             case USB_REQUEST_COMPLETED:
1420                 needXferCount -= req->actual;
1421                 xferActual += req->actual;
1422                 break;
1423             case USB_REQUEST_NO_DEVICE:
1424                 HDF_LOGE("%{public}s: device disconnected", __func__);
1425                 mtpDev_->mtpState = MTP_STATE_OFFLINE;
1426                 ret = HDF_DEV_ERR_NO_DEVICE;
1427                 break;
1428             default:
1429                 HDF_LOGE("%{public}s: unexpected status %{public}d", __func__, req->status);
1430                 ret = HDF_ERR_IO;
1431                 break;
1432         }
1433         if (ret != HDF_SUCCESS) {
1434             HDF_LOGE("%{public}s: bulk-in req failed: %{public}d", __func__, ret);
1435             break;
1436         }
1437     }
1438     RemoveReqFromList(req);
1439     DListInsertTail(&req->list, pool);
1440     return ret;
1441 }
1442 
getActualLength(const std::vector<uint8_t> & data)1443 uint32_t UsbfnMtpImpl::getActualLength(const std::vector<uint8_t> &data)
1444 {
1445     if (data.size() < MTP_PROTOCOL_PACKET_SIZE) {
1446         return data.size();
1447     }
1448     uint32_t length;
1449     std::copy(data.data(), data.data() + MTP_PROTOCOL_PACKET_SIZE,
1450 	    reinterpret_cast<uint8_t*>(&length));
1451     return length;
1452 }
1453 
WriteSplitPacket(const std::vector<uint8_t> & data)1454 int32_t UsbfnMtpImpl::WriteSplitPacket(const std::vector<uint8_t> &data)
1455 {
1456     if (data.size() > WRITE_SPLIT_MININUM_LENGTH && writeActualLen_ == 0) {
1457         uint32_t writeLen = getActualLength(data);
1458         if (writeLen > data.size()) {
1459             vectorSplited_.resize(writeLen);
1460             std::copy(data.begin(), data.end(), vectorSplited_.begin());
1461             writeActualLen_ = data.size();
1462             return HDF_SUCCESS;
1463         }
1464     }
1465     if (vectorSplited_.size() > WRITE_SPLIT_MININUM_LENGTH &&
1466         (data.size() < vectorSplited_.size() - writeActualLen_)) {
1467         std::copy(data.begin(), data.end(), vectorSplited_.begin() + writeActualLen_);
1468         writeActualLen_ += data.size();
1469         return HDF_SUCCESS;
1470     } else if (vectorSplited_.size() > WRITE_SPLIT_MININUM_LENGTH &&
1471         (data.size() > vectorSplited_.size() - writeActualLen_)) {
1472         vectorSplited_.clear();
1473         writeActualLen_ = 0;
1474         return HDF_ERR_INVALID_PARAM;
1475     } else if (vectorSplited_.size() > WRITE_SPLIT_MININUM_LENGTH &&
1476         (data.size() == vectorSplited_.size() - writeActualLen_)) {
1477         std::copy(data.begin(), data.end(), vectorSplited_.begin() + writeActualLen_);
1478         writeActualLen_ += data.size();
1479     }
1480 
1481     std::lock_guard<std::mutex> guard(writeMutex_);
1482     if (DListIsEmpty(&mtpPort_->writePool) || !mtpDev_->initFlag) {
1483         return HDF_DEV_ERR_DEV_INIT_FAIL;
1484     }
1485     mtpDev_->mtpState = MTP_STATE_BUSY;
1486     uint32_t xferActual = 0;
1487     uint8_t needZLP = ZLP_NO_NEED;
1488     uint32_t needXferCount = vectorSplited_.size() > WRITE_SPLIT_MININUM_LENGTH ?
1489         vectorSplited_.size() : data.size();
1490     if ((needXferCount & (mtpDev_->dataInPipe.maxPacketSize - 1)) == 0) {
1491         needZLP = ZLP_NEED;
1492     }
1493     int32_t ret = HDF_FAILURE;
1494     if (writeActualLen_ > WRITE_SPLIT_MININUM_LENGTH &&
1495         vectorSplited_.size() == writeActualLen_) {
1496         ret = WriteEx(vectorSplited_, needZLP, xferActual);
1497         vectorSplited_.clear();
1498         writeActualLen_ = 0;
1499     } else {
1500         ret = WriteEx(data, needZLP, xferActual);
1501     }
1502     return ret;
1503 }
1504 
Write(const std::vector<uint8_t> & data)1505 int32_t UsbfnMtpImpl::Write(const std::vector<uint8_t> &data)
1506 {
1507     pthread_rwlock_rdlock(&mtpRunrwLock_);
1508     if (mtpPort_ == nullptr || mtpDev_ == nullptr || !mtpDev_->initFlag) {
1509         pthread_rwlock_unlock(&mtpRunrwLock_);
1510         HDF_LOGE("%{public}s: no init", __func__);
1511         return HDF_DEV_ERR_DEV_INIT_FAIL;
1512     }
1513 
1514     if (mtpDev_->mtpState == MTP_STATE_OFFLINE || mtpDev_->mtpPort == nullptr || mtpDev_->mtpPort->suspended) {
1515         pthread_rwlock_unlock(&mtpRunrwLock_);
1516         HDF_LOGE("%{public}s: device disconnect", __func__);
1517         return HDF_DEV_ERR_NO_DEVICE;
1518     }
1519     if (data.size() == 0) {
1520         pthread_rwlock_unlock(&mtpRunrwLock_);
1521         HDF_LOGW("%{public}s: no data need to send", __func__);
1522         return HDF_SUCCESS;
1523     }
1524     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1525         mtpDev_->mtpState = MTP_STATE_READY;
1526         pthread_rwlock_unlock(&mtpRunrwLock_);
1527         HDF_LOGE("%{public}s: states is ecanceled", __func__);
1528         return HDF_ERROR_ECANCEL;
1529     }
1530     int32_t ret = WriteSplitPacket(data);
1531     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1532         HDF_LOGE("%{public}s: running, states is ecanceled", __func__);
1533         ret = HDF_ERROR_ECANCEL;
1534     } else if (mtpDev_->mtpState != MTP_STATE_OFFLINE) {
1535         mtpDev_->mtpState = MTP_STATE_READY;
1536     }
1537     pthread_rwlock_unlock(&mtpRunrwLock_);
1538     return ret;
1539 }
1540 
UsbMtpPortRxCheckReq(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req,bool & writeToFile)1541 int32_t UsbfnMtpImpl::UsbMtpPortRxCheckReq(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req, bool &writeToFile)
1542 {
1543     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1544     switch (req->status) {
1545         case USB_REQUEST_NO_DEVICE:
1546             mtpDev->mtpState = MTP_STATE_OFFLINE;
1547             HDF_LOGE("%{public}s: rx req return disconnected", __func__);
1548             return HDF_DEV_ERR_NO_DEVICE;
1549         case USB_REQUEST_COMPLETED:
1550             break;
1551         default:
1552             HDF_LOGE("%{public}s: unexpected status %{public}d", __func__, req->status);
1553             return HDF_FAILURE;
1554     }
1555     if (req->actual == 0) {
1556         HDF_LOGD("%{public}s: recv ZLP packet, end xfer", __func__);
1557         mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1558         return HDF_SUCCESS;
1559     }
1560     if (mtpDev->xferFileLength == MTP_MAX_FILE_SIZE) {
1561         /* no specific length */
1562         writeToFile = true;
1563         if (req->actual < req->length) {
1564             /* short packet indicate transfer end */
1565             mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1566         }
1567         /* normal full packet, also write to file */
1568         return HDF_SUCCESS;
1569     }
1570     /* specific length */
1571     if (req->actual < req->length) {
1572         HDF_LOGE("%{public}s: normal packet(error): %{public}u < %{public}u", __func__, req->actual, req->length);
1573         return HDF_FAILURE;
1574     }
1575     if (req->actual != 0) {
1576         writeToFile = true;
1577     }
1578     if (mtpDev->asyncRecvFileActual + static_cast<uint64_t>(req->actual) == mtpDev->xferFileLength) {
1579         if (mtpDev->needZLP != ZLP_NEED) {
1580             mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1581         }
1582         HDF_LOGD("%{public}s: last packet: req(%{public}d/%{public}d)%{public}u/%{public}u, recv %{public}" PRIu64
1583             "/%{public}" PRIu64 "/%{public}" PRIu64 ",need zlp:%{public}d", __func__, mtpPort->readStarted,
1584             mtpPort->readAllocated, req->actual, req->length, mtpDev->asyncRecvFileExpect, mtpDev->asyncRecvFileActual,
1585             mtpDev->xferFileLength, mtpDev->needZLP);
1586     }
1587     return HDF_SUCCESS;
1588 }
1589 
UsbMtpPortProcessAsyncRxDone(struct UsbMtpPort * mtpPort)1590 int32_t UsbfnMtpImpl::UsbMtpPortProcessAsyncRxDone(struct UsbMtpPort *mtpPort)
1591 {
1592     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1593     HDF_LOGD("%{public}s: recv done, ignore other packet(%{public}d/%{public}d):%{public}" PRIu64 "/%{public}" PRIu64
1594         "/%{public}" PRIu64 "", __func__, mtpPort->readStarted, mtpPort->readAllocated, mtpDev->asyncRecvFileExpect,
1595         mtpDev->asyncRecvFileActual, mtpDev->xferFileLength);
1596     if (mtpPort->readStarted == 0) {
1597         sem_post(&asyncReq_);
1598     } else if (mtpDev->xferFileLength == MTP_MAX_FILE_SIZE) {
1599         HDF_LOGD("%{public}s: cancel redundant req", __func__);
1600         while (!DListIsEmpty(&mtpPort->readQueue)) {
1601             struct UsbFnRequest *req = DLIST_FIRST_ENTRY(&mtpPort->readQueue, struct UsbFnRequest, list);
1602             (void)UsbFnCancelRequest(req);
1603             if (req->list.prev != NULL && req->list.next != NULL) {
1604                 DListRemove(&req->list);
1605             } else {
1606                 HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
1607             }
1608             DListInsertTail(&req->list, &mtpPort->readPool);
1609         }
1610     }
1611     return HDF_SUCCESS;
1612 }
1613 
UsbMtpPortRxPush(struct UsbMtpPort * mtpPort,struct UsbFnRequest * req)1614 int32_t UsbfnMtpImpl::UsbMtpPortRxPush(struct UsbMtpPort *mtpPort, struct UsbFnRequest *req)
1615 {
1616     if (mtpPort == nullptr || mtpPort->mtpDev == nullptr) {
1617         HDF_LOGE("%{public}s: invalid param", __func__);
1618         return HDF_ERR_INVALID_PARAM;
1619     }
1620     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1621     bool writeToFile = false;
1622     int32_t ret = UsbMtpPortRxCheckReq(mtpPort, req, writeToFile);
1623     if (ret != HDF_SUCCESS) {
1624         HDF_LOGE("%{public}s: req failed: %{public}d", __func__, ret);
1625         sem_post(&asyncReq_);
1626         return HDF_ERR_IO;
1627     }
1628     if (writeToFile && mtpDev->asyncRecvWriteTempContent) {
1629         uint8_t *bufOff = mtpDev->asyncRecvWriteTempContent + mtpDev->asyncRecvWriteTempCount;
1630         if (memcpy_s(bufOff, req->actual, req->buf, req->actual) != EOK) {
1631             HDF_LOGE("%{public}s: memcpy_s failed", __func__);
1632             return HDF_FAILURE;
1633         }
1634         mtpDev->asyncRecvWriteTempCount += req->actual;
1635         if (mtpDev->asyncRecvWriteTempCount >= WRITE_FILE_TEMP_SLICE) {
1636             ssize_t writeRet = write(mtpDev->xferFd, static_cast<void *>(mtpDev->asyncRecvWriteTempContent),
1637                 static_cast<size_t>(WRITE_FILE_TEMP_SLICE));
1638             if (writeRet != static_cast<ssize_t>(WRITE_FILE_TEMP_SLICE)) {
1639                 HDF_LOGE("%{public}s: write temp failed: %{public}zd", __func__, writeRet);
1640                 mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1641                 sem_post(&asyncReq_);
1642                 return HDF_FAILURE;
1643             }
1644             mtpDev->asyncRecvWriteTempCount = 0;
1645         }
1646         mtpDev->asyncRecvFileActual += static_cast<uint64_t>(req->actual);
1647     }
1648     if (mtpDev->asyncXferFile == ASYNC_XFER_FILE_DONE) {
1649         ssize_t writeRet = write(mtpDev->xferFd, static_cast<void *>(mtpDev->asyncRecvWriteTempContent),
1650             static_cast<size_t>(mtpDev->asyncRecvWriteTempCount));
1651         if (writeRet != static_cast<ssize_t>(mtpDev->asyncRecvWriteTempCount)) {
1652             HDF_LOGE("%{public}s: write last failed: %{public}d", __func__, mtpDev->asyncRecvWriteTempCount);
1653             mtpDev->asyncXferFile = ASYNC_XFER_FILE_DONE;
1654             sem_post(&asyncReq_);
1655             return HDF_FAILURE;
1656         }
1657         return UsbMtpPortProcessAsyncRxDone(mtpPort);
1658     }
1659     if ((mtpDev->xferFileLength == MTP_MAX_FILE_SIZE) || (mtpDev->asyncRecvFileActual == mtpDev->xferFileLength) ||
1660         (mtpDev->xferFileLength != MTP_MAX_FILE_SIZE && mtpDev->asyncRecvFileExpect != mtpDev->xferFileLength)) {
1661         ret = UsbMtpPortStartRxAsync(mtpPort);
1662     }
1663     return ret;
1664 }
1665 
UsbMtpPortStartSubmitRxReq(struct UsbMtpPort * mtpPort,bool needZLP)1666 int32_t UsbfnMtpImpl::UsbMtpPortStartSubmitRxReq(struct UsbMtpPort *mtpPort, bool needZLP)
1667 {
1668     struct DListHead *pool = &mtpPort->readPool;
1669     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1670     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1671     uint64_t reqMax = static_cast<uint64_t>(MTP_BUFFER_SIZE);
1672     if (mtpDev->asyncRecvFileExpect + reqMax < mtpDev->xferFileLength) {
1673         req->length = static_cast<uint32_t>(MTP_BUFFER_SIZE);
1674     } else if (mtpDev->xferFileLength == MTP_MAX_FILE_SIZE) {
1675         req->length = static_cast<uint32_t>(MTP_BUFFER_SIZE);
1676     } else {
1677         req->length = static_cast<uint32_t>(mtpDev->xferFileLength - mtpDev->asyncRecvFileExpect);
1678     }
1679 
1680     if (needZLP) {
1681         req->length = 0;
1682     }
1683     RemoveReqFromList(req);
1684     DListInsertTail(&req->list, &mtpPort->readQueue);
1685     int32_t ret = UsbFnSubmitRequestAsync(req);
1686     if (ret != HDF_SUCCESS) {
1687         HDF_LOGE("%{public}s: submit bulk-out req error %{public}d", __func__, ret);
1688         if (req->list.prev != NULL && req->list.next != NULL) {
1689             DListRemove(&req->list);
1690         } else {
1691             HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
1692         }
1693         DListInsertTail(&req->list, pool);
1694         return ret;
1695     }
1696     mtpPort->readStarted++;
1697     mtpDev->asyncRecvFileExpect += static_cast<uint64_t>(req->length);
1698     return HDF_SUCCESS;
1699 }
1700 
UsbMtpPortStartRxAsync(struct UsbMtpPort * mtpPort)1701 int32_t UsbfnMtpImpl::UsbMtpPortStartRxAsync(struct UsbMtpPort *mtpPort)
1702 {
1703     std::lock_guard<std::mutex> guard(asyncMutex_);
1704     struct DListHead *pool = &mtpPort->readPool;
1705     struct UsbMtpDevice *mtpDev = mtpPort->mtpDev;
1706     int32_t ret = HDF_SUCCESS;
1707     while (!DListIsEmpty(pool)) {
1708         if (mtpPort->readStarted >= mtpPort->readAllocated) {
1709             HDF_LOGW("%{public}s no idle read req(BULK-OUT): %{public}d/%{public}d", __func__, mtpPort->readStarted,
1710                 mtpPort->readAllocated);
1711             ret = HDF_ERR_DEVICE_BUSY;
1712             break;
1713         }
1714         if (mtpDev->mtpState == MTP_STATE_OFFLINE) {
1715             HDF_LOGE("%{public}s: device disconnect, stop rx", __func__);
1716             ret = HDF_DEV_ERR_NO_DEVICE;
1717             break;
1718         }
1719         if (mtpDev->asyncRecvFileActual == mtpDev->xferFileLength) {
1720             HDF_LOGD("%{public}s: recv a zlp", __func__);
1721             return UsbMtpPortStartSubmitRxReq(mtpPort, true);
1722         }
1723         if ((mtpDev->xferFileLength != MTP_MAX_FILE_SIZE && mtpDev->asyncRecvFileExpect >= mtpDev->xferFileLength) ||
1724             mtpDev->asyncXferFile == ASYNC_XFER_FILE_DONE) {
1725             HDF_LOGD("%{public}s: no need rx req[%{public}d/%{public}d]:%{public}" PRIu64 "/%{public}" PRIu64
1726                 "/%{public}" PRIu64 ", xfer=%{public}hhu", __func__, mtpPort->readStarted, mtpPort->readAllocated,
1727                 mtpDev->asyncRecvFileExpect, mtpDev->asyncRecvFileActual, mtpDev->xferFileLength,
1728                 mtpDev->asyncXferFile);
1729             return ret;
1730         }
1731         ret = UsbMtpPortStartSubmitRxReq(mtpPort, false);
1732         if (ret != HDF_SUCCESS) {
1733             HDF_LOGE("%{public}s: submit bulk-out req error %{public}d", __func__, ret);
1734             break;
1735         }
1736     }
1737     return ret;
1738 }
1739 
ReceiveFileEx()1740 int32_t UsbfnMtpImpl::ReceiveFileEx()
1741 {
1742     sem_init(&asyncReq_, 1, 0);
1743     mtpDev_->asyncXferFile = ASYNC_XFER_FILE_NORMAL;
1744     mtpDev_->asyncRecvWriteTempContent = static_cast<uint8_t *>(OsalMemCalloc(WRITE_FILE_TEMP_SLICE));
1745     mtpDev_->asyncRecvWriteTempCount = 0;
1746     int32_t ret = UsbMtpPortStartRxAsync(mtpPort_);
1747     if (ret != HDF_SUCCESS) {
1748         HDF_LOGE("%{public}s: start async tx failed: %{public}d", __func__, ret);
1749         (void)OsalMemFree(mtpDev_->asyncRecvWriteTempContent);
1750         mtpDev_->asyncRecvWriteTempContent = nullptr;
1751         return HDF_ERR_IO;
1752     }
1753     HDF_LOGD("%{public}s: wait async rx", __func__);
1754     sem_wait(&asyncReq_);
1755     (void)OsalMemFree(mtpDev_->asyncRecvWriteTempContent);
1756     mtpDev_->asyncRecvWriteTempContent = nullptr;
1757     if (syncfs(mtpDev_->xferFd) != 0) {
1758         HDF_LOGE("%{public}s: failed: commit filesystem caches to disk", __func__);
1759         return HDF_ERR_IO;
1760     }
1761     if (mtpDev_->xferFileLength == MTP_MAX_FILE_SIZE) {
1762         HDF_LOGE("%{public}s: no specific length, reset state", __func__);
1763         mtpDev_->mtpState = MTP_STATE_READY;
1764         return mtpDev_->asyncXferFile == ASYNC_XFER_FILE_DONE ? HDF_SUCCESS : HDF_ERR_IO;
1765     }
1766     return mtpDev_->asyncRecvFileActual == mtpDev_->xferFileLength ? HDF_SUCCESS : HDF_ERR_IO;
1767 }
1768 
ReceiveFile(const UsbFnMtpFileSlice & mfs)1769 int32_t UsbfnMtpImpl::ReceiveFile(const UsbFnMtpFileSlice &mfs)
1770 {
1771     pthread_rwlock_rdlock(&mtpRunrwLock_);
1772     ON_SCOPE_EXIT(release) {
1773         pthread_rwlock_unlock(&mtpRunrwLock_);
1774         close(mfs.fd);
1775     };
1776     if (mtpPort_ == nullptr || mtpDev_ == nullptr || !mtpDev_->initFlag) {
1777         HDF_LOGE("%{public}s: no init", __func__);
1778         return HDF_DEV_ERR_DEV_INIT_FAIL;
1779     }
1780 
1781     if (mtpDev_->mtpState == MTP_STATE_OFFLINE || mtpDev_->mtpPort == nullptr || mtpDev_->mtpPort->suspended) {
1782         HDF_LOGE("%{public}s: device disconnect", __func__);
1783         return HDF_DEV_ERR_NO_DEVICE;
1784     }
1785     if (mfs.length <= 0) {
1786         return HDF_SUCCESS;
1787     }
1788     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1789         mtpDev_->mtpState = MTP_STATE_READY;
1790         HDF_LOGE("%{public}s: states is ecanceled", __func__);
1791         return HDF_ERROR_ECANCEL;
1792     }
1793     std::lock_guard<std::mutex> guard(readMutex_);
1794     if (!mtpDev_->initFlag) {
1795         HDF_LOGE("%{public}s: dev is release", __func__);
1796         return HDF_DEV_ERR_DEV_INIT_FAIL;
1797     }
1798     mtpDev_->mtpState = MTP_STATE_BUSY;
1799     mtpDev_->xferFd = mfs.fd;
1800     mtpDev_->xferFileOffset = mfs.offset;
1801     mtpDev_->xferFileLength = static_cast<uint64_t>(mfs.length);
1802     lseek(mfs.fd, mfs.offset, SEEK_SET);
1803     mtpDev_->asyncRecvFileActual = 0;
1804     mtpDev_->asyncRecvFileExpect = 0;
1805     mtpDev_->needZLP = ZLP_NO_NEED;
1806     if ((mtpDev_->xferFileLength & (mtpDev_->dataInPipe.maxPacketSize - 1)) == 0) {
1807         mtpDev_->needZLP = ZLP_NEED;
1808     }
1809     int32_t ret = ReceiveFileEx();
1810     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1811         HDF_LOGE("%{public}s: running, states is ecanceled", __func__);
1812         ret = HDF_ERROR_ECANCEL;
1813     } else if (mtpDev_->mtpState != MTP_STATE_OFFLINE) {
1814         mtpDev_->mtpState = MTP_STATE_READY;
1815     }
1816     return ret;
1817 }
1818 
UsbMtpPortSendFileFillFirstReq(struct UsbFnRequest * req,uint64_t & oneReqLeft)1819 int32_t UsbfnMtpImpl::UsbMtpPortSendFileFillFirstReq(struct UsbFnRequest *req, uint64_t &oneReqLeft)
1820 {
1821     uint64_t hdrSize = static_cast<uint64_t>((mtpDev_->xferSendHeader == 1) ? sizeof(struct UsbMtpDataHeader) : 0);
1822     uint64_t needXferCount = mtpDev_->xferFileLength + hdrSize;
1823     uint64_t reqMax = static_cast<uint64_t>(MTP_BUFFER_SIZE);
1824     req->length = (reqMax > needXferCount) ? static_cast<uint32_t>(needXferCount) : static_cast<uint32_t>(reqMax);
1825     if (hdrSize != 0) {
1826         /* write MTP header first */
1827         struct UsbMtpDataHeader *header = static_cast<struct UsbMtpDataHeader *>(req->buf);
1828         /* set file size with header according to MTP Specification v1.0 */
1829         header->length =
1830             static_cast<uint32_t>(needXferCount > MTP_MAX_FILE_SIZE ? MTP_MAX_FILE_SIZE : CPU_TO_LE32(needXferCount));
1831         /* type value 2 specified data packet */
1832         header->type = CPU_TO_LE16(2);
1833         header->cmdCode = CPU_TO_LE16(mtpDev_->xferCommand);
1834         header->transactionId = CPU_TO_LE32(mtpDev_->xferTransactionId);
1835     }
1836     uint8_t *bufOffset = static_cast<uint8_t *>(req->buf) + hdrSize;
1837     oneReqLeft = (hdrSize + mtpDev_->xferFileLength < reqMax) ? mtpDev_->xferFileLength : reqMax - hdrSize;
1838     ssize_t readRet = read(mtpDev_->xferFd, static_cast<void *>(bufOffset), static_cast<size_t>(oneReqLeft));
1839     if (readRet != static_cast<ssize_t>(oneReqLeft)) {
1840         HDF_LOGE("%{public}s: read failed: %{public}zd vs %{public}" PRId64 "", __func__, readRet, oneReqLeft);
1841         return HDF_FAILURE;
1842     }
1843     return HDF_SUCCESS;
1844 }
1845 
UsbMtpPortSendFileEx()1846 int32_t UsbfnMtpImpl::UsbMtpPortSendFileEx()
1847 {
1848     if (DListIsEmpty(&mtpPort_->writePool)) {
1849         HDF_LOGE("%{public}s: writePool is empty.", __func__);
1850         return HDF_DEV_ERR_NO_DEVICE;
1851     }
1852     struct DListHead *pool = &mtpPort_->writePool;
1853     struct UsbFnRequest *req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1854     if (req == nullptr) {
1855         HDF_LOGE("%{public}s: req invalid", __func__);
1856         return HDF_DEV_ERR_DEV_INIT_FAIL;
1857     }
1858     RemoveReqFromList(req);
1859     DListInsertTail(&req->list, &mtpPort_->writeQueue);
1860     uint64_t oneReqLeft = 0;
1861     int32_t ret = UsbMtpPortSendFileFillFirstReq(req, oneReqLeft);
1862     if (ret != HDF_SUCCESS) {
1863         HDF_LOGE("%{public}s: fill first sync bulk-in req failed: %{public}d", __func__, ret);
1864         DListInsertTail(&req->list, pool);
1865         return ret;
1866     }
1867     ret = UsbFnSubmitRequestSync(req, BULK_IN_TIMEOUT_JIFFIES);
1868     RemoveReqFromList(req);
1869     DListInsertTail(&req->list, pool);
1870     if (ret != HDF_SUCCESS) {
1871         HDF_LOGE("%{public}s: bulk-in req failed: %{public}d", __func__, ret);
1872         return ret;
1873     }
1874     switch (req->status) {
1875         case USB_REQUEST_COMPLETED:
1876             break;
1877         case USB_REQUEST_NO_DEVICE:
1878             HDF_LOGE("%{public}s: device disconnected", __func__);
1879             mtpDev_->mtpState = MTP_STATE_OFFLINE;
1880             return HDF_DEV_ERR_NO_DEVICE;
1881         default:
1882             HDF_LOGD("%{public}s: unexpected status %{public}d", __func__, req->status);
1883             return HDF_ERR_IO;
1884     }
1885     if (!mtpDev_->initFlag || mtpDev_->mtpState == MTP_STATE_CANCELED) {
1886         HDF_LOGE("%{public}s: dev is release or canceled", __func__);
1887         return HDF_DEV_ERR_DEV_INIT_FAIL;
1888     }
1889     if (oneReqLeft != mtpDev_->xferFileLength || mtpDev_->needZLP) {
1890         ret = UsbMtpPortSendFileLeftAsync(oneReqLeft);
1891     }
1892     return ret;
1893 }
1894 
UsbMtpPortSendFileLeftAsync(uint64_t oneReqLeft)1895 int32_t UsbfnMtpImpl::UsbMtpPortSendFileLeftAsync(uint64_t oneReqLeft)
1896 {
1897     mtpDev_->xferFileLength -= oneReqLeft;
1898     mtpDev_->asyncSendFileActual = 0;
1899     mtpDev_->asyncSendFileExpect = 0;
1900     sem_init(&asyncReq_, 1, 0);
1901     mtpDev_->asyncXferFile = ASYNC_XFER_FILE_NORMAL;
1902     if (UsbMtpPortStartTxAsync(mtpPort_, false) != HDF_SUCCESS) {
1903         HDF_LOGE("%{public}s: start async tx failed", __func__);
1904         return HDF_ERR_IO;
1905     }
1906     HDF_LOGD("%{public}s: wait async tx", __func__);
1907     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1908         HDF_LOGE("%{public}s: dev is canceled", __func__);
1909         return HDF_ERROR_ECANCEL;
1910     }
1911     sem_wait(&asyncReq_);
1912     return (mtpDev_->mtpState == MTP_STATE_ERROR) ? HDF_ERR_IO : HDF_SUCCESS;
1913 }
1914 
UsbMtpSendFileParamSet(const UsbFnMtpFileSlice & mfs)1915 void UsbfnMtpImpl::UsbMtpSendFileParamSet(const UsbFnMtpFileSlice &mfs)
1916 {
1917     mtpDev_->xferFd = mfs.fd;
1918     mtpDev_->xferFileOffset = static_cast<uint64_t>(mfs.offset);
1919     mtpDev_->xferFileLength = static_cast<uint64_t>(mfs.length);
1920     mtpDev_->xferCommand = mfs.command;
1921     mtpDev_->xferTransactionId = mfs.transactionId;
1922     mtpDev_->xferSendHeader = (mfs.command == 0 && mfs.transactionId == 0) ? 0 : 1;
1923     return;
1924 }
1925 
SendFile(const UsbFnMtpFileSlice & mfs)1926 int32_t UsbfnMtpImpl::SendFile(const UsbFnMtpFileSlice &mfs)
1927 {
1928     pthread_rwlock_rdlock(&mtpRunrwLock_);
1929     ON_SCOPE_EXIT(release) {
1930         pthread_rwlock_unlock(&mtpRunrwLock_);
1931         close(mfs.fd);
1932     };
1933     if (mtpPort_ == nullptr || mtpDev_ == nullptr || !mtpDev_->initFlag) {
1934         HDF_LOGE("%{public}s: no init", __func__);
1935         return HDF_DEV_ERR_DEV_INIT_FAIL;
1936     }
1937 
1938     UsbMtpSendFileParamSet(mfs);
1939     uint64_t hdrSize = (mtpDev_->xferSendHeader == 1) ? static_cast<uint64_t>(sizeof(struct UsbMtpDataHeader)) : 0;
1940     uint64_t needXferCount = mfs.length + hdrSize;
1941     lseek(mfs.fd, mfs.offset, SEEK_SET);
1942 
1943     if (needXferCount == 0 || mfs.length < 0) {
1944         HDF_LOGW("%{public}s: no data need to send", __func__);
1945         return HDF_SUCCESS;
1946     }
1947     if (mtpDev_->mtpState == MTP_STATE_OFFLINE || mtpDev_->mtpPort == nullptr || mtpDev_->mtpPort->suspended) {
1948         HDF_LOGE("%{public}s: device disconnect", __func__);
1949         return HDF_DEV_ERR_NO_DEVICE;
1950     }
1951     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1952         mtpDev_->mtpState = MTP_STATE_READY;
1953         HDF_LOGE("%{public}s: states is ecanceled", __func__);
1954         return HDF_ERROR_ECANCEL;
1955     }
1956     std::lock_guard<std::mutex> guard(writeMutex_);
1957     if (!mtpDev_->initFlag) {
1958         HDF_LOGE("%{public}s: dev is release", __func__);
1959         return HDF_DEV_ERR_DEV_INIT_FAIL;
1960     }
1961     mtpDev_->mtpState = MTP_STATE_BUSY;
1962     mtpDev_->needZLP = ZLP_NO_NEED;
1963     if ((needXferCount & (mtpDev_->dataInPipe.maxPacketSize - 1)) == 0) {
1964         mtpDev_->needZLP = ZLP_NEED;
1965     }
1966     int32_t ret = UsbMtpPortSendFileEx();
1967     if (mtpDev_->mtpState == MTP_STATE_CANCELED) {
1968         HDF_LOGE("%{public}s: running, states is ecanceled", __func__);
1969         ret = HDF_ERROR_ECANCEL;
1970     } else if (mtpDev_->mtpState != MTP_STATE_OFFLINE) {
1971         mtpDev_->mtpState = MTP_STATE_READY;
1972     }
1973     return ret;
1974 }
1975 
SendEvent(const std::vector<uint8_t> & eventData)1976 int32_t UsbfnMtpImpl::SendEvent(const std::vector<uint8_t> &eventData)
1977 {
1978     pthread_rwlock_rdlock(&mtpRunrwLock_);
1979     if (mtpPort_ == nullptr || mtpDev_ == nullptr || !mtpDev_->initFlag) {
1980         pthread_rwlock_unlock(&mtpRunrwLock_);
1981         HDF_LOGE("%{public}s: no init", __func__);
1982         return HDF_DEV_ERR_DEV_INIT_FAIL;
1983     }
1984 
1985     if (eventData.size() > MTP_EVENT_PACKET_MAX_BYTES || eventData.size() == 0) {
1986         pthread_rwlock_unlock(&mtpRunrwLock_);
1987         HDF_LOGE("%{public}s: length is invald: %{public}zu", __func__, eventData.size());
1988         return HDF_FAILURE;
1989     }
1990     if (mtpDev_->mtpState == MTP_STATE_OFFLINE || mtpDev_->mtpPort == nullptr || mtpDev_->mtpPort->suspended) {
1991         pthread_rwlock_unlock(&mtpRunrwLock_);
1992         HDF_LOGE("%{public}s: device disconnect, mtpState is %{public}u", __func__, mtpDev_->mtpState);
1993         return HDF_DEV_ERR_NO_DEVICE;
1994     }
1995     std::lock_guard<std::mutex> guard(eventMutex_);
1996     if (!mtpDev_->initFlag) {
1997         pthread_rwlock_unlock(&mtpRunrwLock_);
1998         HDF_LOGE("%{public}s: dev is release", __func__);
1999         return HDF_DEV_ERR_DEV_INIT_FAIL;
2000     }
2001     struct UsbFnRequest *req = mtpDev_->notifyReq;
2002     if (req == nullptr || req->buf == nullptr) {
2003         pthread_rwlock_unlock(&mtpRunrwLock_);
2004         HDF_LOGE("%{public}s: notify req is null", __func__);
2005         return HDF_ERR_INVALID_PARAM;
2006     }
2007     if (memcpy_s(req->buf, eventData.size(), eventData.data(), eventData.size()) != EOK) {
2008         HDF_LOGE("%{public}s: memcpy_s failed", __func__);
2009         (void)UsbFnFreeRequest(req);
2010         pthread_rwlock_unlock(&mtpRunrwLock_);
2011         return HDF_FAILURE;
2012     }
2013     req->length = static_cast<uint32_t>(eventData.size());
2014     int32_t ret = UsbFnSubmitRequestSync(req, INTR_IN_TIMEOUT_JIFFIES);
2015     if (ret != HDF_SUCCESS) {
2016         HDF_LOGE("%{public}s: send notify sync request failed: %{public}d", __func__, ret);
2017     }
2018     pthread_rwlock_unlock(&mtpRunrwLock_);
2019     return ret;
2020 }
2021 } // namespace V1_0
2022 } // namespace Mtp
2023 } // namespace Gadget
2024 } // namespace Usb
2025 } // namespace HDI
2026 } // namespace OHOS
2027