1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci 16020a203aSopenharmony_ci#include "event_server.h" 17020a203aSopenharmony_ci 18020a203aSopenharmony_ci#include <fstream> 19020a203aSopenharmony_ci#include <memory> 20020a203aSopenharmony_ci#include <string> 21020a203aSopenharmony_ci#include <vector> 22020a203aSopenharmony_ci 23020a203aSopenharmony_ci#include <fcntl.h> 24020a203aSopenharmony_ci#include <sys/epoll.h> 25020a203aSopenharmony_ci#include <sys/socket.h> 26020a203aSopenharmony_ci#include <sys/stat.h> 27020a203aSopenharmony_ci#include <sys/types.h> 28020a203aSopenharmony_ci#include <sys/un.h> 29020a203aSopenharmony_ci#include <unistd.h> 30020a203aSopenharmony_ci 31020a203aSopenharmony_ci#include <securec.h> 32020a203aSopenharmony_ci 33020a203aSopenharmony_ci#include "base/raw_data_base_def.h" 34020a203aSopenharmony_ci#include "decoded/decoded_event.h" 35020a203aSopenharmony_ci#include "device_node.h" 36020a203aSopenharmony_ci#include "init_socket.h" 37020a203aSopenharmony_ci#include "hiview_logger.h" 38020a203aSopenharmony_ci#include "socket_util.h" 39020a203aSopenharmony_ci 40020a203aSopenharmony_ci#define SOCKET_FILE_DIR "/dev/unix/socket/hisysevent" 41020a203aSopenharmony_ci 42020a203aSopenharmony_cinamespace OHOS { 43020a203aSopenharmony_cinamespace HiviewDFX { 44020a203aSopenharmony_ciDEFINE_LOG_TAG("HiView-EventServer"); 45020a203aSopenharmony_cinamespace { 46020a203aSopenharmony_ciconstexpr int BUFFER_SIZE = 384 * 1024; 47020a203aSopenharmony_ci#ifndef KERNEL_DEVICE_BUFFER 48020a203aSopenharmony_ciconstexpr int EVENT_READ_BUFFER = 2048; 49020a203aSopenharmony_ci#else 50020a203aSopenharmony_ciconstexpr int EVENT_READ_BUFFER = KERNEL_DEVICE_BUFFER; 51020a203aSopenharmony_ci#endif 52020a203aSopenharmony_ci 53020a203aSopenharmony_cistruct Header { 54020a203aSopenharmony_ci unsigned short len; 55020a203aSopenharmony_ci unsigned short headerSize; 56020a203aSopenharmony_ci char msg[0]; 57020a203aSopenharmony_ci}; 58020a203aSopenharmony_ci 59020a203aSopenharmony_civoid InitSocketBuf(int socketId, int optName) 60020a203aSopenharmony_ci{ 61020a203aSopenharmony_ci int bufferSizeOld = 0; 62020a203aSopenharmony_ci socklen_t sizeOfInt = static_cast<socklen_t>(sizeof(int)); 63020a203aSopenharmony_ci if (getsockopt(socketId, SOL_SOCKET, optName, static_cast<void *>(&bufferSizeOld), &sizeOfInt) < 0) { 64020a203aSopenharmony_ci HIVIEW_LOGE("get socket buffer error=%{public}d, msg=%{public}s", errno, strerror(errno)); 65020a203aSopenharmony_ci } 66020a203aSopenharmony_ci 67020a203aSopenharmony_ci int bufferSizeSet = BUFFER_SIZE; 68020a203aSopenharmony_ci if (setsockopt(socketId, SOL_SOCKET, optName, static_cast<void *>(&bufferSizeSet), sizeof(int)) < 0) { 69020a203aSopenharmony_ci HIVIEW_LOGE("set socket buffer error=%{public}d, msg=%{public}s", errno, strerror(errno)); 70020a203aSopenharmony_ci } 71020a203aSopenharmony_ci 72020a203aSopenharmony_ci int bufferSizeNew = 0; 73020a203aSopenharmony_ci sizeOfInt = static_cast<socklen_t>(sizeof(int)); 74020a203aSopenharmony_ci if (getsockopt(socketId, SOL_SOCKET, optName, static_cast<void *>(&bufferSizeNew), &sizeOfInt) < 0) { 75020a203aSopenharmony_ci HIVIEW_LOGE("get new socket buffer error=%{public}d, msg=%{public}s", errno, strerror(errno)); 76020a203aSopenharmony_ci } 77020a203aSopenharmony_ci HIVIEW_LOGI("reset buffer size old=%{public}d, new=%{public}d", bufferSizeOld, bufferSizeNew); 78020a203aSopenharmony_ci} 79020a203aSopenharmony_ci 80020a203aSopenharmony_civoid InitRecvBuffer(int socketId) 81020a203aSopenharmony_ci{ 82020a203aSopenharmony_ci InitSocketBuf(socketId, SO_RCVBUF); 83020a203aSopenharmony_ci} 84020a203aSopenharmony_ci 85020a203aSopenharmony_cistd::shared_ptr<EventRaw::RawData> ConverRawData(char* source) 86020a203aSopenharmony_ci{ 87020a203aSopenharmony_ci if (source == nullptr) { 88020a203aSopenharmony_ci HIVIEW_LOGE("invalid source."); 89020a203aSopenharmony_ci return nullptr; 90020a203aSopenharmony_ci } 91020a203aSopenharmony_ci uint32_t sourceLen = *(reinterpret_cast<uint32_t*>(source)); 92020a203aSopenharmony_ci uint32_t desLen = sourceLen + sizeof(uint8_t); 93020a203aSopenharmony_ci uint8_t* des = reinterpret_cast<uint8_t*>(malloc(desLen)); 94020a203aSopenharmony_ci if (des == nullptr) { 95020a203aSopenharmony_ci HIVIEW_LOGE("malloc failed."); 96020a203aSopenharmony_ci return nullptr; 97020a203aSopenharmony_ci } 98020a203aSopenharmony_ci uint32_t sourceHeaderLen = sizeof(int32_t) + sizeof(EventRaw::HiSysEventHeader) - sizeof(uint8_t); 99020a203aSopenharmony_ci if (memcpy_s(des, desLen, source, sourceHeaderLen) != EOK) { 100020a203aSopenharmony_ci HIVIEW_LOGE("copy failed."); 101020a203aSopenharmony_ci free(des); 102020a203aSopenharmony_ci return nullptr; 103020a203aSopenharmony_ci } 104020a203aSopenharmony_ci *(reinterpret_cast<uint8_t*>(des + sourceHeaderLen)) = 0; // init header.log flag 105020a203aSopenharmony_ci uint32_t desPos = sourceHeaderLen + sizeof(uint8_t); 106020a203aSopenharmony_ci if (memcpy_s(des + desPos, desLen - desPos, source + sourceHeaderLen, sourceLen - sourceHeaderLen) != EOK) { 107020a203aSopenharmony_ci HIVIEW_LOGE("copy failed."); 108020a203aSopenharmony_ci free(des); 109020a203aSopenharmony_ci return nullptr; 110020a203aSopenharmony_ci } 111020a203aSopenharmony_ci *(reinterpret_cast<int32_t*>(des)) = desLen; 112020a203aSopenharmony_ci auto rawData = std::make_shared<EventRaw::RawData>(des, desLen); 113020a203aSopenharmony_ci free(des); 114020a203aSopenharmony_ci return rawData; 115020a203aSopenharmony_ci} 116020a203aSopenharmony_ci 117020a203aSopenharmony_civoid InitMsgh(char* buffer, int bufferLen, std::array<char, CMSG_SPACE(sizeof(struct ucred))>& control, 118020a203aSopenharmony_ci struct msghdr& msgh, struct iovec& iov) 119020a203aSopenharmony_ci{ 120020a203aSopenharmony_ci iov.iov_base = buffer; 121020a203aSopenharmony_ci iov.iov_len = static_cast<uint32_t>(bufferLen); 122020a203aSopenharmony_ci msgh.msg_iov = &iov; 123020a203aSopenharmony_ci msgh.msg_iovlen = 1; // 1 is length of io vector 124020a203aSopenharmony_ci 125020a203aSopenharmony_ci msgh.msg_control = control.data(); 126020a203aSopenharmony_ci msgh.msg_controllen = control.size(); 127020a203aSopenharmony_ci 128020a203aSopenharmony_ci msgh.msg_name = nullptr; 129020a203aSopenharmony_ci msgh.msg_namelen = 0; 130020a203aSopenharmony_ci msgh.msg_flags = 0; 131020a203aSopenharmony_ci} 132020a203aSopenharmony_ci 133020a203aSopenharmony_cipid_t ReadPidFromMsgh(struct msghdr& msgh) 134020a203aSopenharmony_ci{ 135020a203aSopenharmony_ci struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msgh); 136020a203aSopenharmony_ci if (cmsg == nullptr) { 137020a203aSopenharmony_ci return UN_INIT_INT_TYPE_VAL; 138020a203aSopenharmony_ci } 139020a203aSopenharmony_ci struct ucred* uCredRecv = reinterpret_cast<struct ucred*>(CMSG_DATA(cmsg)); 140020a203aSopenharmony_ci if (uCredRecv == nullptr) { 141020a203aSopenharmony_ci return UN_INIT_INT_TYPE_VAL; 142020a203aSopenharmony_ci } 143020a203aSopenharmony_ci return uCredRecv->pid; 144020a203aSopenharmony_ci} 145020a203aSopenharmony_ci} 146020a203aSopenharmony_ci 147020a203aSopenharmony_civoid SocketDevice::InitSocket(int &socketId) 148020a203aSopenharmony_ci{ 149020a203aSopenharmony_ci struct sockaddr_un serverAddr; 150020a203aSopenharmony_ci serverAddr.sun_family = AF_UNIX; 151020a203aSopenharmony_ci if (strcpy_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), SOCKET_FILE_DIR) != EOK) { 152020a203aSopenharmony_ci socketId = -1; 153020a203aSopenharmony_ci HIVIEW_LOGE("copy hisysevent dev path failed, error=%{public}d, msg=%{public}s", errno, strerror(errno)); 154020a203aSopenharmony_ci return; 155020a203aSopenharmony_ci } 156020a203aSopenharmony_ci serverAddr.sun_path[sizeof(serverAddr.sun_path) - 1] = '\0'; 157020a203aSopenharmony_ci socketId = TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); 158020a203aSopenharmony_ci if (socketId < 0) { 159020a203aSopenharmony_ci HIVIEW_LOGE("create hisysevent socket failed, error=%{public}d, msg=%{public}s", errno, strerror(errno)); 160020a203aSopenharmony_ci return; 161020a203aSopenharmony_ci } 162020a203aSopenharmony_ci InitRecvBuffer(socketId_); 163020a203aSopenharmony_ci unlink(serverAddr.sun_path); 164020a203aSopenharmony_ci if (TEMP_FAILURE_RETRY(bind(socketId, reinterpret_cast<sockaddr*>(&serverAddr), sizeof(serverAddr))) < 0) { 165020a203aSopenharmony_ci close(socketId); 166020a203aSopenharmony_ci socketId = -1; 167020a203aSopenharmony_ci HIVIEW_LOGE("bind hisysevent socket failed, error=%{public}d, msg=%{public}s", errno, strerror(errno)); 168020a203aSopenharmony_ci return; 169020a203aSopenharmony_ci } 170020a203aSopenharmony_ci} 171020a203aSopenharmony_ci 172020a203aSopenharmony_ciint SocketDevice::Open() 173020a203aSopenharmony_ci{ 174020a203aSopenharmony_ci socketId_ = GetControlSocket("hisysevent"); 175020a203aSopenharmony_ci if (socketId_ < 0) { 176020a203aSopenharmony_ci HIVIEW_LOGI("create hisysevent socket"); 177020a203aSopenharmony_ci InitSocket(socketId_); 178020a203aSopenharmony_ci } else { 179020a203aSopenharmony_ci InitRecvBuffer(socketId_); 180020a203aSopenharmony_ci HIVIEW_LOGI("use hisysevent exist socket"); 181020a203aSopenharmony_ci } 182020a203aSopenharmony_ci 183020a203aSopenharmony_ci if (socketId_ < 0) { 184020a203aSopenharmony_ci HIVIEW_LOGE("hisysevent create socket failed"); 185020a203aSopenharmony_ci return -1; 186020a203aSopenharmony_ci } 187020a203aSopenharmony_ci return socketId_; 188020a203aSopenharmony_ci} 189020a203aSopenharmony_ci 190020a203aSopenharmony_ciint SocketDevice::Close() 191020a203aSopenharmony_ci{ 192020a203aSopenharmony_ci if (socketId_ > 0) { 193020a203aSopenharmony_ci close(socketId_); 194020a203aSopenharmony_ci socketId_ = -1; 195020a203aSopenharmony_ci } 196020a203aSopenharmony_ci return 0; 197020a203aSopenharmony_ci} 198020a203aSopenharmony_ci 199020a203aSopenharmony_ciuint32_t SocketDevice::GetEvents() 200020a203aSopenharmony_ci{ 201020a203aSopenharmony_ci return EPOLLIN | EPOLLET; 202020a203aSopenharmony_ci} 203020a203aSopenharmony_ci 204020a203aSopenharmony_cistd::string SocketDevice::GetName() 205020a203aSopenharmony_ci{ 206020a203aSopenharmony_ci return "SysEventSocket"; 207020a203aSopenharmony_ci} 208020a203aSopenharmony_ci 209020a203aSopenharmony_cibool SocketDevice::IsValidMsg(char* msg, int32_t len) 210020a203aSopenharmony_ci{ 211020a203aSopenharmony_ci if (len < static_cast<int32_t>(EventRaw::GetValidDataMinimumByteCount())) { 212020a203aSopenharmony_ci HIVIEW_LOGD("the data length=%{public}d is invalid", len); 213020a203aSopenharmony_ci return false; 214020a203aSopenharmony_ci } 215020a203aSopenharmony_ci int32_t dataByteCnt = *(reinterpret_cast<int32_t*>(msg)); 216020a203aSopenharmony_ci if (dataByteCnt != len) { 217020a203aSopenharmony_ci HIVIEW_LOGW("the data byte count=%{public}d are not equal to read length %{public}d", dataByteCnt, len); 218020a203aSopenharmony_ci return false; 219020a203aSopenharmony_ci } 220020a203aSopenharmony_ci int32_t pid = *(reinterpret_cast<int32_t*>(msg + sizeof(int32_t) + EventRaw::POS_OF_PID_IN_HEADER)); 221020a203aSopenharmony_ci if (uCredPid_ > 0 && pid != uCredPid_) { 222020a203aSopenharmony_ci HIVIEW_LOGW("failed to verify the consistensy of process id: [%{public}" PRId32 223020a203aSopenharmony_ci ", %{public}" PRId32 "]", pid, uCredPid_); 224020a203aSopenharmony_ci return false; 225020a203aSopenharmony_ci } 226020a203aSopenharmony_ci msg[len] = '\0'; 227020a203aSopenharmony_ci return true; 228020a203aSopenharmony_ci} 229020a203aSopenharmony_ci 230020a203aSopenharmony_civoid SocketDevice::SetUCredPid(const pid_t pid) 231020a203aSopenharmony_ci{ 232020a203aSopenharmony_ci uCredPid_ = pid; 233020a203aSopenharmony_ci} 234020a203aSopenharmony_ci 235020a203aSopenharmony_ciint SocketDevice::ReceiveMsg(std::vector<std::shared_ptr<EventReceiver>> &receivers) 236020a203aSopenharmony_ci{ 237020a203aSopenharmony_ci char* buffer = new char[BUFFER_SIZE + 1](); 238020a203aSopenharmony_ci std::array<char, CMSG_SPACE(sizeof(struct ucred))> control = {0}; 239020a203aSopenharmony_ci struct msghdr msgh = {0}; 240020a203aSopenharmony_ci struct iovec iov = { 241020a203aSopenharmony_ci .iov_base = nullptr, 242020a203aSopenharmony_ci .iov_len = 0 243020a203aSopenharmony_ci }; 244020a203aSopenharmony_ci InitMsgh(buffer, BUFFER_SIZE, control, msgh, iov); 245020a203aSopenharmony_ci while (true) { 246020a203aSopenharmony_ci int ret = recvmsg(socketId_, &msgh, 0); 247020a203aSopenharmony_ci if (ret <= 0) { 248020a203aSopenharmony_ci HIVIEW_LOGD("failed to recv msg from socket"); 249020a203aSopenharmony_ci break; 250020a203aSopenharmony_ci } 251020a203aSopenharmony_ci pid_t uCredPid = ReadPidFromMsgh(msgh); 252020a203aSopenharmony_ci SetUCredPid(uCredPid); 253020a203aSopenharmony_ci if (!IsValidMsg(buffer, ret)) { 254020a203aSopenharmony_ci break; 255020a203aSopenharmony_ci } 256020a203aSopenharmony_ci for (auto receiver = receivers.begin(); receiver != receivers.end(); receiver++) { 257020a203aSopenharmony_ci (*receiver)->HandlerEvent(ConverRawData(buffer)); 258020a203aSopenharmony_ci } 259020a203aSopenharmony_ci } 260020a203aSopenharmony_ci delete[] buffer; 261020a203aSopenharmony_ci return 0; 262020a203aSopenharmony_ci} 263020a203aSopenharmony_ci 264020a203aSopenharmony_ciint BBoxDevice::Close() 265020a203aSopenharmony_ci{ 266020a203aSopenharmony_ci if (fd_ > 0) { 267020a203aSopenharmony_ci close(fd_); 268020a203aSopenharmony_ci fd_ = -1; 269020a203aSopenharmony_ci } 270020a203aSopenharmony_ci return 0; 271020a203aSopenharmony_ci} 272020a203aSopenharmony_ci 273020a203aSopenharmony_ciint BBoxDevice::Open() 274020a203aSopenharmony_ci{ 275020a203aSopenharmony_ci fd_ = open("/dev/sysevent", O_RDONLY | O_NONBLOCK, 0); 276020a203aSopenharmony_ci if (fd_ < 0) { 277020a203aSopenharmony_ci fd_ = open("/dev/bbox", O_RDONLY | O_NONBLOCK, 0); 278020a203aSopenharmony_ci } else { 279020a203aSopenharmony_ci hasBbox_ = true; 280020a203aSopenharmony_ci } 281020a203aSopenharmony_ci 282020a203aSopenharmony_ci if (fd_ < 0) { 283020a203aSopenharmony_ci HIVIEW_LOGE("open bbox failed, error=%{public}d, msg=%{public}s", errno, strerror(errno)); 284020a203aSopenharmony_ci return -1; 285020a203aSopenharmony_ci } 286020a203aSopenharmony_ci return fd_; 287020a203aSopenharmony_ci} 288020a203aSopenharmony_ci 289020a203aSopenharmony_ciuint32_t BBoxDevice::GetEvents() 290020a203aSopenharmony_ci{ 291020a203aSopenharmony_ci return EPOLLIN; 292020a203aSopenharmony_ci} 293020a203aSopenharmony_ci 294020a203aSopenharmony_cistd::string BBoxDevice::GetName() 295020a203aSopenharmony_ci{ 296020a203aSopenharmony_ci return "BBox"; 297020a203aSopenharmony_ci} 298020a203aSopenharmony_ci 299020a203aSopenharmony_cibool BBoxDevice::IsValidMsg(char* msg, int32_t len) 300020a203aSopenharmony_ci{ 301020a203aSopenharmony_ci if (len < static_cast<int32_t>(EventRaw::GetValidDataMinimumByteCount())) { 302020a203aSopenharmony_ci HIVIEW_LOGW("the data length=%{public}d is invalid", len); 303020a203aSopenharmony_ci return false; 304020a203aSopenharmony_ci } 305020a203aSopenharmony_ci int32_t dataByteCnt = *(reinterpret_cast<int32_t*>(msg)); 306020a203aSopenharmony_ci if ((hasBbox_ && dataByteCnt != len) || 307020a203aSopenharmony_ci (!hasBbox_ && dataByteCnt != (len - sizeof(struct Header) - 1))) { // extra bytes in kernel write 308020a203aSopenharmony_ci HIVIEW_LOGW("the data lengths=%{public}d are not equal", len); 309020a203aSopenharmony_ci return false; 310020a203aSopenharmony_ci } 311020a203aSopenharmony_ci msg[EVENT_READ_BUFFER - 1] = '\0'; 312020a203aSopenharmony_ci return true; 313020a203aSopenharmony_ci} 314020a203aSopenharmony_ci 315020a203aSopenharmony_ciint BBoxDevice::ReceiveMsg(std::vector<std::shared_ptr<EventReceiver>> &receivers) 316020a203aSopenharmony_ci{ 317020a203aSopenharmony_ci char buffer[EVENT_READ_BUFFER]; 318020a203aSopenharmony_ci (void)memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); 319020a203aSopenharmony_ci int ret = read(fd_, buffer, EVENT_READ_BUFFER); 320020a203aSopenharmony_ci if (!IsValidMsg(buffer, ret)) { 321020a203aSopenharmony_ci return -1; 322020a203aSopenharmony_ci } 323020a203aSopenharmony_ci for (auto receiver = receivers.begin(); receiver != receivers.end(); receiver++) { 324020a203aSopenharmony_ci (*receiver)->HandlerEvent(ConverRawData(buffer)); 325020a203aSopenharmony_ci } 326020a203aSopenharmony_ci return 0; 327020a203aSopenharmony_ci} 328020a203aSopenharmony_ci 329020a203aSopenharmony_civoid EventServer::AddDev(std::shared_ptr<DeviceNode> dev) 330020a203aSopenharmony_ci{ 331020a203aSopenharmony_ci int fd = dev->Open(); 332020a203aSopenharmony_ci if (fd < 0) { 333020a203aSopenharmony_ci HIVIEW_LOGI("open device %{public}s failed", dev->GetName().c_str()); 334020a203aSopenharmony_ci return; 335020a203aSopenharmony_ci } 336020a203aSopenharmony_ci devs_[fd] = dev; 337020a203aSopenharmony_ci} 338020a203aSopenharmony_ci 339020a203aSopenharmony_ciint EventServer::OpenDevs() 340020a203aSopenharmony_ci{ 341020a203aSopenharmony_ci AddDev(std::make_shared<SocketDevice>()); 342020a203aSopenharmony_ci AddDev(std::make_shared<BBoxDevice>()); 343020a203aSopenharmony_ci if (devs_.empty()) { 344020a203aSopenharmony_ci HIVIEW_LOGE("can not open any device"); 345020a203aSopenharmony_ci return -1; 346020a203aSopenharmony_ci } 347020a203aSopenharmony_ci HIVIEW_LOGI("has open %{public}zu devices", devs_.size()); 348020a203aSopenharmony_ci return 0; 349020a203aSopenharmony_ci} 350020a203aSopenharmony_ci 351020a203aSopenharmony_ciint EventServer::AddToMonitor(int pollFd, struct epoll_event pollEvents[]) 352020a203aSopenharmony_ci{ 353020a203aSopenharmony_ci int index = 0; 354020a203aSopenharmony_ci auto it = devs_.begin(); 355020a203aSopenharmony_ci while (it != devs_.end()) { 356020a203aSopenharmony_ci HIVIEW_LOGI("add to poll device %{public}s, fd=%{public}d", it->second->GetName().c_str(), it->first); 357020a203aSopenharmony_ci pollEvents[index].data.fd = it->first; 358020a203aSopenharmony_ci pollEvents[index].events = it->second->GetEvents(); 359020a203aSopenharmony_ci int ret = epoll_ctl(pollFd, EPOLL_CTL_ADD, it->first, &pollEvents[index]); 360020a203aSopenharmony_ci if (ret < 0) { 361020a203aSopenharmony_ci HIVIEW_LOGE("add to poll fail device %{public}s error=%{public}d, msg=%{public}s", 362020a203aSopenharmony_ci it->second->GetName().c_str(), errno, strerror(errno)); 363020a203aSopenharmony_ci it->second->Close(); 364020a203aSopenharmony_ci it = devs_.erase(it); 365020a203aSopenharmony_ci } else { 366020a203aSopenharmony_ci it++; 367020a203aSopenharmony_ci } 368020a203aSopenharmony_ci index++; 369020a203aSopenharmony_ci } 370020a203aSopenharmony_ci 371020a203aSopenharmony_ci if (devs_.empty()) { 372020a203aSopenharmony_ci HIVIEW_LOGE("can not monitor any device"); 373020a203aSopenharmony_ci return -1; 374020a203aSopenharmony_ci } 375020a203aSopenharmony_ci HIVIEW_LOGI("monitor devices %{public}zu", devs_.size()); 376020a203aSopenharmony_ci return 0; 377020a203aSopenharmony_ci} 378020a203aSopenharmony_ci 379020a203aSopenharmony_civoid EventServer::Start() 380020a203aSopenharmony_ci{ 381020a203aSopenharmony_ci HIVIEW_LOGD("start event server"); 382020a203aSopenharmony_ci if (OpenDevs() < 0) { 383020a203aSopenharmony_ci return; 384020a203aSopenharmony_ci } 385020a203aSopenharmony_ci 386020a203aSopenharmony_ci int pollFd = epoll_create1(EPOLL_CLOEXEC); 387020a203aSopenharmony_ci if (pollFd < 0) { 388020a203aSopenharmony_ci HIVIEW_LOGE("create poll failed, error=%{public}d, msg=%{public}s", errno, strerror(errno)); 389020a203aSopenharmony_ci return; 390020a203aSopenharmony_ci } 391020a203aSopenharmony_ci 392020a203aSopenharmony_ci struct epoll_event pollEvents[devs_.size()]; 393020a203aSopenharmony_ci if (AddToMonitor(pollFd, pollEvents) < 0) { 394020a203aSopenharmony_ci return; 395020a203aSopenharmony_ci } 396020a203aSopenharmony_ci 397020a203aSopenharmony_ci HIVIEW_LOGI("go into event loop"); 398020a203aSopenharmony_ci isStart_ = true; 399020a203aSopenharmony_ci while (isStart_) { 400020a203aSopenharmony_ci struct epoll_event chkPollEvents[devs_.size()]; 401020a203aSopenharmony_ci int eventCount = epoll_wait(pollFd, chkPollEvents, devs_.size(), -1); // -1: Wait indefinitely 402020a203aSopenharmony_ci if (eventCount <= 0) { 403020a203aSopenharmony_ci HIVIEW_LOGD("read event timeout"); 404020a203aSopenharmony_ci continue; 405020a203aSopenharmony_ci } 406020a203aSopenharmony_ci for (int ii = 0; ii < eventCount; ii++) { 407020a203aSopenharmony_ci auto it = devs_.find(chkPollEvents[ii].data.fd); 408020a203aSopenharmony_ci it->second->ReceiveMsg(receivers_); 409020a203aSopenharmony_ci } 410020a203aSopenharmony_ci } 411020a203aSopenharmony_ci CloseDevs(); 412020a203aSopenharmony_ci} 413020a203aSopenharmony_ci 414020a203aSopenharmony_civoid EventServer::CloseDevs() 415020a203aSopenharmony_ci{ 416020a203aSopenharmony_ci for (auto devItem : devs_) { 417020a203aSopenharmony_ci devItem.second->Close(); 418020a203aSopenharmony_ci } 419020a203aSopenharmony_ci} 420020a203aSopenharmony_ci 421020a203aSopenharmony_civoid EventServer::Stop() 422020a203aSopenharmony_ci{ 423020a203aSopenharmony_ci isStart_ = false; 424020a203aSopenharmony_ci} 425020a203aSopenharmony_ci 426020a203aSopenharmony_civoid EventServer::AddReceiver(std::shared_ptr<EventReceiver> receiver) 427020a203aSopenharmony_ci{ 428020a203aSopenharmony_ci receivers_.emplace_back(receiver); 429020a203aSopenharmony_ci} 430020a203aSopenharmony_ci} // namespace HiviewDFX 431020a203aSopenharmony_ci} // namespace OHOS 432