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