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