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