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