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, HDF_DEV_ERR_DEV_INIT_FAIL,
63 "IUsbfnMtpInterface::Get() failed.");
64
65 auto ret = usbfnMtpInterface->Start();
66 CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "MtpDriver::OpenDriver Start() failed error = %{public}d", ret);
67 usbOpenFlag = true;
68 MEDIA_INFO_LOG("MtpDriver::OpenDriver end");
69 return MTP_SUCCESS;
70 }
71
CloseDriver()72 int MtpDriver::CloseDriver()
73 {
74 usbOpenFlag = false;
75 return MTP_SUCCESS;
76 }
77
Read(std::vector<uint8_t> & outBuffer,uint32_t & outReadSize)78 int MtpDriver::Read(std::vector<uint8_t> &outBuffer, uint32_t &outReadSize)
79 {
80 MediaLibraryTracer tracer;
81 tracer.Start("MTP MtpDriver::Read");
82 if (usbOpenFlag == false) {
83 int ret = OpenDriver();
84 if (ret < 0) {
85 return ret;
86 }
87 }
88
89 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "Read: usbfnMtpInterface is nullptr");
90 if (outReadSize == 0) {
91 outReadSize = READ_SIZE;
92 }
93
94 MEDIA_DEBUG_LOG("MtpDriver::Read start");
95 outBuffer.resize(outReadSize);
96
97 tracer.Start("MTP usbfnMtpInterface->Read");
98 auto ret = usbfnMtpInterface->Read(outBuffer);
99 tracer.Finish();
100
101 MEDIA_DEBUG_LOG("MtpDriver::Read end ret:%{public}d", ret);
102 if (ret != 0) {
103 outReadSize = 0;
104 MEDIA_ERR_LOG("MtpDriver::Read Out Error: %{public}d", ret);
105 return ret;
106 }
107 outReadSize = outBuffer.size();
108 MtpPacketTool::DumpPacket(outBuffer);
109 return MTP_SUCCESS;
110 }
111
Write(std::vector<uint8_t> & buffer,uint32_t & bufferSize)112 void MtpDriver::Write(std::vector<uint8_t> &buffer, uint32_t &bufferSize)
113 {
114 MediaLibraryTracer tracer;
115 tracer.Start("MTP MtpDriver::Write");
116 CHECK_AND_RETURN_LOG(usbfnMtpInterface != nullptr, "Write: usbfnMtpInterface is nullptr");
117 MtpPacketTool::DumpPacket(buffer);
118 MEDIA_DEBUG_LOG("MtpDriver::Write start, buffer.size:%{public}zu", buffer.size());
119
120 tracer.Start("MTP usbfnMtpInterface->Write");
121 auto ret = usbfnMtpInterface->Write(buffer);
122 tracer.Finish();
123
124 bufferSize = static_cast<uint32_t>(ret);
125 MEDIA_DEBUG_LOG("MtpDriver::Write end, ret:%{public}d", ret);
126 }
127
ReceiveObj(MtpFileRange & mfr)128 int MtpDriver::ReceiveObj(MtpFileRange &mfr)
129 {
130 MediaLibraryTracer tracer;
131 tracer.Start("MTP MtpDriver::ReceiveObj");
132 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "ReceiveObj: usbfnMtpInterface is nullptr");
133 MEDIA_DEBUG_LOG("MtpDriver::ReceiveObj start");
134 struct UsbFnMtpFileSlice mfs = {
135 .fd = mfr.fd,
136 .offset = mfr.offset,
137 .length = mfr.length,
138 .command = mfr.command,
139 .transactionId = mfr.transaction_id,
140 };
141
142 tracer.Start("MTP usbfnMtpInterface->ReceiveFile");
143 auto ret = usbfnMtpInterface->ReceiveFile(mfs);
144 tracer.Finish();
145
146 MEDIA_DEBUG_LOG("MtpDriver::ReceiveObj end ret:%{public}d", ret);
147 return ret;
148 }
149
SendObj(MtpFileRange & mfr)150 int MtpDriver::SendObj(MtpFileRange &mfr)
151 {
152 MediaLibraryTracer tracer;
153 tracer.Start("MTP MtpDriver::SendObj");
154 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "SendObj: usbfnMtpInterface is nullptr");
155 MEDIA_DEBUG_LOG("MtpDriver::SendObj start");
156 struct UsbFnMtpFileSlice mfs = {
157 .fd = mfr.fd,
158 .offset = mfr.offset,
159 .length = mfr.length,
160 .command = mfr.command,
161 .transactionId = mfr.transaction_id,
162 };
163
164 tracer.Start("MTP usbfnMtpInterface->SendFile");
165 auto ret = usbfnMtpInterface->SendFile(mfs);
166 tracer.Finish();
167
168 MEDIA_DEBUG_LOG("MtpDriver::SendObj end ret:%{public}d", ret);
169 return ret;
170 }
171
WriteEvent(EventMtp & em)172 int MtpDriver::WriteEvent(EventMtp &em)
173 {
174 MediaLibraryTracer tracer;
175 tracer.Start("MTP MtpDriver::WriteEvent");
176 CHECK_AND_RETURN_RET_LOG(usbfnMtpInterface != nullptr, E_ERR, "WriteEvent: usbfnMtpInterface is nullptr");
177 MtpPacketTool::DumpPacket(em.data);
178 MEDIA_DEBUG_LOG("MtpDriver::WriteEvent start");
179
180 tracer.Start("MTP usbfnMtpInterface->SendEvent");
181 auto ret = usbfnMtpInterface->SendEvent(em.data);
182 tracer.Finish();
183
184 MEDIA_DEBUG_LOG("MtpDriver::WriteEvent end ret:%{public}d", ret);
185 return ret;
186 }
187 } // namespace Media
188 } // namespace OHOS