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_packet.h"
16 #include "media_log.h"
17 #include "media_mtp_utils.h"
18 #include "mtp_constants.h"
19 #include "packet_payload_factory.h"
20 using namespace std;
21 namespace OHOS {
22 namespace Media {
23 const int EVENT_LENGTH = 16;
MtpPacket(std::shared_ptr<MtpOperationContext> &context)24 MtpPacket::MtpPacket(std::shared_ptr<MtpOperationContext> &context)
25 : context_(context), readSize_(0), headerData_(nullptr), payloadData_(nullptr)
26 {
27 }
28
MtpPacket(std::shared_ptr<MtpOperationContext> &context, const shared_ptr<MtpDriver> &mtpDriver)29 MtpPacket::MtpPacket(std::shared_ptr<MtpOperationContext> &context, const shared_ptr<MtpDriver> &mtpDriver)
30 : context_(context), readSize_(0), headerData_(nullptr), payloadData_(nullptr), mtpDriver_(mtpDriver)
31 {
32 }
33
~MtpPacket()34 MtpPacket::~MtpPacket()
35 {
36 }
37
Init(std::shared_ptr<HeaderData> &headerData)38 void MtpPacket::Init(std::shared_ptr<HeaderData> &headerData)
39 {
40 readSize_ = 0;
41 headerData_ = headerData;
42
43 if (headerData->GetContainerType() == DATA_CONTAINER_TYPE) {
44 readBufSize_ = READ_DATA_BUFFER_MAX_SIZE;
45 } else {
46 readBufSize_ = READ_BUFFER_MAX_SIZE;
47 }
48 }
49
Init(std::shared_ptr<HeaderData> &headerData, std::shared_ptr<PayloadData> &payloadData)50 void MtpPacket::Init(std::shared_ptr<HeaderData> &headerData, std::shared_ptr<PayloadData> &payloadData)
51 {
52 readSize_ = 0;
53 headerData_ = headerData;
54 payloadData_ = payloadData;
55
56 if (headerData->GetContainerType() == DATA_CONTAINER_TYPE) {
57 readBufSize_ = READ_DATA_BUFFER_MAX_SIZE;
58 } else {
59 readBufSize_ = READ_BUFFER_MAX_SIZE;
60 }
61 }
62
Reset()63 void MtpPacket::Reset()
64 {
65 readSize_ = 0;
66 headerData_ = nullptr;
67 payloadData_ = nullptr;
68 std::vector<uint8_t>().swap(writeBuffer_);
69 }
70
IsNeedDataPhase(uint16_t operationCode)71 bool MtpPacket::IsNeedDataPhase(uint16_t operationCode)
72 {
73 switch (operationCode) {
74 case MTP_OPERATION_GET_DEVICE_INFO_CODE:
75 case MTP_OPERATION_GET_STORAGE_IDS_CODE:
76 case MTP_OPERATION_GET_STORAGE_INFO_CODE:
77 case MTP_OPERATION_GET_OBJECT_HANDLES_CODE:
78 case MTP_OPERATION_GET_OBJECT_CODE:
79 case MTP_OPERATION_GET_OBJECT_INFO_CODE:
80 case MTP_OPERATION_GET_THUMB_CODE:
81 case MTP_OPERATION_SEND_OBJECT_INFO_CODE:
82 case MTP_OPERATION_SEND_OBJECT_CODE:
83 case MTP_OPERATION_GET_DEVICE_PROP_DESC_CODE:
84 case MTP_OPERATION_SET_DEVICE_PROP_VALUE_CODE:
85 case MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED_CODE:
86 case MTP_OPERATION_GET_OBJECT_PROP_DESC_CODE:
87 case MTP_OPERATION_GET_OBJECT_PROP_VALUE_CODE:
88 case MTP_OPERATION_SET_OBJECT_PROP_VALUE_CODE:
89 case MTP_OPERATION_GET_OBJECT_PROP_LIST_CODE:
90 case MTP_OPERATION_GET_OBJECT_REFERENCES_CODE:
91 return true;
92 default:
93 break;
94 }
95 return false;
96 }
97
IsI2R(uint16_t operationCode)98 bool MtpPacket::IsI2R(uint16_t operationCode)
99 {
100 switch (operationCode) {
101 case MTP_OPERATION_SEND_OBJECT_INFO_CODE:
102 case MTP_OPERATION_SEND_OBJECT_CODE:
103 case MTP_OPERATION_SET_DEVICE_PROP_VALUE_CODE:
104 case MTP_OPERATION_SET_OBJECT_PROP_VALUE_CODE:
105 return true;
106 default:
107 break;
108 }
109 return false;
110 }
111
Read()112 int MtpPacket::Read()
113 {
114 std::vector<uint8_t>().swap(readBuffer_);
115 int errorCode = mtpDriver_->Read(readBuffer_, readSize_);
116 return errorCode;
117 }
118
Write()119 int MtpPacket::Write()
120 {
121 if (headerData_->GetContainerType() == EVENT_CONTAINER_TYPE) {
122 EventMtp event;
123 event.length = EVENT_LENGTH;
124 event.data = writeBuffer_;
125 mtpDriver_->WriteEvent(event);
126 return MTP_SUCCESS;
127 }
128 mtpDriver_->Write(writeBuffer_, writeSize_);
129 return MTP_SUCCESS;
130 }
131
Parser()132 int MtpPacket::Parser()
133 {
134 int errorCode = ParserHead();
135 if (errorCode != MTP_SUCCESS) {
136 MEDIA_ERR_LOG("ParserHead fail err: %{public}d", errorCode);
137 return errorCode;
138 }
139
140 errorCode = ParserPayload();
141 if (errorCode != MTP_SUCCESS) {
142 MEDIA_ERR_LOG("ParserPayload fail err: %{public}d", errorCode);
143 return errorCode;
144 }
145 return MTP_SUCCESS;
146 }
147
Maker(bool isPayload)148 int MtpPacket::Maker(bool isPayload)
149 {
150 writeSize_ = payloadData_->CalculateSize() + PACKET_HEADER_LENGETH;
151 headerData_->SetContainerLength(writeSize_);
152
153 int errorCode = MakeHead();
154 if (errorCode != MTP_SUCCESS) {
155 MEDIA_ERR_LOG("MakeHead fail err: %{public}d", errorCode);
156 return errorCode;
157 }
158
159 errorCode = MakerPayload();
160 if (errorCode != MTP_SUCCESS) {
161 MEDIA_ERR_LOG("MakeHead fail err: %{public}d", errorCode);
162 return errorCode;
163 }
164 return MTP_SUCCESS;
165 }
166
ParserHead()167 int MtpPacket::ParserHead()
168 {
169 if (readSize_ <= 0) {
170 MEDIA_ERR_LOG("ParserHead fail readSize_ <= 0");
171 return MTP_ERROR_PACKET_INCORRECT;
172 }
173 if (headerData_ == nullptr) {
174 headerData_ = make_shared<HeaderData>(context_);
175 }
176 int errorCode = headerData_->Parser(readBuffer_, readSize_);
177 if (errorCode != MTP_SUCCESS) {
178 MEDIA_ERR_LOG("PacketHeader Parser fail err: %{public}d", errorCode);
179 return errorCode;
180 }
181 return MTP_SUCCESS;
182 }
183
ParserPayload()184 int MtpPacket::ParserPayload()
185 {
186 if (readSize_ <= 0) {
187 MEDIA_ERR_LOG("ParserPayload fail readSize_ <= 0");
188 return MTP_ERROR_PACKET_INCORRECT;
189 }
190 if (headerData_->GetCode() == 0) {
191 MEDIA_ERR_LOG("GetOperationCode fail");
192 return MTP_ERROR_PACKET_INCORRECT;
193 }
194
195 if (headerData_->GetContainerType() == 0) {
196 MEDIA_ERR_LOG("GetOperationCode fail");
197 return MTP_ERROR_PACKET_INCORRECT;
198 }
199
200 payloadData_ = PacketPayloadFactory::CreatePayload(context_,
201 headerData_->GetCode(), headerData_->GetContainerType());
202 if (payloadData_ == nullptr) {
203 MEDIA_ERR_LOG("payloadData_ is nullptr");
204 return MTP_FAIL;
205 }
206
207 int errorCode = payloadData_->Parser(readBuffer_, readSize_);
208 if (errorCode != MTP_SUCCESS) {
209 MEDIA_ERR_LOG("PacketHeader Parser fail err: %{public}d", errorCode);
210 }
211 return errorCode;
212 }
213
MakeHead()214 int MtpPacket::MakeHead()
215 {
216 if (headerData_ == nullptr) {
217 MEDIA_ERR_LOG("headerData_ is null!");
218 return MTP_SUCCESS;
219 }
220
221 int errorCode = headerData_->Maker(writeBuffer_);
222 if (errorCode != MTP_SUCCESS) {
223 MEDIA_ERR_LOG("HeaderData Make fail err: %{public}d", errorCode);
224 return errorCode;
225 }
226 return MTP_SUCCESS;
227 }
228
MakerPayload()229 int MtpPacket::MakerPayload()
230 {
231 if (payloadData_ == nullptr) {
232 MEDIA_ERR_LOG("payloadData_ is null!");
233 return MTP_SUCCESS;
234 }
235
236 int errorCode = payloadData_->Maker(writeBuffer_);
237 if (errorCode != MTP_SUCCESS) {
238 MEDIA_ERR_LOG("PayloadData Make fail err: %{public}d", errorCode);
239 return errorCode;
240 }
241 return MTP_SUCCESS;
242 }
243
GetOperationCode()244 uint16_t MtpPacket::GetOperationCode()
245 {
246 return headerData_->GetCode();
247 }
248
GetTransactionId()249 uint32_t MtpPacket::GetTransactionId()
250 {
251 return headerData_->GetTransactionId();
252 }
253
GetSessionID()254 uint32_t MtpPacket::GetSessionID()
255 {
256 return 0;
257 }
258 } // namespace Media
259 } // namespace OHOS
260