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