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