1bae4d13cSopenharmony_ci/*
2bae4d13cSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3bae4d13cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bae4d13cSopenharmony_ci * you may not use this file except in compliance with the License.
5bae4d13cSopenharmony_ci * You may obtain a copy of the License at
6bae4d13cSopenharmony_ci *
7bae4d13cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bae4d13cSopenharmony_ci *
9bae4d13cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bae4d13cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bae4d13cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bae4d13cSopenharmony_ci * See the License for the specific language governing permissions and
13bae4d13cSopenharmony_ci * limitations under the License.
14bae4d13cSopenharmony_ci */
15bae4d13cSopenharmony_ci
16bae4d13cSopenharmony_ci#include "stream_server.h"
17bae4d13cSopenharmony_ci
18bae4d13cSopenharmony_ci#include <cinttypes>
19bae4d13cSopenharmony_ci
20bae4d13cSopenharmony_ci#include <sys/socket.h>
21bae4d13cSopenharmony_ci
22bae4d13cSopenharmony_ci#include "sensor_errors.h"
23bae4d13cSopenharmony_ci
24bae4d13cSopenharmony_ci#undef LOG_TAG
25bae4d13cSopenharmony_ci#define LOG_TAG "StreamServer"
26bae4d13cSopenharmony_ci
27bae4d13cSopenharmony_cinamespace OHOS {
28bae4d13cSopenharmony_cinamespace Sensors {
29bae4d13cSopenharmony_cinamespace {
30bae4d13cSopenharmony_ciconstexpr int32_t INVALID_PID = -1;
31bae4d13cSopenharmony_ciconstexpr int32_t INVALID_FD = -1;
32bae4d13cSopenharmony_ci} // namespace
33bae4d13cSopenharmony_ci
34bae4d13cSopenharmony_ciStreamServer::~StreamServer()
35bae4d13cSopenharmony_ci{
36bae4d13cSopenharmony_ci    CALL_LOG_ENTER;
37bae4d13cSopenharmony_ci    std::lock_guard<std::mutex> sessionLock(sessionMutex_);
38bae4d13cSopenharmony_ci    idxPidMap_.clear();
39bae4d13cSopenharmony_ci    for (const auto &item : sessionsMap_) {
40bae4d13cSopenharmony_ci        item.second->Close();
41bae4d13cSopenharmony_ci    }
42bae4d13cSopenharmony_ci    sessionsMap_.clear();
43bae4d13cSopenharmony_ci}
44bae4d13cSopenharmony_ci
45bae4d13cSopenharmony_ciint32_t StreamServer::GetClientFd(int32_t pid)
46bae4d13cSopenharmony_ci{
47bae4d13cSopenharmony_ci    std::lock_guard<std::mutex> sessionLock(sessionMutex_);
48bae4d13cSopenharmony_ci    auto it = idxPidMap_.find(pid);
49bae4d13cSopenharmony_ci    return it == idxPidMap_.end() ? INVALID_FD : it->second;
50bae4d13cSopenharmony_ci}
51bae4d13cSopenharmony_ci
52bae4d13cSopenharmony_ciint32_t StreamServer::GetClientPid(int32_t fd)
53bae4d13cSopenharmony_ci{
54bae4d13cSopenharmony_ci    std::lock_guard<std::mutex> sessionLock(sessionMutex_);
55bae4d13cSopenharmony_ci    auto it = sessionsMap_.find(fd);
56bae4d13cSopenharmony_ci    return it == sessionsMap_.end() ? INVALID_PID : it->second->GetPid();
57bae4d13cSopenharmony_ci}
58bae4d13cSopenharmony_ci
59bae4d13cSopenharmony_ciSessionPtr StreamServer::GetSession(int32_t fd)
60bae4d13cSopenharmony_ci{
61bae4d13cSopenharmony_ci    std::lock_guard<std::mutex> sessionLock(sessionMutex_);
62bae4d13cSopenharmony_ci    auto it = sessionsMap_.find(fd);
63bae4d13cSopenharmony_ci    if (it == sessionsMap_.end()) {
64bae4d13cSopenharmony_ci        SEN_HILOGE("Session not found");
65bae4d13cSopenharmony_ci        return nullptr;
66bae4d13cSopenharmony_ci    }
67bae4d13cSopenharmony_ci    CHKPP(it->second);
68bae4d13cSopenharmony_ci    return it->second->GetSharedPtr();
69bae4d13cSopenharmony_ci}
70bae4d13cSopenharmony_ci
71bae4d13cSopenharmony_ciSessionPtr StreamServer::GetSessionByPid(int32_t pid)
72bae4d13cSopenharmony_ci{
73bae4d13cSopenharmony_ci    int32_t fd = GetClientFd(pid);
74bae4d13cSopenharmony_ci    if (fd <= 0) {
75bae4d13cSopenharmony_ci        SEN_HILOGE("Session not found");
76bae4d13cSopenharmony_ci        return nullptr;
77bae4d13cSopenharmony_ci    }
78bae4d13cSopenharmony_ci    return GetSession(fd);
79bae4d13cSopenharmony_ci}
80bae4d13cSopenharmony_ci
81bae4d13cSopenharmony_ciint32_t StreamServer::AddSocketPairInfo(int32_t uid, int32_t pid, int32_t tokenType,
82bae4d13cSopenharmony_ci    int32_t &serverFd, int32_t &clientFd)
83bae4d13cSopenharmony_ci{
84bae4d13cSopenharmony_ci    CALL_LOG_ENTER;
85bae4d13cSopenharmony_ci    int32_t sockFds[2] = { -1 };
86bae4d13cSopenharmony_ci    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockFds) != 0) {
87bae4d13cSopenharmony_ci        SEN_HILOGE("Socketpair failed, errno:%{public}d", errno);
88bae4d13cSopenharmony_ci        return ERROR;
89bae4d13cSopenharmony_ci    }
90bae4d13cSopenharmony_ci    serverFd = sockFds[0];
91bae4d13cSopenharmony_ci    clientFd = sockFds[1];
92bae4d13cSopenharmony_ci    if (serverFd < 0 || clientFd < 0) {
93bae4d13cSopenharmony_ci        SEN_HILOGE("ServerFd or clientFd is invalid");
94bae4d13cSopenharmony_ci        return ERROR;
95bae4d13cSopenharmony_ci    }
96bae4d13cSopenharmony_ci    static constexpr size_t bufferSize = 32 * 1024;
97bae4d13cSopenharmony_ci    SessionPtr sess = nullptr;
98bae4d13cSopenharmony_ci    if (setsockopt(serverFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) {
99bae4d13cSopenharmony_ci        SEN_HILOGE("Setsockopt serverFd send buffer size failed, errno:%{public}d", errno);
100bae4d13cSopenharmony_ci        goto CLOSE_SOCK;
101bae4d13cSopenharmony_ci    }
102bae4d13cSopenharmony_ci    if (setsockopt(serverFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) {
103bae4d13cSopenharmony_ci        SEN_HILOGE("Setsockopt serverFd recv buffer size failed, errno:%{public}d", errno);
104bae4d13cSopenharmony_ci        goto CLOSE_SOCK;
105bae4d13cSopenharmony_ci    }
106bae4d13cSopenharmony_ci    if (setsockopt(clientFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) {
107bae4d13cSopenharmony_ci        SEN_HILOGE("Setsockopt clientFd send buffer size failed, errno:%{public}d", errno);
108bae4d13cSopenharmony_ci        goto CLOSE_SOCK;
109bae4d13cSopenharmony_ci    }
110bae4d13cSopenharmony_ci    if (setsockopt(clientFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) {
111bae4d13cSopenharmony_ci        SEN_HILOGE("Setsockopt clientFd recv buffer size failed, errno:%{public}d", errno);
112bae4d13cSopenharmony_ci        goto CLOSE_SOCK;
113bae4d13cSopenharmony_ci    }
114bae4d13cSopenharmony_ci    sess = std::make_shared<StreamSession>("", serverFd, uid, pid);
115bae4d13cSopenharmony_ci    sess->SetTokenType(tokenType);
116bae4d13cSopenharmony_ci    if (!AddSession(sess)) {
117bae4d13cSopenharmony_ci        SEN_HILOGE("AddSession fail");
118bae4d13cSopenharmony_ci        goto CLOSE_SOCK;
119bae4d13cSopenharmony_ci    }
120bae4d13cSopenharmony_ci    return ERR_OK;
121bae4d13cSopenharmony_ci
122bae4d13cSopenharmony_ciCLOSE_SOCK:
123bae4d13cSopenharmony_ci    close(serverFd);
124bae4d13cSopenharmony_ci    close(clientFd);
125bae4d13cSopenharmony_ci    return ERROR;
126bae4d13cSopenharmony_ci}
127bae4d13cSopenharmony_ci
128bae4d13cSopenharmony_cibool StreamServer::AddSession(SessionPtr sess)
129bae4d13cSopenharmony_ci{
130bae4d13cSopenharmony_ci    CALL_LOG_ENTER;
131bae4d13cSopenharmony_ci    CHKPF(sess);
132bae4d13cSopenharmony_ci    auto fd = sess->GetFd();
133bae4d13cSopenharmony_ci    if (fd < 0) {
134bae4d13cSopenharmony_ci        SEN_HILOGE("Fd is Invalid");
135bae4d13cSopenharmony_ci        return false;
136bae4d13cSopenharmony_ci    }
137bae4d13cSopenharmony_ci    auto pid = sess->GetPid();
138bae4d13cSopenharmony_ci    if (pid <= 0) {
139bae4d13cSopenharmony_ci        SEN_HILOGE("Pid is invalid");
140bae4d13cSopenharmony_ci        return false;
141bae4d13cSopenharmony_ci    }
142bae4d13cSopenharmony_ci    std::lock_guard<std::mutex> sessionLock(sessionMutex_);
143bae4d13cSopenharmony_ci    if (sessionsMap_.size() > MAX_SESSON_ALARM) {
144bae4d13cSopenharmony_ci        SEN_HILOGE("Too many clients, size:%{public}zu", sessionsMap_.size());
145bae4d13cSopenharmony_ci        return false;
146bae4d13cSopenharmony_ci    }
147bae4d13cSopenharmony_ci    idxPidMap_[pid] = fd;
148bae4d13cSopenharmony_ci    sessionsMap_[fd] = sess;
149bae4d13cSopenharmony_ci    return true;
150bae4d13cSopenharmony_ci}
151bae4d13cSopenharmony_ci
152bae4d13cSopenharmony_civoid StreamServer::DelSession(int32_t pid)
153bae4d13cSopenharmony_ci{
154bae4d13cSopenharmony_ci    CALL_LOG_ENTER;
155bae4d13cSopenharmony_ci    std::lock_guard<std::mutex> sessionLock(sessionMutex_);
156bae4d13cSopenharmony_ci    auto pidIt = idxPidMap_.find(pid);
157bae4d13cSopenharmony_ci    if (pidIt == idxPidMap_.end()) {
158bae4d13cSopenharmony_ci        SEN_HILOGW("Pid session not exist");
159bae4d13cSopenharmony_ci        return;
160bae4d13cSopenharmony_ci    }
161bae4d13cSopenharmony_ci    int32_t fd = pidIt->second;
162bae4d13cSopenharmony_ci    idxPidMap_.erase(pidIt);
163bae4d13cSopenharmony_ci    auto fdIt = sessionsMap_.find(fd);
164bae4d13cSopenharmony_ci    if (fdIt != sessionsMap_.end()) {
165bae4d13cSopenharmony_ci        sessionsMap_.erase(fdIt);
166bae4d13cSopenharmony_ci    }
167bae4d13cSopenharmony_ci    if (fd >= 0) {
168bae4d13cSopenharmony_ci        int32_t ret = close(fd);
169bae4d13cSopenharmony_ci        if (ret != 0) {
170bae4d13cSopenharmony_ci            SEN_HILOGE("Socket fd close failed, ret:%{public}d, errno:%{public}d", ret, errno);
171bae4d13cSopenharmony_ci        }
172bae4d13cSopenharmony_ci    }
173bae4d13cSopenharmony_ci}
174bae4d13cSopenharmony_ci} // namespace Sensors
175bae4d13cSopenharmony_ci} // namespace OHOS