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