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