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