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