1 /*
2 * Copyright (c) 2024 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
16 #include "response_message_receiver.h"
17
18 #include <unistd.h>
19
20 #include <cstdint>
21 #include <cstdlib>
22 #include <sstream>
23 #include <string>
24 #include <vector>
25
26 #include "log.h"
27 #include "sys_event.h"
28
29 namespace OHOS::Request {
30
31 static constexpr int32_t INT64_SIZE = 8;
32 static constexpr int32_t INT32_SIZE = 4;
33 static constexpr int32_t INT16_SIZE = 2;
34 // static constexpr int32_t INT8_SIZE = 1;
35
36 std::shared_ptr<OHOS::AppExecFwk::EventHandler> serviceHandler_;
37
Int64FromParcel(int64_t & num,char * & parcel,int32_t & size)38 int32_t ResponseMessageReceiver::Int64FromParcel(int64_t &num, char *&parcel, int32_t &size)
39 {
40 if (size < INT64_SIZE) {
41 REQUEST_HILOGE("message not complete");
42 return -1;
43 }
44 num = *reinterpret_cast<int64_t *>(parcel);
45 parcel += INT64_SIZE;
46 size -= INT64_SIZE;
47 return 0;
48 }
49
Uint64FromParcel(uint64_t & num,char * & parcel,int32_t & size)50 int32_t ResponseMessageReceiver::Uint64FromParcel(uint64_t &num, char *&parcel, int32_t &size)
51 {
52 if (size < INT64_SIZE) {
53 REQUEST_HILOGE("message not complete");
54 return -1;
55 }
56 num = *reinterpret_cast<uint64_t *>(parcel);
57 parcel += INT64_SIZE;
58 size -= INT64_SIZE;
59 return 0;
60 }
61
Int32FromParcel(int32_t & num,char * & parcel,int32_t & size)62 int32_t ResponseMessageReceiver::Int32FromParcel(int32_t &num, char *&parcel, int32_t &size)
63 {
64 if (size < INT32_SIZE) {
65 REQUEST_HILOGE("message not complete");
66 return -1;
67 }
68 num = *reinterpret_cast<int32_t *>(parcel);
69 parcel += INT32_SIZE;
70 size -= INT32_SIZE;
71 return 0;
72 }
73
Uint32FromParcel(uint32_t & num,char * & parcel,int32_t & size)74 int32_t ResponseMessageReceiver::Uint32FromParcel(uint32_t &num, char *&parcel, int32_t &size)
75 {
76 if (size < INT32_SIZE) {
77 REQUEST_HILOGE("message not complete");
78 return -1;
79 }
80 num = *reinterpret_cast<uint32_t *>(parcel);
81 parcel += INT32_SIZE;
82 size -= INT32_SIZE;
83 return 0;
84 }
85
Int16FromParcel(int16_t & num,char * & parcel,int32_t & size)86 int32_t ResponseMessageReceiver::Int16FromParcel(int16_t &num, char *&parcel, int32_t &size)
87 {
88 if (size < INT16_SIZE) {
89 REQUEST_HILOGE("message not complete");
90 return -1;
91 }
92 num = *reinterpret_cast<int16_t *>(parcel);
93 parcel += INT16_SIZE;
94 size -= INT16_SIZE;
95 return 0;
96 }
97
StateFromParcel(State & state,char * & parcel,int32_t & size)98 int32_t ResponseMessageReceiver::StateFromParcel(State &state, char *&parcel, int32_t &size)
99 {
100 uint32_t temp;
101 if (Uint32FromParcel(temp, parcel, size) || temp > static_cast<uint32_t>(State::ANY)) {
102 return -1;
103 }
104 state = static_cast<State>(temp);
105 return 0;
106 }
107
ActionFromParcel(Action & action,char * & parcel,int32_t & size)108 int32_t ResponseMessageReceiver::ActionFromParcel(Action &action, char *&parcel, int32_t &size)
109 {
110 uint32_t temp;
111 if (Uint32FromParcel(temp, parcel, size) || temp > static_cast<uint32_t>(Action::ANY)) {
112 return -1;
113 }
114 action = static_cast<Action>(temp);
115 return 0;
116 }
117
VersionFromParcel(Version & version,char * & parcel,int32_t & size)118 int32_t ResponseMessageReceiver::VersionFromParcel(Version &version, char *&parcel, int32_t &size)
119 {
120 uint32_t temp;
121 if (Uint32FromParcel(temp, parcel, size) || temp > static_cast<uint32_t>(Version::API10)) {
122 return -1;
123 }
124 version = static_cast<Version>(temp);
125 return 0;
126 }
127
SubscribeTypeFromParcel(SubscribeType & type,char * & parcel,int32_t & size)128 int32_t ResponseMessageReceiver::SubscribeTypeFromParcel(SubscribeType &type, char *&parcel, int32_t &size)
129 {
130 uint32_t temp;
131 if (Uint32FromParcel(temp, parcel, size) || temp > static_cast<uint32_t>(SubscribeType::BUTT)) {
132 return -1;
133 }
134 type = static_cast<SubscribeType>(temp);
135 return 0;
136 }
137
StringFromParcel(std::string & str,char * & parcel,int32_t & size)138 int32_t ResponseMessageReceiver::StringFromParcel(std::string &str, char *&parcel, int32_t &size)
139 {
140 int32_t i = 0;
141
142 while (i < size && parcel[i] != '\0') {
143 ++i;
144 }
145
146 if (i < size) {
147 str.assign(parcel, i);
148 parcel += (i + 1);
149 size -= (i + 1);
150 return 0;
151 } else {
152 REQUEST_HILOGE("message not complete");
153 return -1;
154 }
155 }
156
ResponseHeaderFromParcel(std::map<std::string,std::vector<std::string>> & headers,char * & parcel,int32_t & size)157 int32_t ResponseMessageReceiver::ResponseHeaderFromParcel(
158 std::map<std::string, std::vector<std::string>> &headers, char *&parcel, int32_t &size)
159 {
160 std::string s(parcel, size);
161 std::stringstream ss(s);
162 std::string line;
163 while (std::getline(ss, line, '\n')) {
164 std::stringstream keyValue(line);
165 std::string key;
166 std::string valueLine;
167 std::getline(keyValue, key, ':');
168 std::getline(keyValue, valueLine);
169 std::stringstream values(valueLine);
170 std::string value;
171 while (getline(values, value, ',')) {
172 headers[key].push_back(value);
173 }
174 }
175 return 0;
176 }
177
ProgressExtrasFromParcel(std::map<std::string,std::string> & extras,char * & parcel,int32_t & size)178 int32_t ResponseMessageReceiver::ProgressExtrasFromParcel(
179 std::map<std::string, std::string> &extras, char *&parcel, int32_t &size)
180 {
181 uint32_t length;
182 if (Uint32FromParcel(length, parcel, size)) {
183 return -1;
184 }
185
186 for (uint32_t i = 0; i < length; ++i) {
187 std::string key;
188 std::string value;
189 if (StringFromParcel(key, parcel, size) != 0) {
190 return -1;
191 }
192 if (StringFromParcel(value, parcel, size) != 0) {
193 return -1;
194 }
195 extras[key] = value;
196 }
197
198 return 0;
199 }
200
VecInt64FromParcel(std::vector<int64_t> & vec,char * & parcel,int32_t & size)201 int32_t ResponseMessageReceiver::VecInt64FromParcel(std::vector<int64_t> &vec, char *&parcel, int32_t &size)
202 {
203 uint32_t length;
204 if (Uint32FromParcel(length, parcel, size)) {
205 return -1;
206 }
207 for (uint32_t i = 0; i < length; ++i) {
208 int64_t value;
209 if (Int64FromParcel(value, parcel, size)) {
210 return -1;
211 }
212 vec.push_back(value);
213 }
214
215 return 0;
216 }
217
ResponseMessageReceiver(IResponseMessageHandler * handler,int32_t sockFd)218 ResponseMessageReceiver::ResponseMessageReceiver(IResponseMessageHandler *handler, int32_t sockFd)
219 : handler_(handler), sockFd_(sockFd)
220 {
221 }
222
BeginReceive()223 void ResponseMessageReceiver::BeginReceive()
224 {
225 std::shared_ptr<OHOS::AppExecFwk::EventRunner> runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner();
226 if (!runner) {
227 SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_10, "GetMainEventRunner failed");
228 }
229 serviceHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
230 auto err = serviceHandler_->AddFileDescriptorListener(
231 sockFd_, OHOS::AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, shared_from_this(), "subscribe");
232 if (err != ERR_OK) {
233 REQUEST_HILOGE("handler addlisterner err: %{public}d", err);
234 SysEventLog::SendSysEventLog(FAULT_EVENT, ABMS_FAULT_11, "handler addlisterner err");
235 }
236 }
237
238 // ret 0 if success, ret < 0 if fail
MsgHeaderParcel(int32_t & msgId,int16_t & msgType,int16_t & bodySize,char * & parcel,int32_t & size)239 int32_t ResponseMessageReceiver::MsgHeaderParcel(
240 int32_t &msgId, int16_t &msgType, int16_t &bodySize, char *&parcel, int32_t &size)
241 {
242 int32_t magicNum = 0;
243 if (Int32FromParcel(magicNum, parcel, size) != 0) {
244 return -1;
245 }
246 if (magicNum != ResponseMessageReceiver::RESPONSE_MAGIC_NUM) {
247 REQUEST_HILOGE("Bad magic num, %{public}d", magicNum);
248 return -1;
249 }
250
251 if (Int32FromParcel(msgId, parcel, size) != 0) {
252 return -1;
253 }
254 if (Int16FromParcel(msgType, parcel, size) != 0) {
255 return -1;
256 }
257 if (Int16FromParcel(bodySize, parcel, size) != 0) {
258 return -1;
259 }
260 return 0;
261 }
262
ResponseFromParcel(std::shared_ptr<Response> & response,char * & parcel,int32_t & size)263 int32_t ResponseMessageReceiver::ResponseFromParcel(std::shared_ptr<Response> &response, char *&parcel, int32_t &size)
264 {
265 int32_t tid;
266 if (Int32FromParcel(tid, parcel, size) != 0) {
267 REQUEST_HILOGE("Bad tid");
268 return -1;
269 }
270 response->taskId = std::to_string(tid);
271
272 if (StringFromParcel(response->version, parcel, size) != 0) {
273 REQUEST_HILOGE("Bad version");
274 return -1;
275 }
276
277 if (Int32FromParcel(response->statusCode, parcel, size) != 0) {
278 REQUEST_HILOGE("Bad statusCode");
279 return -1;
280 }
281
282 if (StringFromParcel(response->reason, parcel, size) != 0) {
283 REQUEST_HILOGE("Bad reason");
284 return -1;
285 }
286
287 ResponseHeaderFromParcel(response->headers, parcel, size);
288 return 0;
289 }
290
TaskStatesFromParcel(std::vector<TaskState> & taskStates,char * & parcel,int32_t & size)291 int32_t ResponseMessageReceiver::TaskStatesFromParcel(std::vector<TaskState> &taskStates, char *&parcel, int32_t &size)
292 {
293 uint32_t length;
294 if (Uint32FromParcel(length, parcel, size) != 0) {
295 REQUEST_HILOGE("Bad type");
296 return -1;
297 }
298 for (uint32_t i = 0; i < length; ++i) {
299 TaskState taskState;
300 if (StringFromParcel(taskState.path, parcel, size) != 0) {
301 REQUEST_HILOGE("Bad path");
302 return -1;
303 }
304 if (Uint32FromParcel(taskState.responseCode, parcel, size) != 0) {
305 REQUEST_HILOGE("Bad responseCode");
306 return -1;
307 }
308 if (StringFromParcel(taskState.message, parcel, size) != 0) {
309 REQUEST_HILOGE("Bad message");
310 return -1;
311 }
312 taskStates.push_back(taskState);
313 }
314 return 0;
315 }
316
NotifyDataFromParcel(std::shared_ptr<NotifyData> & notifyData,char * & parcel,int32_t & size)317 int32_t ResponseMessageReceiver::NotifyDataFromParcel(
318 std::shared_ptr<NotifyData> ¬ifyData, char *&parcel, int32_t &size)
319 {
320 if (SubscribeTypeFromParcel(notifyData->type, parcel, size) != 0) {
321 REQUEST_HILOGE("Bad type");
322 return -1;
323 }
324 if (Uint32FromParcel(notifyData->taskId, parcel, size) != 0) {
325 REQUEST_HILOGE("Bad tid");
326 return -1;
327 }
328 if (StateFromParcel(notifyData->progress.state, parcel, size) != 0) {
329 REQUEST_HILOGE("Bad state");
330 return -1;
331 }
332 if (Uint32FromParcel(notifyData->progress.index, parcel, size) != 0) {
333 REQUEST_HILOGE("Bad index");
334 return -1;
335 }
336 if (Uint64FromParcel(notifyData->progress.processed, parcel, size) != 0) {
337 REQUEST_HILOGE("Bad processed");
338 return -1;
339 }
340 if (Uint64FromParcel(notifyData->progress.totalProcessed, parcel, size) != 0) {
341 REQUEST_HILOGE("Bad totalProcessed");
342 return -1;
343 }
344 if (VecInt64FromParcel(notifyData->progress.sizes, parcel, size) != 0) {
345 REQUEST_HILOGE("Bad sizes");
346 return -1;
347 }
348 if (ProgressExtrasFromParcel(notifyData->progress.extras, parcel, size) != 0) {
349 REQUEST_HILOGE("Bad extras");
350 return -1;
351 }
352
353 if (ActionFromParcel(notifyData->action, parcel, size) != 0) {
354 REQUEST_HILOGE("Bad action");
355 return -1;
356 }
357 if (VersionFromParcel(notifyData->version, parcel, size) != 0) {
358 REQUEST_HILOGE("Bad version");
359 return -1;
360 }
361 if (TaskStatesFromParcel(notifyData->taskStates, parcel, size) != 0) {
362 REQUEST_HILOGE("Bad taskStates");
363 return -1;
364 }
365 return 0;
366 }
367
OnReadable(int32_t fd)368 void ResponseMessageReceiver::OnReadable(int32_t fd)
369 {
370 int readSize = ResponseMessageReceiver::RESPONSE_MAX_SIZE;
371 char buffer[readSize];
372 int32_t length = read(fd, buffer, readSize);
373 if (length <= 0) {
374 return;
375 }
376 REQUEST_HILOGD("read message: %{public}d", length);
377
378 char lenBuf[4];
379 *reinterpret_cast<uint32_t *>(lenBuf) = length;
380 int32_t ret = write(fd, lenBuf, 4);
381 if (ret <= 0) {
382 REQUEST_HILOGE("send length back failed: %{public}d", ret);
383 SysEventLog::SendSysEventLog(FAULT_EVENT, UDS_FAULT_02, "write" + std::to_string(ret));
384 }
385 char *leftBuf = buffer;
386 int32_t leftLen = length;
387 int32_t msgId = -1;
388 int16_t msgType = -1;
389 int16_t headerSize = -1;
390 MsgHeaderParcel(msgId, msgType, headerSize, leftBuf, leftLen);
391 if (msgId != messageId_) {
392 REQUEST_HILOGE("Bad messageId, expect %{public}d = %{public}d", msgId, messageId_);
393 SysEventLog::SendSysEventLog(FAULT_EVENT, UDS_FAULT_01, msgId, messageId_);
394 }
395 if (headerSize != static_cast<int16_t>(length)) {
396 REQUEST_HILOGE("Bad headerSize, %{public}d, %{public}d", length, headerSize);
397 SysEventLog::SendSysEventLog(FAULT_EVENT, UDS_FAULT_01, headerSize, length);
398 }
399 ++messageId_;
400
401 if (msgType == MessageType::HTTP_RESPONSE) {
402 std::shared_ptr<Response> response = std::make_shared<Response>();
403 if (ResponseFromParcel(response, leftBuf, leftLen) == 0) {
404 this->handler_->OnResponseReceive(response);
405 } else {
406 REQUEST_HILOGE("Bad Response");
407 SysEventLog::SendSysEventLog(FAULT_EVENT, UDS_FAULT_01, "Bad Response");
408 }
409 } else if (msgType == MessageType::NOTIFY_DATA) {
410 std::shared_ptr<NotifyData> notifyData = std::make_shared<NotifyData>();
411 if (NotifyDataFromParcel(notifyData, leftBuf, leftLen) == 0) {
412 this->handler_->OnNotifyDataReceive(notifyData);
413 } else {
414 REQUEST_HILOGE("Bad NotifyData");
415 SysEventLog::SendSysEventLog(FAULT_EVENT, UDS_FAULT_01, "Bad NotifyData");
416 }
417 }
418 }
419
OnShutdown(int32_t fd)420 void ResponseMessageReceiver::OnShutdown(int32_t fd)
421 {
422 REQUEST_HILOGI("uds OnShutdown, %{public}d", fd);
423 serviceHandler_->RemoveFileDescriptorListener(fd);
424 close(fd);
425 this->handler_->OnChannelBroken();
426 }
427
OnException(int32_t fd)428 void ResponseMessageReceiver::OnException(int32_t fd)
429 {
430 REQUEST_HILOGI("uds OnException, %{public}d", fd);
431 serviceHandler_->RemoveFileDescriptorListener(fd);
432 close(fd);
433 this->handler_->OnChannelBroken();
434 }
435
Shutdown()436 void ResponseMessageReceiver::Shutdown()
437 {
438 REQUEST_HILOGI("uds shutdown, %{public}d", sockFd_);
439 serviceHandler_->RemoveFileDescriptorListener(sockFd_);
440 close(sockFd_);
441 this->handler_->OnChannelBroken();
442 }
443
444 } // namespace OHOS::Request