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