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