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