1/* 2 * Copyright (c) 2023 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 "stream_server.h" 17 18#include <cinttypes> 19 20#include <sys/socket.h> 21 22#include "sensor_errors.h" 23 24#undef LOG_TAG 25#define LOG_TAG "StreamServer" 26 27namespace OHOS { 28namespace Sensors { 29namespace { 30constexpr int32_t INVALID_PID = -1; 31constexpr int32_t INVALID_FD = -1; 32} // namespace 33 34StreamServer::~StreamServer() 35{ 36 CALL_LOG_ENTER; 37 std::lock_guard<std::mutex> sessionLock(sessionMutex_); 38 idxPidMap_.clear(); 39 for (const auto &item : sessionsMap_) { 40 item.second->Close(); 41 } 42 sessionsMap_.clear(); 43} 44 45int32_t StreamServer::GetClientFd(int32_t pid) 46{ 47 std::lock_guard<std::mutex> sessionLock(sessionMutex_); 48 auto it = idxPidMap_.find(pid); 49 return it == idxPidMap_.end() ? INVALID_FD : it->second; 50} 51 52int32_t StreamServer::GetClientPid(int32_t fd) 53{ 54 std::lock_guard<std::mutex> sessionLock(sessionMutex_); 55 auto it = sessionsMap_.find(fd); 56 return it == sessionsMap_.end() ? INVALID_PID : it->second->GetPid(); 57} 58 59SessionPtr StreamServer::GetSession(int32_t fd) 60{ 61 std::lock_guard<std::mutex> sessionLock(sessionMutex_); 62 auto it = sessionsMap_.find(fd); 63 if (it == sessionsMap_.end()) { 64 SEN_HILOGE("Session not found"); 65 return nullptr; 66 } 67 CHKPP(it->second); 68 return it->second->GetSharedPtr(); 69} 70 71SessionPtr StreamServer::GetSessionByPid(int32_t pid) 72{ 73 int32_t fd = GetClientFd(pid); 74 if (fd <= 0) { 75 SEN_HILOGE("Session not found"); 76 return nullptr; 77 } 78 return GetSession(fd); 79} 80 81int32_t StreamServer::AddSocketPairInfo(int32_t uid, int32_t pid, int32_t tokenType, 82 int32_t &serverFd, int32_t &clientFd) 83{ 84 CALL_LOG_ENTER; 85 int32_t sockFds[2] = { -1 }; 86 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockFds) != 0) { 87 SEN_HILOGE("Socketpair failed, errno:%{public}d", errno); 88 return ERROR; 89 } 90 serverFd = sockFds[0]; 91 clientFd = sockFds[1]; 92 if (serverFd < 0 || clientFd < 0) { 93 SEN_HILOGE("ServerFd or clientFd is invalid"); 94 return ERROR; 95 } 96 static constexpr size_t bufferSize = 32 * 1024; 97 SessionPtr sess = nullptr; 98 if (setsockopt(serverFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) { 99 SEN_HILOGE("Setsockopt serverFd send buffer size failed, errno:%{public}d", errno); 100 goto CLOSE_SOCK; 101 } 102 if (setsockopt(serverFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) { 103 SEN_HILOGE("Setsockopt serverFd recv buffer size failed, errno:%{public}d", errno); 104 goto CLOSE_SOCK; 105 } 106 if (setsockopt(clientFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) { 107 SEN_HILOGE("Setsockopt clientFd send buffer size failed, errno:%{public}d", errno); 108 goto CLOSE_SOCK; 109 } 110 if (setsockopt(clientFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) { 111 SEN_HILOGE("Setsockopt clientFd recv buffer size failed, errno:%{public}d", errno); 112 goto CLOSE_SOCK; 113 } 114 sess = std::make_shared<StreamSession>("", serverFd, uid, pid); 115 sess->SetTokenType(tokenType); 116 if (!AddSession(sess)) { 117 SEN_HILOGE("AddSession fail"); 118 goto CLOSE_SOCK; 119 } 120 return ERR_OK; 121 122CLOSE_SOCK: 123 close(serverFd); 124 close(clientFd); 125 return ERROR; 126} 127 128bool StreamServer::AddSession(SessionPtr sess) 129{ 130 CALL_LOG_ENTER; 131 CHKPF(sess); 132 auto fd = sess->GetFd(); 133 if (fd < 0) { 134 SEN_HILOGE("Fd is Invalid"); 135 return false; 136 } 137 auto pid = sess->GetPid(); 138 if (pid <= 0) { 139 SEN_HILOGE("Pid is invalid"); 140 return false; 141 } 142 std::lock_guard<std::mutex> sessionLock(sessionMutex_); 143 if (sessionsMap_.size() > MAX_SESSON_ALARM) { 144 SEN_HILOGE("Too many clients, size:%{public}zu", sessionsMap_.size()); 145 return false; 146 } 147 idxPidMap_[pid] = fd; 148 sessionsMap_[fd] = sess; 149 return true; 150} 151 152void StreamServer::DelSession(int32_t pid) 153{ 154 CALL_LOG_ENTER; 155 std::lock_guard<std::mutex> sessionLock(sessionMutex_); 156 auto pidIt = idxPidMap_.find(pid); 157 if (pidIt == idxPidMap_.end()) { 158 SEN_HILOGW("Pid session not exist"); 159 return; 160 } 161 int32_t fd = pidIt->second; 162 idxPidMap_.erase(pidIt); 163 auto fdIt = sessionsMap_.find(fd); 164 if (fdIt != sessionsMap_.end()) { 165 sessionsMap_.erase(fdIt); 166 } 167 if (fd >= 0) { 168 int32_t ret = close(fd); 169 if (ret != 0) { 170 SEN_HILOGE("Socket fd close failed, ret:%{public}d, errno:%{public}d", ret, errno); 171 } 172 } 173} 174} // namespace Sensors 175} // namespace OHOS