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 "payload_data/set_object_prop_value_data.h"
16 #include <cinttypes>
17 #include "media_log.h"
18 #include "media_mtp_utils.h"
19 #include "mtp_packet_tools.h"
20 #include "mtp_storage_manager.h"
21 using namespace std;
22 namespace OHOS {
23 namespace Media {
24 static constexpr int32_t PARSER_PARAM_SUM = 2;
25 
SetObjectPropValueData(std::shared_ptr<MtpOperationContext> & context)26 SetObjectPropValueData::SetObjectPropValueData(std::shared_ptr<MtpOperationContext> &context)
27     : PayloadData(context)
28 {
29 }
30 
~SetObjectPropValueData()31 SetObjectPropValueData::~SetObjectPropValueData()
32 {
33 }
34 
Parser(const std::vector<uint8_t> & buffer,int32_t readSize)35 int SetObjectPropValueData::Parser(const std::vector<uint8_t> &buffer, int32_t readSize)
36 {
37     if ((context_ == nullptr) || (!MtpStorageManager::GetInstance()->HasStorage())) {
38         MEDIA_ERR_LOG("SetObjectPropValueData::parser null or storage");
39         return MTP_FAIL;
40     }
41 
42     size_t offset = MTP_CONTAINER_HEADER_SIZE;
43     if (!context_->indata) {
44         int32_t parameterCount = (readSize - MTP_CONTAINER_HEADER_SIZE) / MTP_PARAMETER_SIZE;
45         if (parameterCount < PARSER_PARAM_SUM) {
46             MEDIA_ERR_LOG("SetObjectPropValueData::parser paramCount=%{public}u, needCount=%{public}d",
47                 parameterCount, PARSER_PARAM_SUM);
48             return MTP_INVALID_PARAMETER_CODE;
49         }
50         context_->handle = MtpPacketTool::GetUInt32(buffer, offset);
51         context_->property = MtpPacketTool::GetUInt32(buffer, offset);
52         auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(context_->property);
53         if (properType == MTP_TYPE_UNDEFINED_CODE) {
54             MEDIA_ERR_LOG("SetObjectPropValueData::parser unsupported type");
55             return MTP_OBJECTPROP_NOT_SUPPORTED_CODE;
56         }
57         context_->properType = properType;
58     } else {
59         if (context_->properType == MTP_TYPE_STRING_CODE) {
60             if (!MtpPacketTool::GetString(buffer, offset, context_->properStrValue)) {
61                 MEDIA_ERR_LOG("SetObjectPropValueData::parser invalid object prop string format");
62                 return MTP_GENERAL_ERROR_CODE;
63             }
64         } else {
65             if (!ReadIntValue(buffer, offset, context_->properType, context_->properIntValue)) {
66                 MEDIA_ERR_LOG("SetObjectPropValueData::parser invalid object prop format");
67                 return MTP_INVALID_OBJECTPROP_FORMAT_CODE;
68             }
69         }
70     }
71     return MTP_SUCCESS;
72 }
73 
Maker(std::vector<uint8_t> & outBuffer)74 int SetObjectPropValueData::Maker(std::vector<uint8_t> &outBuffer)
75 {
76     if ((context_ == nullptr) || (!MtpStorageManager::GetInstance()->HasStorage())) {
77         MEDIA_ERR_LOG("SetObjectPropValueData::maker null or storage");
78         return MTP_FAIL;
79     }
80 
81     if (!hasSetResult_) {
82         MEDIA_ERR_LOG("SetObjectPropValueData::maker set");
83         return MTP_INVALID_OBJECTHANDLE_CODE;
84     }
85     return MTP_SUCCESS;
86 }
87 
CalculateSize()88 uint32_t SetObjectPropValueData::CalculateSize()
89 {
90     std::vector<uint8_t> tmpVar;
91     int res = Maker(tmpVar);
92     if (res != MTP_SUCCESS) {
93         return res;
94     }
95     return tmpVar.size();
96 }
97 
SetResult(uint16_t result)98 bool SetObjectPropValueData::SetResult(uint16_t result)
99 {
100     if (hasSetResult_) {
101         return false;
102     }
103     hasSetResult_ = true;
104     result_ = result;
105     return true;
106 }
107 
ReadIntValue(const std::vector<uint8_t> & buffer,size_t & offset,int type,int64_t & int64Value)108 bool SetObjectPropValueData::ReadIntValue(const std::vector<uint8_t> &buffer, size_t &offset, int type,
109     int64_t& int64Value)
110 {
111     if ((type == MTP_TYPE_INT8_CODE) || (type == MTP_TYPE_UINT8_CODE)) {
112         if (!ReadInt8Value(buffer, offset, type, int64Value)) {
113             return false;
114         }
115         return true;
116     }
117     if ((type == MTP_TYPE_INT16_CODE) || (type == MTP_TYPE_UINT16_CODE)) {
118         if (!ReadInt16Value(buffer, offset, type, int64Value)) {
119             return false;
120         }
121         return true;
122     }
123     if ((type == MTP_TYPE_INT32_CODE) || (type == MTP_TYPE_UINT32_CODE)) {
124         if (!ReadInt32Value(buffer, offset, type, int64Value)) {
125             return false;
126         }
127         return true;
128     }
129     if ((type == MTP_TYPE_INT64_CODE) || (type == MTP_TYPE_UINT64_CODE)) {
130         if (!ReadInt64Value(buffer, offset, type, int64Value)) {
131             return false;
132         }
133         return true;
134     }
135 
136     MEDIA_ERR_LOG("SetObjectPropValueData::ReadIntValue unsupported type");
137     return false;
138 }
139 
ReadInt8Value(const std::vector<uint8_t> & buffer,size_t & offset,int type,int64_t & int64Value)140 bool SetObjectPropValueData::ReadInt8Value(const std::vector<uint8_t> &buffer, size_t &offset, int type,
141     int64_t& int64Value)
142 {
143     if (type == MTP_TYPE_INT8_CODE) {
144         int8_t tmpVar = 0;
145         if (!MtpPacketTool::GetInt8(buffer, offset, tmpVar)) {
146             return false;
147         }
148         int64Value = tmpVar;
149         return true;
150     }
151 
152     if (type == MTP_TYPE_UINT8_CODE) {
153         uint8_t tmpVar = 0;
154         if (!MtpPacketTool::GetUInt8(buffer, offset, tmpVar)) {
155             return false;
156         }
157         int64Value = tmpVar;
158         return true;
159     }
160     return false;
161 }
162 
ReadInt16Value(const std::vector<uint8_t> & buffer,size_t & offset,int type,int64_t & int64Value)163 bool SetObjectPropValueData::ReadInt16Value(const std::vector<uint8_t> &buffer, size_t &offset, int type,
164     int64_t& int64Value)
165 {
166     if (type == MTP_TYPE_INT16_CODE) {
167         int16_t tmpVar = 0;
168         if (!MtpPacketTool::GetInt16(buffer, offset, tmpVar)) {
169             return false;
170         }
171         int64Value = tmpVar;
172         return true;
173     }
174 
175     if (type == MTP_TYPE_UINT16_CODE) {
176         uint16_t tmpVar = 0;
177         if (!MtpPacketTool::GetUInt16(buffer, offset, tmpVar)) {
178             return false;
179         }
180         int64Value = tmpVar;
181         return true;
182     }
183     return false;
184 }
185 
ReadInt32Value(const std::vector<uint8_t> & buffer,size_t & offset,int type,int64_t & int64Value)186 bool SetObjectPropValueData::ReadInt32Value(const std::vector<uint8_t> &buffer, size_t &offset, int type,
187     int64_t& int64Value)
188 {
189     if (type == MTP_TYPE_INT32_CODE) {
190         int32_t tmpVar = 0;
191         if (!MtpPacketTool::GetInt32(buffer, offset, tmpVar)) {
192             return false;
193         }
194         int64Value = tmpVar;
195         return true;
196     }
197 
198     if (type == MTP_TYPE_UINT32_CODE) {
199         uint32_t tmpVar = 0;
200         if (!MtpPacketTool::GetUInt32(buffer, offset, tmpVar)) {
201             return false;
202         }
203         int64Value = tmpVar;
204         return true;
205     }
206     return false;
207 }
208 
ReadInt64Value(const std::vector<uint8_t> & buffer,size_t & offset,int type,int64_t & int64Value)209 bool SetObjectPropValueData::ReadInt64Value(const std::vector<uint8_t> &buffer, size_t &offset, int type,
210     int64_t& int64Value)
211 {
212     if (type == MTP_TYPE_INT64_CODE) {
213         int64_t tmpVar = 0;
214         if (!MtpPacketTool::GetInt64(buffer, offset, tmpVar)) {
215             return false;
216         }
217         int64Value = tmpVar;
218         return true;
219     }
220 
221     if (type == MTP_TYPE_UINT64_CODE) {
222         uint64_t tmpVar = 0;
223         if (!MtpPacketTool::GetUInt64(buffer, offset, tmpVar)) {
224             return false;
225         }
226         int64Value = static_cast<int64_t>(tmpVar);
227         return true;
228     }
229     return false;
230 }
231 } // namespace Media
232 } // namespace OHOS