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