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