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