1 /*
2 * Copyright (c) 2021-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
16 #include "uds_socket.h"
17
18 #include <cinttypes>
19
20 #include "error_multimodal.h"
21 #include "mmi_log.h"
22
23 #undef MMI_LOG_TAG
24 #define MMI_LOG_TAG "UDSSocket"
25
26 namespace OHOS {
27 namespace MMI {
UDSSocket()28 UDSSocket::UDSSocket() {}
29
~UDSSocket()30 UDSSocket::~UDSSocket()
31 {
32 Close();
33 EpollClose();
34 }
35
EpollCreate(int32_t size)36 int32_t UDSSocket::EpollCreate(int32_t size)
37 {
38 epollFd_ = epoll_create(size);
39 if (epollFd_ < 0) {
40 MMI_HILOGE("epoll_create return %{public}d", epollFd_);
41 } else {
42 MMI_HILOGI("epoll_create, epollFd_:%{public}d", epollFd_);
43 }
44 return epollFd_;
45 }
46
EpollCtl(int32_t fd,int32_t op,struct epoll_event & event,int32_t epollFd)47 int32_t UDSSocket::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event, int32_t epollFd)
48 {
49 if (fd < 0) {
50 MMI_HILOGE("Invalid fd");
51 return RET_ERR;
52 }
53 if (epollFd < 0) {
54 epollFd = epollFd_;
55 }
56 if (epollFd < 0) {
57 MMI_HILOGE("Invalid param epollFd");
58 return RET_ERR;
59 }
60 int32_t ret;
61 if (op == EPOLL_CTL_DEL) {
62 ret = epoll_ctl(epollFd, op, fd, nullptr);
63 } else {
64 ret = epoll_ctl(epollFd, op, fd, &event);
65 }
66 if (ret < 0) {
67 MMI_HILOGE("epoll_ctl return %{public}d,epollFd_:%{public}d,"
68 "op:%{public}d,fd:%{public}d,errno:%{public}d",
69 ret, epollFd, op, fd, errno);
70 }
71 return ret;
72 }
73
EpollWait(struct epoll_event & events,int32_t maxevents,int32_t timeout,int32_t epollFd)74 int32_t UDSSocket::EpollWait(struct epoll_event &events, int32_t maxevents, int32_t timeout, int32_t epollFd)
75 {
76 if (epollFd < 0) {
77 epollFd = epollFd_;
78 }
79 if (epollFd < 0) {
80 MMI_HILOGE("Invalid param epollFd");
81 return RET_ERR;
82 }
83 auto ret = epoll_wait(epollFd, &events, maxevents, timeout);
84 if (ret < 0) {
85 MMI_HILOGE("epoll_wait ret:%{public}d,errno:%{public}d", ret, errno);
86 }
87 return ret;
88 }
89
OnReadPackets(CircleStreamBuffer & circBuf,UDSSocket::PacketCallBackFun callbackFun)90 void UDSSocket::OnReadPackets(CircleStreamBuffer &circBuf, UDSSocket::PacketCallBackFun callbackFun)
91 {
92 constexpr int32_t headSize = static_cast<int32_t>(sizeof(PackHead));
93 while (!circBuf.IsEmpty()) {
94 const int32_t unreadSize = circBuf.UnreadSize();
95 if (unreadSize < headSize) {
96 break;
97 }
98 int32_t dataSize = unreadSize - headSize;
99 char *buf = const_cast<char *>(circBuf.ReadBuf());
100 CHKPB(buf);
101 PackHead *head = reinterpret_cast<PackHead *>(buf);
102 CHKPB(head);
103 if (head->size < 0 || head->size > MAX_PACKET_BUF_SIZE) {
104 MMI_HILOGF("Packet header parsing error, and this error cannot be recovered. The buffer will be reset."
105 " head->size:%{public}d, unreadSize:%{public}d", head->size, unreadSize);
106 circBuf.Reset();
107 break;
108 }
109 if (head->size > dataSize) {
110 break;
111 }
112 NetPacket pkt(head->idMsg);
113 if ((head->size > 0) && (!pkt.Write(&buf[headSize], head->size))) {
114 MMI_HILOGW("Error writing data in the NetPacket. It will be retried next time. messageid:%{public}d,"
115 "size:%{public}d", head->idMsg, head->size);
116 break;
117 }
118 if (!circBuf.SeekReadPos(pkt.GetPacketLength())) {
119 MMI_HILOGW("Set read position error, and this error cannot be recovered, and the buffer will be reset."
120 " packetSize:%{public}d unreadSize:%{public}d", pkt.GetPacketLength(), unreadSize);
121 circBuf.Reset();
122 break;
123 }
124 callbackFun(pkt);
125 if (circBuf.IsEmpty()) {
126 circBuf.Reset();
127 break;
128 }
129 }
130 }
131
EpollClose()132 void UDSSocket::EpollClose()
133 {
134 if (epollFd_ >= 0) {
135 close(epollFd_);
136 epollFd_ = -1;
137 }
138 }
139
Close()140 void UDSSocket::Close()
141 {
142 if (fd_ >= 0) {
143 auto rf = close(fd_);
144 if (rf > 0) {
145 MMI_HILOGE("Socket close failed rf:%{public}d", rf);
146 }
147 }
148 fd_ = -1;
149 }
150 } // namespace MMI
151 } // namespace OHOS