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