1 /* 2 * Copyright (C) 2022 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 #define MLOG_TAG "MtpDriver" 16 #include "mtp_driver.h" 17 #include "media_log.h" 18 #include "media_mtp_utils.h" 19 #include "medialibrary_tracer.h" 20 #include "mtp_operation_utils.h" 21 #include "mtp_packet_tools.h" 22 #include <fcntl.h> 23 #include <unistd.h> 24 #include <cstdio> 25 #include <cstring> 26 #include <sys/ioctl.h> 27 #include "v1_0/iusb_interface.h" 28 29 #define MTP_SEND_FILE _IOW('M', 0, struct MtpFileRange) 30 /* 31 * Receives data from the host and writes it to a file. 32 * The file is created if it does not exist. 33 */ 34 #define MTP_RECEIVE_FILE _IOW('M', 1, struct MtpFileRange) 35 /* Sends an event to the host via the interrupt endpoint */ 36 #define MTP_SEND_EVENT _IOW('M', 3, struct EventMtp) 37 /* 38 * Sends the specified file range to the host, 39 * with a 12 byte MTP data packet header at the beginning. 40 */ 41 #define MTP_SEND_FILE_WITH_HEADER _IOW('M', 4, struct MtpFileRange) 42 43 using namespace std; 44 using namespace OHOS::HDI::Usb::Gadget::Mtp::V1_0; 45 namespace OHOS { 46 namespace Media { 47 const int READ_SIZE = 10240; 48 MtpDriver()49 MtpDriver::MtpDriver() 50 { 51 } 52 ~MtpDriver()53 MtpDriver::~MtpDriver() 54 { 55 CloseDriver(); 56 } 57 OpenDriver()58 int MtpDriver::OpenDriver() 59 { 60 MEDIA_INFO_LOG("MtpDriver::OpenDriver start"); 61 usbfnMtpInterface = IUsbfnMtpInterface::Get(); 62 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "IUsbfnMtpInterface::Get() failed."); 63 64 auto ret = usbfnMtpInterface->Start(); 65 CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "MtpDriver::OpenDriver Start() failed error = %{public}d", ret); 66 usbOpenFlag = true; 67 MEDIA_INFO_LOG("MtpDriver::OpenDriver end"); 68 return MTP_SUCCESS; 69 } 70 CloseDriver()71 int MtpDriver::CloseDriver() 72 { 73 if (usbfnMtpInterface != nullptr) { 74 auto ret = usbfnMtpInterface->Stop(); 75 MEDIA_ERR_LOG("MtpDriver::CloseDriver Error: %{public}d", ret); 76 } 77 78 usbOpenFlag = false; 79 return MTP_SUCCESS; 80 } 81 Read(std::vector<uint8_t> & outBuffer,uint32_t & outReadSize)82 int MtpDriver::Read(std::vector<uint8_t> &outBuffer, uint32_t &outReadSize) 83 { 84 MediaLibraryTracer tracer; 85 tracer.Start("MTP MtpDriver::Read"); 86 if (usbOpenFlag == false) { 87 int ret = OpenDriver(); 88 if (ret < 0) { 89 return MTP_ERROR_DRIVER_OPEN_FAILED; 90 } 91 } 92 93 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "Read: usbfnMtpInterface is nullptr"); 94 if (outReadSize == 0) { 95 outReadSize = READ_SIZE; 96 } 97 98 MEDIA_DEBUG_LOG("MtpDriver::Read start"); 99 outBuffer.resize(outReadSize); 100 101 tracer.Start("MTP usbfnMtpInterface->Read"); 102 auto ret = usbfnMtpInterface->Read(outBuffer); 103 tracer.Finish(); 104 105 MEDIA_DEBUG_LOG("MtpDriver::Read end ret:%{public}d", ret); 106 if (ret != 0) { 107 outBuffer.resize(0); 108 outReadSize = 0; 109 MEDIA_ERR_LOG("MtpDriver::Read Out Error: %{public}d", ret); 110 return E_ERR; 111 } 112 outReadSize = outBuffer.size(); 113 MtpPacketTool::DumpPacket(outBuffer); 114 return MTP_SUCCESS; 115 } 116 Write(std::vector<uint8_t> & buffer,uint32_t & bufferSize)117 void MtpDriver::Write(std::vector<uint8_t> &buffer, uint32_t &bufferSize) 118 { 119 MediaLibraryTracer tracer; 120 tracer.Start("MTP MtpDriver::Write"); 121 CHECK_AND_RETURN_LOG(usbfnMtpInterface != nullptr, "Write: usbfnMtpInterface is nullptr"); 122 MtpPacketTool::DumpPacket(buffer); 123 MEDIA_DEBUG_LOG("MtpDriver::Write start, buffer.size:%{public}zu", buffer.size()); 124 125 tracer.Start("MTP usbfnMtpInterface->Write"); 126 auto ret = usbfnMtpInterface->Write(buffer); 127 tracer.Finish(); 128 129 bufferSize = static_cast<uint32_t>(ret); 130 MEDIA_DEBUG_LOG("MtpDriver::Write end, ret:%{public}d", ret); 131 } 132 ReceiveObj(MtpFileRange & mfr)133 int MtpDriver::ReceiveObj(MtpFileRange &mfr) 134 { 135 MediaLibraryTracer tracer; 136 tracer.Start("MTP MtpDriver::ReceiveObj"); 137 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "ReceiveObj: usbfnMtpInterface is nullptr"); 138 MEDIA_DEBUG_LOG("MtpDriver::ReceiveObj start"); 139 struct UsbFnMtpFileSlice mfs = { 140 .fd = mfr.fd, 141 .offset = mfr.offset, 142 .length = mfr.length, 143 .command = mfr.command, 144 .transactionId = mfr.transaction_id, 145 }; 146 147 tracer.Start("MTP usbfnMtpInterface->ReceiveFile"); 148 auto ret = usbfnMtpInterface->ReceiveFile(mfs); 149 tracer.Finish(); 150 151 MEDIA_DEBUG_LOG("MtpDriver::ReceiveObj end ret:%{public}d", ret); 152 return ret; 153 } 154 SendObj(MtpFileRange & mfr)155 int MtpDriver::SendObj(MtpFileRange &mfr) 156 { 157 MediaLibraryTracer tracer; 158 tracer.Start("MTP MtpDriver::SendObj"); 159 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "SendObj: usbfnMtpInterface is nullptr"); 160 MEDIA_DEBUG_LOG("MtpDriver::SendObj start"); 161 struct UsbFnMtpFileSlice mfs = { 162 .fd = mfr.fd, 163 .offset = 0, 164 .length = mfr.length, 165 .command = mfr.command, 166 .transactionId = mfr.transaction_id, 167 }; 168 169 tracer.Start("MTP usbfnMtpInterface->SendFile"); 170 auto ret = usbfnMtpInterface->SendFile(mfs); 171 tracer.Finish(); 172 173 MEDIA_DEBUG_LOG("MtpDriver::SendObj end ret:%{public}d", ret); 174 return ret; 175 } 176 WriteEvent(EventMtp & em)177 int MtpDriver::WriteEvent(EventMtp &em) 178 { 179 MediaLibraryTracer tracer; 180 tracer.Start("MTP MtpDriver::WriteEvent"); 181 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "WriteEvent: usbfnMtpInterface is nullptr"); 182 MtpPacketTool::DumpPacket(em.data); 183 MEDIA_DEBUG_LOG("MtpDriver::WriteEvent start"); 184 185 tracer.Start("MTP usbfnMtpInterface->SendEvent"); 186 auto ret = usbfnMtpInterface->SendEvent(em.data); 187 tracer.Finish(); 188 189 MEDIA_DEBUG_LOG("MtpDriver::WriteEvent end ret:%{public}d", ret); 190 return ret; 191 } 192 } // namespace Media 193 } // namespace OHOS