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