• 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 "MtpOperation"
16 #include "mtp_operation.h"
17 #include <algorithm>
18 #include "header_data.h"
19 #include "medialibrary_tracer.h"
20 #include "media_log.h"
21 #include "media_mtp_utils.h"
22 #include "mtp_constants.h"
23 #include "mtp_dfx_reporter.h"
24 #include "mtp_packet.h"
25 #include "mtp_packet_tools.h"
26 #include "mtp_operation_context.h"
27 #include "mtp_operation_utils.h"
28 #include "mtp_storage_manager.h"
29 #include "packet_payload_factory.h"
30 #include "parameters.h"
31 #include "payload_data/get_device_info_data.h"
32 #include "payload_data.h"
33 #include "payload_data/send_object_info_data.h"
34 #include "payload_data/set_object_prop_value_data.h"
35 #include "storage.h"
36 
37 using namespace std;
38 namespace OHOS {
39 namespace Media {
40 constexpr const char *MTP_DISABLE = "persist.edm.mtp_server_disable";
MtpOperation(void)41 MtpOperation::MtpOperation(void)
42 {
43     Init();
44 }
45 
Init()46 void MtpOperation::Init()
47 {
48     mtpContextPtr_ = make_shared<MtpOperationContext>();
49     mtpContextPtr_->indata = false;
50 
51     mtpDriver_ = make_shared<MtpDriver>();
52     mtpContextPtr_->mtpDriver = mtpDriver_;
53 
54     requestPacketPtr_ = make_shared<MtpPacket>(mtpContextPtr_, mtpDriver_);
55     dataPacketPtr_ = make_shared<MtpPacket>(mtpContextPtr_, mtpDriver_);
56     responsePacketPtr_ = make_shared<MtpPacket>(mtpContextPtr_, mtpDriver_);
57 
58     operationUtils_ = make_shared<MtpOperationUtils>(mtpContextPtr_, true);
59     responseCode_ = MTP_UNDEFINED_CODE;
60 }
61 
Stop()62 void MtpOperation::Stop()
63 {
64     CHECK_AND_RETURN_LOG(requestPacketPtr_ != nullptr, "requestPacketPtr_ is null");
65     requestPacketPtr_->Stop();
66 }
67 
Execute()68 int32_t MtpOperation::Execute()
69 {
70     MediaLibraryTracer tracer;
71     tracer.Start("MtpOperation::Execute");
72     // 判断param, disable == true, 直接给Initiator返回error_dode
73     std::string param(MTP_DISABLE);
74     bool mtpDisable = system::GetBoolParameter(param, false);
75     int errorCode = 0;
76     if (mtpDisable) {
77         SendMakeResponsePacket(errorCode);
78         MEDIA_INFO_LOG("MTP is disable");
79         return errorCode;
80     }
81     ResetOperation();
82     ReceiveRequestPacket(errorCode);
83     CHECK_AND_RETURN_RET_LOG(mtpContextPtr_ != nullptr, errorCode, "mtpContextPtr_ is null");
84     if (mtpContextPtr_->operationCode == 0) {
85         MEDIA_DEBUG_LOG("operationCode is 0, read error, no need to send response");
86         return errorCode;
87     }
88     if (errorCode != MTP_SUCCESS) {
89         SendMakeResponsePacket(errorCode);
90         MEDIA_ERR_LOG("MtpOperation::Execute Out ReceiveRequestPacket fail err: %{public}d", errorCode);
91         return errorCode;
92     }
93 
94     DealRequest(mtpContextPtr_->operationCode, errorCode);
95     if (errorCode != MTP_SUCCESS) {
96         SendMakeResponsePacket(errorCode);
97         MEDIA_ERR_LOG("MtpOperation::Execute Out DealRequest fail err: %{public}d", errorCode);
98         return errorCode;
99     }
100 
101     if (MtpPacket::IsNeedDataPhase(mtpContextPtr_->operationCode)) {
102         if (MtpPacket::IsI2R(mtpContextPtr_->operationCode)) {
103             ReceiveI2Rdata(errorCode);
104         } else {
105             SendR2Idata(errorCode);
106         }
107     }
108     if (errorCode == MTP_ERROR_TRANSFER_CANCELLED) {
109         MEDIA_INFO_LOG("File transfer canceled");
110         return errorCode;
111     }
112 
113     SendMakeResponsePacket(errorCode);
114     return errorCode;
115 }
116 
ReceiveRequestPacket(int & errorCode)117 void MtpOperation::ReceiveRequestPacket(int &errorCode)
118 {
119     shared_ptr<HeaderData> headerData = make_shared<HeaderData>(mtpContextPtr_);
120     requestPacketPtr_->Init(headerData);
121     errorCode = requestPacketPtr_->Read();
122     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "requestPacket Read fail err: %{public}d", errorCode);
123     errorCode = requestPacketPtr_->Parser();
124     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "requestPacket Parser fail err: %{public}d", errorCode);
125 }
126 
SendMakeResponsePacket(int & errorCode)127 void MtpOperation::SendMakeResponsePacket(int &errorCode)
128 {
129     CHECK_AND_RETURN_LOG(responsePacketPtr_ != nullptr, "responsePacketPtr_ is null");
130     responsePacketPtr_->Reset();
131     CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "mtpContextPtr_ is null");
132     GetPayloadData(mtpContextPtr_, dataPayloadData_, RESPONSE_CONTAINER_TYPE, errorCode);
133     if (mtpContextPtr_->operationCode != 0) {
134         MEDIA_INFO_LOG("operation = [0x%{public}x : %{public}s ]", mtpContextPtr_->operationCode,
135             MtpPacketTool::GetOperationName(mtpContextPtr_->operationCode).c_str());
136     }
137     MtpDfxReporter::GetInstance().DoOperationResultStatistics(mtpContextPtr_->operationCode, responseCode_);
138     shared_ptr<HeaderData> responseHeaderData = make_shared<HeaderData>(
139         RESPONSE_CONTAINER_TYPE, responseCode_, mtpContextPtr_->transactionID);
140 
141     responsePacketPtr_->Init(responseHeaderData, dataPayloadData_);
142     errorCode = responsePacketPtr_->Maker(false);
143     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "responsePacket Maker fail err: %{public}d", errorCode);
144     int32_t result = 0;
145     auto startTime = std::chrono::high_resolution_clock::now();
146     errorCode = responsePacketPtr_->Write(result);
147     auto endTime = std::chrono::high_resolution_clock::now();
148     std::chrono::duration<uint16_t, std::milli> duration =
149         std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
150     MtpDfxReporter::GetInstance().DoSendResponseResultDfxReporter(mtpContextPtr_->operationCode, result,
151         duration.count(), OperateMode::writemode);
152     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "responsePacket Write fail err: %{public}d", errorCode);
153 }
154 
SendObjectData(int & errorCode)155 void MtpOperation::SendObjectData(int &errorCode)
156 {
157     errorCode = operationUtils_->GetObjectDataDeal();
158 }
159 
RecevieObjectData(int & errorCode)160 void MtpOperation::RecevieObjectData(int &errorCode)
161 {
162     errorCode = operationUtils_->DoRecevieSendObject();
163 }
164 
ReceiveI2Rdata(int & errorCode)165 void MtpOperation::ReceiveI2Rdata(int &errorCode)
166 {
167     if (mtpContextPtr_->operationCode == MTP_OPERATION_SEND_OBJECT_CODE) {
168         MEDIA_INFO_LOG("ReceiveI2Rdata RecevieObjectData");
169         RecevieObjectData(errorCode);
170         return;
171     }
172     mtpContextPtr_->indata = true;
173 
174     errorCode = dataPacketPtr_->Read();
175     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "dataPacket Read fail err: %{public}d", errorCode);
176     errorCode = dataPacketPtr_->Parser();
177     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "dataPacket Parser fail err: %{public}d", errorCode);
178 
179     if (mtpContextPtr_->operationCode == MTP_OPERATION_SET_OBJECT_PROP_VALUE_CODE) {
180         MEDIA_INFO_LOG("ReceiveI2Rdata DoSetObjectPropValue");
181         operationUtils_->DoSetObjectPropValue(errorCode);
182     }
183 }
184 
SendR2Idata(int & errorCode)185 void MtpOperation::SendR2Idata(int &errorCode)
186 {
187     if (mtpContextPtr_->operationCode == MTP_OPERATION_GET_OBJECT_CODE ||
188         mtpContextPtr_->operationCode == MTP_OPERATION_GET_PARTIAL_OBJECT_CODE) {
189         SendObjectData(errorCode);
190         return;
191     }
192 
193     responseCode_ = GetPayloadData(mtpContextPtr_, dataPayloadData_, DATA_CONTAINER_TYPE, errorCode);
194     MEDIA_INFO_LOG("operation = [0x%{public}x : %{public}s ]", mtpContextPtr_->operationCode,
195         MtpPacketTool::GetOperationName(mtpContextPtr_->operationCode).c_str());
196     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "GetPayloadData fail err: %{public}d", errorCode);
197     shared_ptr<HeaderData> dataHeaderData = make_shared<HeaderData>(
198         DATA_CONTAINER_TYPE, mtpContextPtr_->operationCode, mtpContextPtr_->transactionID);
199     dataPacketPtr_->Init(dataHeaderData, dataPayloadData_);
200     errorCode = dataPacketPtr_->Maker(true);
201     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "dataPacket Maker fail err: %{public}d", errorCode);
202     int32_t result = 0;
203     auto startTime = std::chrono::high_resolution_clock::now();
204     errorCode = dataPacketPtr_->Write(result);
205     auto endTime = std::chrono::high_resolution_clock::now();
206     std::chrono::duration<uint16_t, std::milli> duration =
207         std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
208     MtpDfxReporter::GetInstance().DoSendResponseResultDfxReporter(mtpContextPtr_->operationCode, result,
209         duration.count(), OperateMode::writemode);
210     CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "dataPacket Write fail err: %{public}d", errorCode);
211 }
212 
DealRequest(uint16_t operationCode,int & errorCode)213 void MtpOperation::DealRequest(uint16_t operationCode, int &errorCode)
214 {
215     switch (operationCode) {
216         case MTP_OPERATION_OPEN_SESSION_CODE:
217             if (!mtpContextPtr_->sessionOpen) {
218                 mtpContextPtr_->sessionID = mtpContextPtr_->tempSessionID;
219                 errorCode = MTP_SUCCESS;
220             } else {
221                 errorCode = MTP_ERROR_SESSION_ALREADY_OPEN;
222             }
223             break;
224         default:
225             errorCode = MTP_SUCCESS;
226             break;
227     }
228 }
229 
GetPayloadData(shared_ptr<MtpOperationContext> & context,shared_ptr<PayloadData> & data,uint16_t containerType,int & errorCode)230 uint16_t MtpOperation::GetPayloadData(shared_ptr<MtpOperationContext> &context, shared_ptr<PayloadData> &data,
231     uint16_t containerType, int &errorCode)
232 {
233     responseCode_ = MTP_UNDEFINED_CODE;
234     switch (context->operationCode) {
235         case MTP_OPERATION_GET_DEVICE_INFO_CODE:
236             responseCode_ = operationUtils_->GetDeviceInfo(data, containerType, errorCode);
237             break;
238         case MTP_OPERATION_OPEN_SESSION_CODE:
239             responseCode_ = operationUtils_->GetOpenSession(data, errorCode);
240             break;
241         case MTP_OPERATION_SET_DEVICE_PROP_VALUE_CODE:
242             responseCode_ = operationUtils_->SetDevicePropValueResp(data);
243             break;
244         default:
245             responseCode_ = GetPayloadDataSub(context, data, containerType, errorCode);
246             break;
247     }
248     return responseCode_;
249 }
250 
GetPayloadDataSub(shared_ptr<MtpOperationContext> & context,shared_ptr<PayloadData> & data,uint16_t containerType,int & errorCode)251 uint16_t MtpOperation::GetPayloadDataSub(shared_ptr<MtpOperationContext> &context, shared_ptr<PayloadData> &data,
252     uint16_t containerType, int &errorCode)
253 {
254     responseCode_ = MTP_UNDEFINED_CODE;
255     switch (context->operationCode) {
256         case MTP_OPERATION_RESET_DEVICE_CODE:
257         case MTP_OPERATION_CLOSE_SESSION_CODE:
258             responseCode_ = operationUtils_->GetCloseSession(data);
259             break;
260         case MTP_OPERATION_GET_STORAGE_IDS_CODE:
261             responseCode_ = operationUtils_->GetStorageIDs(data, containerType, errorCode);
262             break;
263         case MTP_OPERATION_GET_STORAGE_INFO_CODE:
264             responseCode_ = operationUtils_->GetStorageInfo(data, containerType, errorCode);
265             break;
266         case MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED_CODE:
267             responseCode_ = operationUtils_->GetObjectPropsSupported(data);
268             break;
269         case MTP_OPERATION_GET_OBJECT_HANDLES_CODE:
270             responseCode_ = operationUtils_->GetObjectHandles(data, containerType, errorCode);
271             break;
272         case MTP_OPERATION_GET_NUM_OBJECTS_CODE:
273             responseCode_ = operationUtils_->GetNumObjects(data);
274             break;
275         case MTP_OPERATION_GET_OBJECT_INFO_CODE:
276             responseCode_ = operationUtils_->GetObjectInfo(data, containerType, errorCode);
277             break;
278         case MTP_OPERATION_GET_OBJECT_PROP_DESC_CODE:
279             responseCode_ = operationUtils_->GetObjectPropDesc(data, containerType, errorCode);
280             break;
281         case MTP_OPERATION_GET_OBJECT_PROP_VALUE_CODE:
282             responseCode_ = operationUtils_->GetObjectPropValue(data, containerType, errorCode);
283             break;
284         case MTP_OPERATION_SET_OBJECT_PROP_VALUE_CODE:
285             responseCode_ = operationUtils_->GetRespCommonData(data, errorCode);
286             break;
287         case MTP_OPERATION_GET_OBJECT_PROP_LIST_CODE:
288             responseCode_ = operationUtils_->GetObjectPropList(data, containerType, errorCode);
289             break;
290         default:
291             responseCode_ = GetPayloadDataMore(context, data, containerType, errorCode);
292             break;
293     }
294     return responseCode_;
295 }
296 
GetPayloadDataMore(shared_ptr<MtpOperationContext> & context,shared_ptr<PayloadData> & data,uint16_t containerType,int & errorCode)297 uint16_t MtpOperation::GetPayloadDataMore(shared_ptr<MtpOperationContext> &context, shared_ptr<PayloadData> &data,
298     uint16_t containerType, int &errorCode)
299 {
300     responseCode_ = MTP_UNDEFINED_CODE;
301     switch (context->operationCode) {
302         case MTP_OPERATION_GET_OBJECT_REFERENCES_CODE:
303             responseCode_ = operationUtils_->GetObjectReferences(data, containerType, errorCode);
304             break;
305         case MTP_OPERATION_SET_OBJECT_REFERENCES_CODE:
306             responseCode_ = operationUtils_->SetObjectReferences(data);
307             break;
308         case MTP_OPERATION_DELETE_OBJECT_CODE:
309             responseCode_ = operationUtils_->DeleteObject(data, errorCode);
310             break;
311         case MTP_OPERATION_MOVE_OBJECT_CODE:
312             responseCode_ = operationUtils_->MoveObject(data, errorCode);
313             break;
314         case MTP_OPERATION_COPY_OBJECT_CODE:
315             responseCode_ = operationUtils_->CopyObject(data, errorCode);
316             break;
317         case MTP_OPERATION_GET_DEVICE_PROP_DESC_CODE:
318             responseCode_ = operationUtils_->GetPropDesc(data, containerType, errorCode);
319             break;
320         case MTP_OPERATION_GET_DEVICE_PROP_VALUE_CODE:
321             responseCode_ = operationUtils_->GetPropValue(data, containerType, errorCode);
322             break;
323         case MTP_OPERATION_RESET_DEVICE_PROP_VALUE_CODE:
324             responseCode_ = operationUtils_->ResetDevicePropResp(data);
325             break;
326         case MTP_OPERATION_GET_OBJECT_CODE:
327             responseCode_ = operationUtils_->GetObject(data, errorCode);
328             break;
329         case MTP_OPERATION_SEND_OBJECT_CODE:
330             responseCode_ = operationUtils_->GetRespCommonData(data, errorCode);
331             break;
332         case MTP_OPERATION_GET_THUMB_CODE:
333             responseCode_ = operationUtils_->GetThumb(data, containerType, errorCode);
334             break;
335         case MTP_OPERATION_SEND_OBJECT_INFO_CODE:
336             responseCode_ = operationUtils_->SendObjectInfo(data, errorCode);
337             break;
338         case MTP_OPERATION_GET_PARTIAL_OBJECT_CODE:
339             responseCode_ = operationUtils_->GetPartialObject(data);
340             break;
341         default:
342             responseCode_ = operationUtils_->GetRespCommonData(data, errorCode);
343             break;
344     }
345     return responseCode_;
346 }
347 
ResetOperation()348 void MtpOperation::ResetOperation()
349 {
350     if (requestPacketPtr_ != nullptr) {
351         requestPacketPtr_->Reset();
352     }
353     if (dataPacketPtr_ != nullptr) {
354         dataPacketPtr_->Reset();
355     }
356     if (responsePacketPtr_ != nullptr) {
357         responsePacketPtr_->Reset();
358     }
359     if (dataPayloadData_!= nullptr) {
360         dataPayloadData_ = nullptr;
361     }
362     if (mtpContextPtr_ != nullptr) {
363         mtpContextPtr_->operationCode = 0;
364         mtpContextPtr_->transactionID = 0;
365         mtpContextPtr_->indata = false;
366     }
367 
368     responseCode_ = MTP_OK_CODE;
369 }
370 
AddStorage(shared_ptr<Storage> & storage)371 void MtpOperation::AddStorage(shared_ptr<Storage> &storage)
372 {
373     auto mtpStorageManager = MtpStorageManager::GetInstance();
374     if (mtpStorageManager != nullptr) {
375         mtpStorageManager->AddStorage(storage);
376     }
377 }
378 
RemoveStorage(std::shared_ptr<Storage> & storage)379 void MtpOperation::RemoveStorage(std::shared_ptr<Storage> &storage)
380 {
381     auto mtpStorageManager = MtpStorageManager::GetInstance();
382     if (mtpStorageManager != nullptr) {
383         mtpStorageManager->RemoveStorage(storage);
384     }
385 }
386 } // namespace Media
387 } // namespace OHOS