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 */ 31static 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 */ 41struct 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 */ 50struct 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 */ 59static 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 83struct UsbMtpDeviceStatus { 84 uint16_t wLength; 85 uint16_t wCode; 86}; 87 88namespace OHOS { 89namespace HDI { 90namespace Usb { 91namespace Gadget { 92namespace Mtp { 93namespace V1_0 { 94sptr<IUsbfnMtpInterface> g_instance = nullptr; 95std::mutex g_instanceLock; 96extern "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 107struct UsbMtpDevice *UsbfnMtpImpl::mtpDev_ = nullptr; 108struct UsbMtpPort *UsbfnMtpImpl::mtpPort_ = nullptr; 109std::mutex UsbfnMtpImpl::mtpRunning_; 110std::mutex UsbfnMtpImpl::asyncMutex_; 111sem_t UsbfnMtpImpl::asyncReq_ {0}; 112 113constexpr uint32_t BULK_IN_TIMEOUT_JIFFIES = 0; /* sync timeout, set to 0 means wait forever */ 114constexpr uint32_t BULK_OUT_TIMEOUT_JIFFIES = 0; /* sync timeout, set to 0 means wait forever */ 115constexpr uint32_t INTR_IN_TIMEOUT_JIFFIES = 0; /* sync timeout, set to 0 means wait forever */ 116constexpr uint64_t MTP_MAX_FILE_SIZE = 0xFFFFFFFFULL; 117constexpr uint32_t WRITE_FILE_TEMP_SLICE = 100 * 1024; /* 100KB */ 118static constexpr int32_t WAIT_UDC_MAX_LOOP = 3; 119static constexpr uint32_t WAIT_UDC_TIME = 100000; 120enum 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 127enum UsbMtpAsyncXferState { 128 ASYNC_XFER_FILE_NORMAL = 0, 129 ASYNC_XFER_FILE_DONE, 130}; 131 132UsbfnMtpImpl::UsbfnMtpImpl() : deviceObject_(nullptr) {} 133 134void 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 159void 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 184void 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 193void 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 221int32_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 251int32_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 267int32_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 287int32_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 328int32_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 354void 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 366void 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 376int32_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 409int32_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 426int32_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 446int32_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 457int32_t UsbfnMtpImpl::UsbMtpPortReleaseIo() 458{ 459 return UsbMtpPortCancelPlusFreeIo(mtpPort_, true); 460} 461 462struct 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 473int32_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 496int32_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 526int32_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 547int32_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 592void 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 604void 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 618int32_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 636int32_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 654void 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 698int32_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 749int32_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 766bool 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 783int32_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 801int32_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 836int32_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 859int32_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 876int32_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 889void 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 899int32_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 910int32_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; 953ERR: 954 (void)UsbMtpDeviceReleaseFuncDevice(); 955 (void)UsbMtpDeviceFree(); 956 (void)OsalMemFree(mtpDev_); 957 mtpDev_ = nullptr; 958 return ret; 959} 960 961int32_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 984int32_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 997int32_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 1011uint32_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 1018uint32_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 1029int32_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 1071int32_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 1118int32_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 1143int32_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 1190int32_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 1210int32_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) { 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 1261int32_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 1292int32_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 1327int32_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 1356int32_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 1391int32_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 1418int32_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 1458int32_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 1474int32_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 1514int32_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