• 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 "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> &notifyData, 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