1c29fa5a6Sopenharmony_ci/*
2c29fa5a6Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License.
5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at
6c29fa5a6Sopenharmony_ci *
7c29fa5a6Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8c29fa5a6Sopenharmony_ci *
9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and
13c29fa5a6Sopenharmony_ci * limitations under the License.
14c29fa5a6Sopenharmony_ci */
15c29fa5a6Sopenharmony_ci
16c29fa5a6Sopenharmony_ci#include "uds_server.h"
17c29fa5a6Sopenharmony_ci
18c29fa5a6Sopenharmony_ci#include <cinttypes>
19c29fa5a6Sopenharmony_ci#include <list>
20c29fa5a6Sopenharmony_ci
21c29fa5a6Sopenharmony_ci#include <sys/socket.h>
22c29fa5a6Sopenharmony_ci
23c29fa5a6Sopenharmony_ci#include "dfx_hisysevent.h"
24c29fa5a6Sopenharmony_ci#include "i_multimodal_input_connect.h"
25c29fa5a6Sopenharmony_ci#include "mmi_log.h"
26c29fa5a6Sopenharmony_ci#include "multimodalinput_ipc_interface_code.h"
27c29fa5a6Sopenharmony_ci#include "util.h"
28c29fa5a6Sopenharmony_ci#include "util_ex.h"
29c29fa5a6Sopenharmony_ci
30c29fa5a6Sopenharmony_ci#undef MMI_LOG_DOMAIN
31c29fa5a6Sopenharmony_ci#define MMI_LOG_DOMAIN MMI_LOG_SERVER
32c29fa5a6Sopenharmony_ci#undef MMI_LOG_TAG
33c29fa5a6Sopenharmony_ci#define MMI_LOG_TAG "UDSServer"
34c29fa5a6Sopenharmony_ci
35c29fa5a6Sopenharmony_cinamespace OHOS {
36c29fa5a6Sopenharmony_cinamespace MMI {
37c29fa5a6Sopenharmony_ciUDSServer::~UDSServer()
38c29fa5a6Sopenharmony_ci{
39c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
40c29fa5a6Sopenharmony_ci    UdsStop();
41c29fa5a6Sopenharmony_ci}
42c29fa5a6Sopenharmony_ci
43c29fa5a6Sopenharmony_civoid UDSServer::UdsStop()
44c29fa5a6Sopenharmony_ci{
45c29fa5a6Sopenharmony_ci    if (epollFd_ != -1) {
46c29fa5a6Sopenharmony_ci        close(epollFd_);
47c29fa5a6Sopenharmony_ci        epollFd_ = -1;
48c29fa5a6Sopenharmony_ci    }
49c29fa5a6Sopenharmony_ci
50c29fa5a6Sopenharmony_ci    for (const auto &item : sessionsMap_) {
51c29fa5a6Sopenharmony_ci        item.second->Close();
52c29fa5a6Sopenharmony_ci    }
53c29fa5a6Sopenharmony_ci    sessionsMap_.clear();
54c29fa5a6Sopenharmony_ci}
55c29fa5a6Sopenharmony_ci
56c29fa5a6Sopenharmony_ciint32_t UDSServer::GetClientFd(int32_t pid) const
57c29fa5a6Sopenharmony_ci{
58c29fa5a6Sopenharmony_ci    auto it = idxPidMap_.find(pid);
59c29fa5a6Sopenharmony_ci    if (it == idxPidMap_.end()) {
60c29fa5a6Sopenharmony_ci        if (pid_ != pid) {
61c29fa5a6Sopenharmony_ci            pid_ = pid;
62c29fa5a6Sopenharmony_ci            MMI_HILOGE("Not found pid:%{public}d", pid);
63c29fa5a6Sopenharmony_ci        }
64c29fa5a6Sopenharmony_ci        return INVALID_FD;
65c29fa5a6Sopenharmony_ci    }
66c29fa5a6Sopenharmony_ci    return it->second;
67c29fa5a6Sopenharmony_ci}
68c29fa5a6Sopenharmony_ci
69c29fa5a6Sopenharmony_ciint32_t UDSServer::GetClientPid(int32_t fd) const
70c29fa5a6Sopenharmony_ci{
71c29fa5a6Sopenharmony_ci    auto it = sessionsMap_.find(fd);
72c29fa5a6Sopenharmony_ci    if (it == sessionsMap_.end()) {
73c29fa5a6Sopenharmony_ci        MMI_HILOGE("Not found fd:%{public}d", fd);
74c29fa5a6Sopenharmony_ci        return INVALID_PID;
75c29fa5a6Sopenharmony_ci    }
76c29fa5a6Sopenharmony_ci    return it->second->GetPid();
77c29fa5a6Sopenharmony_ci}
78c29fa5a6Sopenharmony_ci
79c29fa5a6Sopenharmony_cibool UDSServer::SendMsg(int32_t fd, NetPacket& pkt)
80c29fa5a6Sopenharmony_ci{
81c29fa5a6Sopenharmony_ci    if (fd < 0) {
82c29fa5a6Sopenharmony_ci        MMI_HILOGE("The fd is less than 0");
83c29fa5a6Sopenharmony_ci        return false;
84c29fa5a6Sopenharmony_ci    }
85c29fa5a6Sopenharmony_ci    auto ses = GetSession(fd);
86c29fa5a6Sopenharmony_ci    if (ses == nullptr) {
87c29fa5a6Sopenharmony_ci        MMI_HILOGE("The fd:%{public}d not found, The message was discarded. errCode:%{public}d",
88c29fa5a6Sopenharmony_ci                   fd, SESSION_NOT_FOUND);
89c29fa5a6Sopenharmony_ci        return false;
90c29fa5a6Sopenharmony_ci    }
91c29fa5a6Sopenharmony_ci    return ses->SendMsg(pkt);
92c29fa5a6Sopenharmony_ci}
93c29fa5a6Sopenharmony_ci
94c29fa5a6Sopenharmony_civoid UDSServer::Multicast(const std::vector<int32_t>& fdList, NetPacket& pkt)
95c29fa5a6Sopenharmony_ci{
96c29fa5a6Sopenharmony_ci    for (const auto &item : fdList) {
97c29fa5a6Sopenharmony_ci        SendMsg(item, pkt);
98c29fa5a6Sopenharmony_ci    }
99c29fa5a6Sopenharmony_ci}
100c29fa5a6Sopenharmony_ci
101c29fa5a6Sopenharmony_ciint32_t UDSServer::AddSocketPairInfo(const std::string& programName,
102c29fa5a6Sopenharmony_ci    const int32_t moduleType, const int32_t uid, const int32_t pid,
103c29fa5a6Sopenharmony_ci    int32_t& serverFd, int32_t& toReturnClientFd, int32_t& tokenType)
104c29fa5a6Sopenharmony_ci{
105c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
106c29fa5a6Sopenharmony_ci    int32_t sockFds[2] = { -1 };
107c29fa5a6Sopenharmony_ci
108c29fa5a6Sopenharmony_ci    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockFds) != 0) {
109c29fa5a6Sopenharmony_ci        MMI_HILOGE("Call socketpair failed, errno:%{public}d", errno);
110c29fa5a6Sopenharmony_ci        return RET_ERR;
111c29fa5a6Sopenharmony_ci    }
112c29fa5a6Sopenharmony_ci    serverFd = sockFds[0];
113c29fa5a6Sopenharmony_ci    toReturnClientFd = sockFds[1];
114c29fa5a6Sopenharmony_ci    if (serverFd < 0 || toReturnClientFd < 0) {
115c29fa5a6Sopenharmony_ci        MMI_HILOGE("Call fcntl failed, errno:%{public}d", errno);
116c29fa5a6Sopenharmony_ci        return RET_ERR;
117c29fa5a6Sopenharmony_ci    }
118c29fa5a6Sopenharmony_ci
119c29fa5a6Sopenharmony_ci    SessionPtr sess = nullptr;
120c29fa5a6Sopenharmony_ci    if (SetFdProperty(tokenType, serverFd, toReturnClientFd) != RET_OK) {
121c29fa5a6Sopenharmony_ci        MMI_HILOGE("SetFdProperty failed");
122c29fa5a6Sopenharmony_ci        goto CLOSE_SOCK;
123c29fa5a6Sopenharmony_ci    }
124c29fa5a6Sopenharmony_ci
125c29fa5a6Sopenharmony_ci    if (AddEpoll(EPOLL_EVENT_SOCKET, serverFd) != RET_OK) {
126c29fa5a6Sopenharmony_ci        MMI_HILOGE("epoll_ctl EPOLL_CTL_ADD failed, errCode:%{public}d", EPOLL_MODIFY_FAIL);
127c29fa5a6Sopenharmony_ci        goto CLOSE_SOCK;
128c29fa5a6Sopenharmony_ci    }
129c29fa5a6Sopenharmony_ci    sess = std::make_shared<UDSSession>(programName, moduleType, serverFd, uid, pid);
130c29fa5a6Sopenharmony_ci    if (sess == nullptr) {
131c29fa5a6Sopenharmony_ci        MMI_HILOGE("make_shared fail. programName:%{public}s, pid:%{public}d, errCode:%{public}d",
132c29fa5a6Sopenharmony_ci            programName.c_str(), pid, MAKE_SHARED_FAIL);
133c29fa5a6Sopenharmony_ci        goto CLOSE_SOCK;
134c29fa5a6Sopenharmony_ci    }
135c29fa5a6Sopenharmony_ci    sess->SetTokenType(tokenType);
136c29fa5a6Sopenharmony_ci    if (!AddSession(sess)) {
137c29fa5a6Sopenharmony_ci        MMI_HILOGE("AddSession fail errCode:%{public}d", ADD_SESSION_FAIL);
138c29fa5a6Sopenharmony_ci        goto CLOSE_SOCK;
139c29fa5a6Sopenharmony_ci    }
140c29fa5a6Sopenharmony_ci    OnConnected(sess);
141c29fa5a6Sopenharmony_ci    return RET_OK;
142c29fa5a6Sopenharmony_ci
143c29fa5a6Sopenharmony_ci    CLOSE_SOCK:
144c29fa5a6Sopenharmony_ci    close(serverFd);
145c29fa5a6Sopenharmony_ci    serverFd = IMultimodalInputConnect::INVALID_SOCKET_FD;
146c29fa5a6Sopenharmony_ci    close(toReturnClientFd);
147c29fa5a6Sopenharmony_ci    toReturnClientFd = IMultimodalInputConnect::INVALID_SOCKET_FD;
148c29fa5a6Sopenharmony_ci    return RET_ERR;
149c29fa5a6Sopenharmony_ci}
150c29fa5a6Sopenharmony_ci
151c29fa5a6Sopenharmony_ciint32_t UDSServer::SetFdProperty(int32_t& tokenType, int32_t& serverFd, int32_t& toReturnClientFd)
152c29fa5a6Sopenharmony_ci{
153c29fa5a6Sopenharmony_ci    static size_t bufferSize = 64 * 1024;
154c29fa5a6Sopenharmony_ci    static size_t serverBufferSize = 64 * 1024;
155c29fa5a6Sopenharmony_ci    static size_t nativeBufferSize = 128 * 1024;
156c29fa5a6Sopenharmony_ci#ifdef OHOS_BUILD_ENABLE_ANCO
157c29fa5a6Sopenharmony_ci    bufferSize = 512 * 1024;
158c29fa5a6Sopenharmony_ci    nativeBufferSize = 1024 * 1024;
159c29fa5a6Sopenharmony_ci#endif // OHOS_BUILD_ENABLE_ANCO
160c29fa5a6Sopenharmony_ci
161c29fa5a6Sopenharmony_ci    if (setsockopt(serverFd, SOL_SOCKET, SO_SNDBUF, &serverBufferSize, sizeof(bufferSize)) != 0) {
162c29fa5a6Sopenharmony_ci        MMI_HILOGE("Setsockopt serverFd failed, errno:%{public}d", errno);
163c29fa5a6Sopenharmony_ci        return RET_ERR;
164c29fa5a6Sopenharmony_ci    }
165c29fa5a6Sopenharmony_ci    if (setsockopt(serverFd, SOL_SOCKET, SO_RCVBUF, &serverBufferSize, sizeof(bufferSize)) != 0) {
166c29fa5a6Sopenharmony_ci        MMI_HILOGE("Setsockopt serverFd failed, errno:%{public}d", errno);
167c29fa5a6Sopenharmony_ci        return RET_ERR;
168c29fa5a6Sopenharmony_ci    }
169c29fa5a6Sopenharmony_ci    if (tokenType == TokenType::TOKEN_NATIVE) {
170c29fa5a6Sopenharmony_ci        if (setsockopt(toReturnClientFd, SOL_SOCKET, SO_SNDBUF, &nativeBufferSize, sizeof(nativeBufferSize)) != 0) {
171c29fa5a6Sopenharmony_ci            MMI_HILOGE("Setsockopt toReturnClientFd failed, errno:%{public}d", errno);
172c29fa5a6Sopenharmony_ci            return RET_ERR;
173c29fa5a6Sopenharmony_ci        }
174c29fa5a6Sopenharmony_ci        if (setsockopt(toReturnClientFd, SOL_SOCKET, SO_RCVBUF, &nativeBufferSize, sizeof(nativeBufferSize)) != 0) {
175c29fa5a6Sopenharmony_ci            MMI_HILOGE("Setsockopt toReturnClientFd failed, errno:%{public}d", errno);
176c29fa5a6Sopenharmony_ci            return RET_ERR;
177c29fa5a6Sopenharmony_ci        }
178c29fa5a6Sopenharmony_ci    } else {
179c29fa5a6Sopenharmony_ci        if (setsockopt(toReturnClientFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) {
180c29fa5a6Sopenharmony_ci            MMI_HILOGE("Setsockopt toReturnClientFd failed, errno:%{public}d", errno);
181c29fa5a6Sopenharmony_ci            return RET_ERR;
182c29fa5a6Sopenharmony_ci        }
183c29fa5a6Sopenharmony_ci        if (setsockopt(toReturnClientFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) {
184c29fa5a6Sopenharmony_ci            MMI_HILOGE("Setsockopt toReturnClientFd failed, errno:%{public}d", errno);
185c29fa5a6Sopenharmony_ci            return RET_ERR;
186c29fa5a6Sopenharmony_ci        }
187c29fa5a6Sopenharmony_ci    }
188c29fa5a6Sopenharmony_ci    return RET_OK;
189c29fa5a6Sopenharmony_ci}
190c29fa5a6Sopenharmony_ci
191c29fa5a6Sopenharmony_civoid UDSServer::Dump(int32_t fd, const std::vector<std::string> &args)
192c29fa5a6Sopenharmony_ci{
193c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
194c29fa5a6Sopenharmony_ci    mprintf(fd, "Uds_server information:\t");
195c29fa5a6Sopenharmony_ci    mprintf(fd, "uds_server: count=%zu", sessionsMap_.size());
196c29fa5a6Sopenharmony_ci    for (const auto &item : sessionsMap_) {
197c29fa5a6Sopenharmony_ci        std::shared_ptr<UDSSession> udsSession = item.second;
198c29fa5a6Sopenharmony_ci        CHKPV(udsSession);
199c29fa5a6Sopenharmony_ci        mprintf(fd,
200c29fa5a6Sopenharmony_ci                "Uid:%d | Pid:%d | Fd:%d | TokenType:%d | Descript:%s\t",
201c29fa5a6Sopenharmony_ci                udsSession->GetUid(), udsSession->GetPid(), udsSession->GetFd(),
202c29fa5a6Sopenharmony_ci                udsSession->GetTokenType(), udsSession->GetDescript().c_str());
203c29fa5a6Sopenharmony_ci    }
204c29fa5a6Sopenharmony_ci}
205c29fa5a6Sopenharmony_ci
206c29fa5a6Sopenharmony_civoid UDSServer::OnConnected(SessionPtr sess)
207c29fa5a6Sopenharmony_ci{
208c29fa5a6Sopenharmony_ci    CHKPV(sess);
209c29fa5a6Sopenharmony_ci    MMI_HILOGI("Session desc:%{public}s", sess->GetDescript().c_str());
210c29fa5a6Sopenharmony_ci}
211c29fa5a6Sopenharmony_ci
212c29fa5a6Sopenharmony_civoid UDSServer::OnDisconnected(SessionPtr sess)
213c29fa5a6Sopenharmony_ci{
214c29fa5a6Sopenharmony_ci    CHKPV(sess);
215c29fa5a6Sopenharmony_ci    MMI_HILOGI("Session desc:%{public}s", sess->GetDescript().c_str());
216c29fa5a6Sopenharmony_ci}
217c29fa5a6Sopenharmony_ci
218c29fa5a6Sopenharmony_ciint32_t UDSServer::AddEpoll(EpollEventType type, int32_t fd)
219c29fa5a6Sopenharmony_ci{
220c29fa5a6Sopenharmony_ci    MMI_HILOGE("This information should not exist. Subclasses should implement this function");
221c29fa5a6Sopenharmony_ci    return RET_ERR;
222c29fa5a6Sopenharmony_ci}
223c29fa5a6Sopenharmony_ci
224c29fa5a6Sopenharmony_civoid UDSServer::SetRecvFun(MsgServerFunCallback fun)
225c29fa5a6Sopenharmony_ci{
226c29fa5a6Sopenharmony_ci    recvFun_ = fun;
227c29fa5a6Sopenharmony_ci}
228c29fa5a6Sopenharmony_ci
229c29fa5a6Sopenharmony_civoid UDSServer::ReleaseSession(int32_t fd, epoll_event& ev)
230c29fa5a6Sopenharmony_ci{
231c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
232c29fa5a6Sopenharmony_ci    auto secPtr = GetSession(fd);
233c29fa5a6Sopenharmony_ci    if (secPtr != nullptr) {
234c29fa5a6Sopenharmony_ci        OnDisconnected(secPtr);
235c29fa5a6Sopenharmony_ci        DelSession(fd);
236c29fa5a6Sopenharmony_ci    } else {
237c29fa5a6Sopenharmony_ci        MMI_HILOGE("Get session secPtr is nullptr, fd:%{public}d", fd);
238c29fa5a6Sopenharmony_ci        DfxHisysevent::OnClientDisconnect(secPtr, fd, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
239c29fa5a6Sopenharmony_ci    }
240c29fa5a6Sopenharmony_ci    if (ev.data.ptr) {
241c29fa5a6Sopenharmony_ci        RemoveEpollEvent(fd);
242c29fa5a6Sopenharmony_ci        ev.data.ptr = nullptr;
243c29fa5a6Sopenharmony_ci    }
244c29fa5a6Sopenharmony_ci    if (auto it = circleBufMap_.find(fd); it != circleBufMap_.end()) {
245c29fa5a6Sopenharmony_ci        circleBufMap_.erase(it);
246c29fa5a6Sopenharmony_ci    } else {
247c29fa5a6Sopenharmony_ci        MMI_HILOGE("Can't find fd");
248c29fa5a6Sopenharmony_ci    }
249c29fa5a6Sopenharmony_ci    if (close(fd) == RET_OK) {
250c29fa5a6Sopenharmony_ci        DfxHisysevent::OnClientDisconnect(secPtr, fd, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
251c29fa5a6Sopenharmony_ci    } else {
252c29fa5a6Sopenharmony_ci        DfxHisysevent::OnClientDisconnect(secPtr, fd, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
253c29fa5a6Sopenharmony_ci    }
254c29fa5a6Sopenharmony_ci}
255c29fa5a6Sopenharmony_ci
256c29fa5a6Sopenharmony_civoid UDSServer::OnPacket(int32_t fd, NetPacket& pkt)
257c29fa5a6Sopenharmony_ci{
258c29fa5a6Sopenharmony_ci    auto sess = GetSession(fd);
259c29fa5a6Sopenharmony_ci    CHKPV(sess);
260c29fa5a6Sopenharmony_ci    recvFun_(sess, pkt);
261c29fa5a6Sopenharmony_ci}
262c29fa5a6Sopenharmony_ci
263c29fa5a6Sopenharmony_civoid UDSServer::OnEpollRecv(int32_t fd, epoll_event& ev)
264c29fa5a6Sopenharmony_ci{
265c29fa5a6Sopenharmony_ci    if (fd < 0) {
266c29fa5a6Sopenharmony_ci        MMI_HILOGE("Invalid input param fd:%{public}d", fd);
267c29fa5a6Sopenharmony_ci        return;
268c29fa5a6Sopenharmony_ci    }
269c29fa5a6Sopenharmony_ci    auto& buf = circleBufMap_[fd];
270c29fa5a6Sopenharmony_ci    char szBuf[MAX_PACKET_BUF_SIZE] = {};
271c29fa5a6Sopenharmony_ci    for (int32_t i = 0; i < MAX_RECV_LIMIT; i++) {
272c29fa5a6Sopenharmony_ci        auto size = recv(fd, szBuf, MAX_PACKET_BUF_SIZE, MSG_DONTWAIT | MSG_NOSIGNAL);
273c29fa5a6Sopenharmony_ci        if (size > 0) {
274c29fa5a6Sopenharmony_ci            if (!buf.Write(szBuf, size)) {
275c29fa5a6Sopenharmony_ci                MMI_HILOGW("Write data failed. size:%{public}zu", size);
276c29fa5a6Sopenharmony_ci            }
277c29fa5a6Sopenharmony_ci            OnReadPackets(buf, [this, fd] (NetPacket& pkt) { return this->OnPacket(fd, pkt); });
278c29fa5a6Sopenharmony_ci        } else if (size < 0) {
279c29fa5a6Sopenharmony_ci            if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
280c29fa5a6Sopenharmony_ci                MMI_HILOGD("Continue for errno EAGAIN|EINTR|EWOULDBLOCK size:%{public}zu, errno:%{public}d",
281c29fa5a6Sopenharmony_ci                    size, errno);
282c29fa5a6Sopenharmony_ci                continue;
283c29fa5a6Sopenharmony_ci            }
284c29fa5a6Sopenharmony_ci            MMI_HILOGE("Recv return %{public}zu errno:%{public}d", size, errno);
285c29fa5a6Sopenharmony_ci            break;
286c29fa5a6Sopenharmony_ci        } else {
287c29fa5a6Sopenharmony_ci            MMI_HILOGE("The client side disconnect with the server. size:0 errno:%{public}d", errno);
288c29fa5a6Sopenharmony_ci            ReleaseSession(fd, ev);
289c29fa5a6Sopenharmony_ci            break;
290c29fa5a6Sopenharmony_ci        }
291c29fa5a6Sopenharmony_ci        if (size < MAX_PACKET_BUF_SIZE) {
292c29fa5a6Sopenharmony_ci            break;
293c29fa5a6Sopenharmony_ci        }
294c29fa5a6Sopenharmony_ci    }
295c29fa5a6Sopenharmony_ci}
296c29fa5a6Sopenharmony_ci
297c29fa5a6Sopenharmony_civoid UDSServer::OnEpollEvent(epoll_event& ev)
298c29fa5a6Sopenharmony_ci{
299c29fa5a6Sopenharmony_ci    CHKPV(ev.data.ptr);
300c29fa5a6Sopenharmony_ci    auto fd = ev.data.fd;
301c29fa5a6Sopenharmony_ci    if (fd < 0) {
302c29fa5a6Sopenharmony_ci        MMI_HILOGE("The fd less than 0, errCode:%{public}d", PARAM_INPUT_INVALID);
303c29fa5a6Sopenharmony_ci        return;
304c29fa5a6Sopenharmony_ci    }
305c29fa5a6Sopenharmony_ci    if ((ev.events & EPOLLERR) || (ev.events & EPOLLHUP)) {
306c29fa5a6Sopenharmony_ci        MMI_HILOGI("EPOLLERR or EPOLLHUP fd:%{public}d, ev.events:0x%{public}x", fd, ev.events);
307c29fa5a6Sopenharmony_ci        ReleaseSession(fd, ev);
308c29fa5a6Sopenharmony_ci    } else if (ev.events & EPOLLIN) {
309c29fa5a6Sopenharmony_ci        OnEpollRecv(fd, ev);
310c29fa5a6Sopenharmony_ci    }
311c29fa5a6Sopenharmony_ci}
312c29fa5a6Sopenharmony_ci
313c29fa5a6Sopenharmony_civoid UDSServer::AddEpollEvent(int32_t fd, std::shared_ptr<mmi_epoll_event> epollEvent)
314c29fa5a6Sopenharmony_ci{
315c29fa5a6Sopenharmony_ci    MMI_HILOGI("Add %{public}d in epollEvent map", fd);
316c29fa5a6Sopenharmony_ci    epollEventMap_[fd] = epollEvent;
317c29fa5a6Sopenharmony_ci}
318c29fa5a6Sopenharmony_ci
319c29fa5a6Sopenharmony_civoid UDSServer::RemoveEpollEvent(int32_t fd)
320c29fa5a6Sopenharmony_ci{
321c29fa5a6Sopenharmony_ci    MMI_HILOGI("Remove %{public}d in epollEvent map", fd);
322c29fa5a6Sopenharmony_ci    epollEventMap_.erase(fd);
323c29fa5a6Sopenharmony_ci}
324c29fa5a6Sopenharmony_ci
325c29fa5a6Sopenharmony_civoid UDSServer::DumpSession(const std::string &title)
326c29fa5a6Sopenharmony_ci{
327c29fa5a6Sopenharmony_ci    MMI_HILOGD("in %s: %s", __func__, title.c_str());
328c29fa5a6Sopenharmony_ci    int32_t i = 0;
329c29fa5a6Sopenharmony_ci    for (auto &[key, value] : sessionsMap_) {
330c29fa5a6Sopenharmony_ci        CHKPV(value);
331c29fa5a6Sopenharmony_ci        MMI_HILOGD("%d, %s", i, value->GetDescript().c_str());
332c29fa5a6Sopenharmony_ci        i++;
333c29fa5a6Sopenharmony_ci    }
334c29fa5a6Sopenharmony_ci}
335c29fa5a6Sopenharmony_ci
336c29fa5a6Sopenharmony_ciSessionPtr UDSServer::GetSession(int32_t fd) const
337c29fa5a6Sopenharmony_ci{
338c29fa5a6Sopenharmony_ci    auto it = sessionsMap_.find(fd);
339c29fa5a6Sopenharmony_ci    if (it == sessionsMap_.end()) {
340c29fa5a6Sopenharmony_ci        MMI_HILOGE("Session not found. fd:%{public}d", fd);
341c29fa5a6Sopenharmony_ci        return nullptr;
342c29fa5a6Sopenharmony_ci    }
343c29fa5a6Sopenharmony_ci    CHKPP(it->second);
344c29fa5a6Sopenharmony_ci    return it->second->GetSharedPtr();
345c29fa5a6Sopenharmony_ci}
346c29fa5a6Sopenharmony_ci
347c29fa5a6Sopenharmony_ciSessionPtr UDSServer::GetSessionByPid(int32_t pid) const
348c29fa5a6Sopenharmony_ci{
349c29fa5a6Sopenharmony_ci    int32_t fd = GetClientFd(pid);
350c29fa5a6Sopenharmony_ci    if (fd <= 0) {
351c29fa5a6Sopenharmony_ci        if (pid_ != pid) {
352c29fa5a6Sopenharmony_ci            pid_ = pid;
353c29fa5a6Sopenharmony_ci            MMI_HILOGE("Session not found. pid:%{public}d", pid);
354c29fa5a6Sopenharmony_ci        }
355c29fa5a6Sopenharmony_ci        return nullptr;
356c29fa5a6Sopenharmony_ci    }
357c29fa5a6Sopenharmony_ci    return GetSession(fd);
358c29fa5a6Sopenharmony_ci}
359c29fa5a6Sopenharmony_ci
360c29fa5a6Sopenharmony_cibool UDSServer::AddSession(SessionPtr ses)
361c29fa5a6Sopenharmony_ci{
362c29fa5a6Sopenharmony_ci    CHKPF(ses);
363c29fa5a6Sopenharmony_ci    MMI_HILOGI("pid:%{public}d, fd:%{public}d", ses->GetPid(), ses->GetFd());
364c29fa5a6Sopenharmony_ci    auto fd = ses->GetFd();
365c29fa5a6Sopenharmony_ci    if (fd < 0) {
366c29fa5a6Sopenharmony_ci        MMI_HILOGE("The fd is less than 0");
367c29fa5a6Sopenharmony_ci        return false;
368c29fa5a6Sopenharmony_ci    }
369c29fa5a6Sopenharmony_ci    auto pid = ses->GetPid();
370c29fa5a6Sopenharmony_ci    if (pid <= 0) {
371c29fa5a6Sopenharmony_ci        MMI_HILOGE("Get process failed");
372c29fa5a6Sopenharmony_ci        return false;
373c29fa5a6Sopenharmony_ci    }
374c29fa5a6Sopenharmony_ci    idxPidMap_[pid] = fd;
375c29fa5a6Sopenharmony_ci    sessionsMap_[fd] = ses;
376c29fa5a6Sopenharmony_ci    DumpSession("AddSession");
377c29fa5a6Sopenharmony_ci    if (sessionsMap_.size() > MAX_SESSON_ALARM) {
378c29fa5a6Sopenharmony_ci        MMI_HILOGW("Too many clients. Warning Value:%{public}d, Current Value:%{public}zd",
379c29fa5a6Sopenharmony_ci                   MAX_SESSON_ALARM, sessionsMap_.size());
380c29fa5a6Sopenharmony_ci    }
381c29fa5a6Sopenharmony_ci    MMI_HILOGI("AddSession end");
382c29fa5a6Sopenharmony_ci    return true;
383c29fa5a6Sopenharmony_ci}
384c29fa5a6Sopenharmony_ci
385c29fa5a6Sopenharmony_civoid UDSServer::DelSession(int32_t fd)
386c29fa5a6Sopenharmony_ci{
387c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
388c29fa5a6Sopenharmony_ci    MMI_HILOGI("fd:%{public}d", fd);
389c29fa5a6Sopenharmony_ci    if (fd < 0) {
390c29fa5a6Sopenharmony_ci        MMI_HILOGE("The fd less than 0, errCode:%{public}d", PARAM_INPUT_INVALID);
391c29fa5a6Sopenharmony_ci        return;
392c29fa5a6Sopenharmony_ci    }
393c29fa5a6Sopenharmony_ci    auto pid = GetClientPid(fd);
394c29fa5a6Sopenharmony_ci    MMI_HILOGI("pid:%{public}d", pid);
395c29fa5a6Sopenharmony_ci    if (pid > 0) {
396c29fa5a6Sopenharmony_ci        idxPidMap_.erase(pid);
397c29fa5a6Sopenharmony_ci    }
398c29fa5a6Sopenharmony_ci    auto it = sessionsMap_.find(fd);
399c29fa5a6Sopenharmony_ci    if (it != sessionsMap_.end()) {
400c29fa5a6Sopenharmony_ci        NotifySessionDeleted(it->second);
401c29fa5a6Sopenharmony_ci        sessionsMap_.erase(it);
402c29fa5a6Sopenharmony_ci    }
403c29fa5a6Sopenharmony_ci    DumpSession("DelSession");
404c29fa5a6Sopenharmony_ci}
405c29fa5a6Sopenharmony_ci
406c29fa5a6Sopenharmony_civoid UDSServer::AddSessionDeletedCallback(std::function<void(SessionPtr)> callback)
407c29fa5a6Sopenharmony_ci{
408c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
409c29fa5a6Sopenharmony_ci    callbacks_.push_back(callback);
410c29fa5a6Sopenharmony_ci}
411c29fa5a6Sopenharmony_ci
412c29fa5a6Sopenharmony_civoid UDSServer::NotifySessionDeleted(SessionPtr ses)
413c29fa5a6Sopenharmony_ci{
414c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
415c29fa5a6Sopenharmony_ci    for (const auto &callback : callbacks_) {
416c29fa5a6Sopenharmony_ci        callback(ses);
417c29fa5a6Sopenharmony_ci    }
418c29fa5a6Sopenharmony_ci}
419c29fa5a6Sopenharmony_ci} // namespace MMI
420c29fa5a6Sopenharmony_ci} // namespace OHOS
421