• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &notifyData, 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