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