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