111fccf17Sopenharmony_ci/* 211fccf17Sopenharmony_ci * Copyright (C) 2021-2024 Huawei Device Co., Ltd. 311fccf17Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 411fccf17Sopenharmony_ci * you may not use this file except in compliance with the License. 511fccf17Sopenharmony_ci * You may obtain a copy of the License at 611fccf17Sopenharmony_ci * 711fccf17Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 811fccf17Sopenharmony_ci * 911fccf17Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1011fccf17Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1111fccf17Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1211fccf17Sopenharmony_ci * See the License for the specific language governing permissions and 1311fccf17Sopenharmony_ci * limitations under the License. 1411fccf17Sopenharmony_ci */ 1511fccf17Sopenharmony_ci 1611fccf17Sopenharmony_ci#include "hril_event.h" 1711fccf17Sopenharmony_ci 1811fccf17Sopenharmony_ci#include <cerrno> 1911fccf17Sopenharmony_ci#include <fcntl.h> 2011fccf17Sopenharmony_ci#include <sys/select.h> 2111fccf17Sopenharmony_ci#include <sys/types.h> 2211fccf17Sopenharmony_ci#include <unistd.h> 2311fccf17Sopenharmony_ci 2411fccf17Sopenharmony_ci#include "securec.h" 2511fccf17Sopenharmony_ci 2611fccf17Sopenharmony_ci#include "telephony_log_wrapper.h" 2711fccf17Sopenharmony_ci 2811fccf17Sopenharmony_cinamespace OHOS { 2911fccf17Sopenharmony_cinamespace Telephony { 3011fccf17Sopenharmony_civoid HRilEvent::GetNowTime(struct timeval &tv) 3111fccf17Sopenharmony_ci{ 3211fccf17Sopenharmony_ci struct timespec ts; 3311fccf17Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &ts); 3411fccf17Sopenharmony_ci tv.tv_sec = ts.tv_sec; 3511fccf17Sopenharmony_ci tv.tv_usec = ts.tv_nsec / TIME_UNIT; 3611fccf17Sopenharmony_ci} 3711fccf17Sopenharmony_ci 3811fccf17Sopenharmony_cibool HRilEvent::GetNextTimeOut(struct timeval &tv) 3911fccf17Sopenharmony_ci{ 4011fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 4111fccf17Sopenharmony_ci std::list<HRilEventMessage>::iterator eventIt = timerList_.begin(); 4211fccf17Sopenharmony_ci if (eventIt == timerList_.end() || timerList_.empty()) { 4311fccf17Sopenharmony_ci return false; 4411fccf17Sopenharmony_ci } 4511fccf17Sopenharmony_ci 4611fccf17Sopenharmony_ci struct timeval now; 4711fccf17Sopenharmony_ci GetNowTime(now); 4811fccf17Sopenharmony_ci TELEPHONY_LOGD("now = %{public}ds + %{public}dus", (int32_t)now.tv_sec, (int32_t)now.tv_usec); 4911fccf17Sopenharmony_ci TELEPHONY_LOGD( 5011fccf17Sopenharmony_ci "next = %{public}ds + %{public}dus", (int32_t)eventIt->timeout.tv_sec, (int32_t)eventIt->timeout.tv_usec); 5111fccf17Sopenharmony_ci if (timercmp(&eventIt->timeout, &now, >)) { 5211fccf17Sopenharmony_ci timersub(&eventIt->timeout, &now, &tv); 5311fccf17Sopenharmony_ci } else { 5411fccf17Sopenharmony_ci // timer already expired. 5511fccf17Sopenharmony_ci tv.tv_sec = tv.tv_usec = 0; 5611fccf17Sopenharmony_ci } 5711fccf17Sopenharmony_ci return true; 5811fccf17Sopenharmony_ci} 5911fccf17Sopenharmony_ci 6011fccf17Sopenharmony_civoid HRilEvent::ProcessTimerList() 6111fccf17Sopenharmony_ci{ 6211fccf17Sopenharmony_ci struct timeval now; 6311fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 6411fccf17Sopenharmony_ci std::list<HRilEventMessage>::iterator eventIt = timerList_.begin(); 6511fccf17Sopenharmony_ci GetNowTime(now); 6611fccf17Sopenharmony_ci 6711fccf17Sopenharmony_ci TELEPHONY_LOGD("finding for timers <= %{public}ds + %{public}dus", (int32_t)now.tv_sec, (int32_t)now.tv_usec); 6811fccf17Sopenharmony_ci while ((eventIt != timerList_.end()) && (timercmp(&now, &eventIt->timeout, >))) { 6911fccf17Sopenharmony_ci HRilEventMessage evMsg = {}; 7011fccf17Sopenharmony_ci evMsg.fd = eventIt->fd; 7111fccf17Sopenharmony_ci evMsg.func = eventIt->func; 7211fccf17Sopenharmony_ci evMsg.index = eventIt->index; 7311fccf17Sopenharmony_ci evMsg.param = eventIt->param; 7411fccf17Sopenharmony_ci evMsg.timeout = eventIt->timeout; 7511fccf17Sopenharmony_ci pendingList_.push_back(evMsg); 7611fccf17Sopenharmony_ci eventIt = timerList_.erase(eventIt); 7711fccf17Sopenharmony_ci } 7811fccf17Sopenharmony_ci} 7911fccf17Sopenharmony_ci 8011fccf17Sopenharmony_cibool HRilEvent::HasEventMessageFromPendingList(HRilEventMessage *eventMsg) 8111fccf17Sopenharmony_ci{ 8211fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 8311fccf17Sopenharmony_ci std::list<HRilEventMessage>::iterator eventIt = pendingList_.begin(); 8411fccf17Sopenharmony_ci if (eventIt == pendingList_.end()) { 8511fccf17Sopenharmony_ci return false; 8611fccf17Sopenharmony_ci } 8711fccf17Sopenharmony_ci eventMsg->fd = eventIt->fd; 8811fccf17Sopenharmony_ci eventMsg->func = eventIt->func; 8911fccf17Sopenharmony_ci eventMsg->index = eventIt->index; 9011fccf17Sopenharmony_ci eventMsg->param = eventIt->param; 9111fccf17Sopenharmony_ci eventMsg->timeout = eventIt->timeout; 9211fccf17Sopenharmony_ci pendingList_.erase(eventIt); 9311fccf17Sopenharmony_ci return true; 9411fccf17Sopenharmony_ci} 9511fccf17Sopenharmony_ci 9611fccf17Sopenharmony_civoid HRilEvent::ProcessPendingList() 9711fccf17Sopenharmony_ci{ 9811fccf17Sopenharmony_ci HRilEventMessage evMsg = {}; 9911fccf17Sopenharmony_ci while (HasEventMessageFromPendingList(&evMsg)) { 10011fccf17Sopenharmony_ci if (evMsg.func != nullptr) { 10111fccf17Sopenharmony_ci evMsg.func(evMsg.fd, 0, evMsg.param); 10211fccf17Sopenharmony_ci } 10311fccf17Sopenharmony_ci } 10411fccf17Sopenharmony_ci} 10511fccf17Sopenharmony_ci 10611fccf17Sopenharmony_civoid HRilEvent::EraseListenEvent(HRilEventMessage &eventMsg, int32_t index) 10711fccf17Sopenharmony_ci{ 10811fccf17Sopenharmony_ci listenEventTable_[index] = nullptr; 10911fccf17Sopenharmony_ci eventMsg.index = DEFAULT_INDEX; 11011fccf17Sopenharmony_ci 11111fccf17Sopenharmony_ci FD_CLR(eventMsg.fd, &readFds_); 11211fccf17Sopenharmony_ci 11311fccf17Sopenharmony_ci if (eventMsg.fd + 1 == nfds_) { 11411fccf17Sopenharmony_ci int32_t n = 0; 11511fccf17Sopenharmony_ci for (auto msg : listenEventTable_) { 11611fccf17Sopenharmony_ci if ((msg != nullptr) && (msg->fd > n)) { 11711fccf17Sopenharmony_ci n = msg->fd; 11811fccf17Sopenharmony_ci } 11911fccf17Sopenharmony_ci } 12011fccf17Sopenharmony_ci nfds_ = n + 1; 12111fccf17Sopenharmony_ci TELEPHONY_LOGD("Updated nfds = %{public}d", nfds_); 12211fccf17Sopenharmony_ci } 12311fccf17Sopenharmony_ci} 12411fccf17Sopenharmony_ci 12511fccf17Sopenharmony_civoid HRilEvent::ProcessEvents(fd_set *rfds, int32_t number) 12611fccf17Sopenharmony_ci{ 12711fccf17Sopenharmony_ci if (rfds == nullptr) { 12811fccf17Sopenharmony_ci return; 12911fccf17Sopenharmony_ci } 13011fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 13111fccf17Sopenharmony_ci auto it = listenEventTable_.begin(); 13211fccf17Sopenharmony_ci for (; (it != listenEventTable_.end()) && (number > 0); ++it) { 13311fccf17Sopenharmony_ci if (*it != nullptr && FD_ISSET((*it)->fd, rfds)) { 13411fccf17Sopenharmony_ci pendingList_.push_back(*(*it)); 13511fccf17Sopenharmony_ci if ((*it)->isHolding == false) { 13611fccf17Sopenharmony_ci EraseListenEvent(*(*it), (*it)->index); 13711fccf17Sopenharmony_ci } 13811fccf17Sopenharmony_ci number--; 13911fccf17Sopenharmony_ci } 14011fccf17Sopenharmony_ci } 14111fccf17Sopenharmony_ci} 14211fccf17Sopenharmony_ci 14311fccf17Sopenharmony_civoid HRilEvent::TimerEventInit() 14411fccf17Sopenharmony_ci{ 14511fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 14611fccf17Sopenharmony_ci FD_ZERO(&readFds_); 14711fccf17Sopenharmony_ci timerList_.clear(); 14811fccf17Sopenharmony_ci pendingList_.clear(); 14911fccf17Sopenharmony_ci listenEventTable_.clear(); 15011fccf17Sopenharmony_ci for (int32_t i = 0; i < LISTEN_FD_EVENTS_MAX; i++) { 15111fccf17Sopenharmony_ci listenEventTable_.push_back(nullptr); 15211fccf17Sopenharmony_ci } 15311fccf17Sopenharmony_ci} 15411fccf17Sopenharmony_ci 15511fccf17Sopenharmony_civoid HRilEvent::AddTimerEvent(HRilEventMessage &eventMsg, const struct timeval &tv) 15611fccf17Sopenharmony_ci{ 15711fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 15811fccf17Sopenharmony_ci struct timeval now; 15911fccf17Sopenharmony_ci eventMsg.fd = IVNALID_FD; // make sure fd is invalid 16011fccf17Sopenharmony_ci 16111fccf17Sopenharmony_ci GetNowTime(now); 16211fccf17Sopenharmony_ci timeradd(&now, &tv, &eventMsg.timeout); 16311fccf17Sopenharmony_ci 16411fccf17Sopenharmony_ci std::list<HRilEventMessage>::iterator it = timerList_.begin(); 16511fccf17Sopenharmony_ci for (; it != timerList_.end(); ++it) { 16611fccf17Sopenharmony_ci if (timercmp(&it->timeout, &eventMsg.timeout, >)) { 16711fccf17Sopenharmony_ci timerList_.insert(it, eventMsg); 16811fccf17Sopenharmony_ci return; 16911fccf17Sopenharmony_ci } 17011fccf17Sopenharmony_ci } 17111fccf17Sopenharmony_ci if (it == timerList_.end()) { 17211fccf17Sopenharmony_ci timerList_.push_back(eventMsg); 17311fccf17Sopenharmony_ci } 17411fccf17Sopenharmony_ci} 17511fccf17Sopenharmony_ci 17611fccf17Sopenharmony_civoid HRilEvent::SetTimerEvent( 17711fccf17Sopenharmony_ci HRilEventMessage &eventMsg, int32_t fd, bool isHolding, HRilEventCallback func, std::shared_ptr<void> param) 17811fccf17Sopenharmony_ci{ 17911fccf17Sopenharmony_ci (void)memset_s(&eventMsg, sizeof(HRilEventMessage), 0, sizeof(HRilEventMessage)); 18011fccf17Sopenharmony_ci eventMsg.fd = fd; 18111fccf17Sopenharmony_ci eventMsg.index = DEFAULT_INDEX; 18211fccf17Sopenharmony_ci eventMsg.func = func; 18311fccf17Sopenharmony_ci eventMsg.param = param; 18411fccf17Sopenharmony_ci eventMsg.isHolding = isHolding; 18511fccf17Sopenharmony_ci fcntl(fd, F_SETFL, O_NONBLOCK); 18611fccf17Sopenharmony_ci} 18711fccf17Sopenharmony_ci 18811fccf17Sopenharmony_civoid HRilEvent::AddEventMessage(const HRilEventMessage &eventMsg) 18911fccf17Sopenharmony_ci{ 19011fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 19111fccf17Sopenharmony_ci for (int32_t i = 0; i < LISTEN_FD_EVENTS_MAX; i++) { 19211fccf17Sopenharmony_ci if (listenEventTable_[i] == nullptr) { 19311fccf17Sopenharmony_ci listenEventTable_[i] = const_cast<HRilEventMessage *>(&eventMsg); 19411fccf17Sopenharmony_ci listenEventTable_[i]->index = i; 19511fccf17Sopenharmony_ci FD_SET(eventMsg.fd, &readFds_); 19611fccf17Sopenharmony_ci if (eventMsg.fd >= nfds_) { 19711fccf17Sopenharmony_ci nfds_ = eventMsg.fd + 1; 19811fccf17Sopenharmony_ci } 19911fccf17Sopenharmony_ci break; 20011fccf17Sopenharmony_ci } 20111fccf17Sopenharmony_ci } 20211fccf17Sopenharmony_ci} 20311fccf17Sopenharmony_ci 20411fccf17Sopenharmony_civoid HRilEvent::RemoveEventMessage(HRilEventMessage &eventMsg) 20511fccf17Sopenharmony_ci{ 20611fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 20711fccf17Sopenharmony_ci if (eventMsg.index < 0 || eventMsg.index >= LISTEN_FD_EVENTS_MAX) { 20811fccf17Sopenharmony_ci TELEPHONY_LOGE("Invalid event message! index:%{pubulic}d", eventMsg.index); 20911fccf17Sopenharmony_ci return; 21011fccf17Sopenharmony_ci } 21111fccf17Sopenharmony_ci EraseListenEvent(eventMsg, eventMsg.index); 21211fccf17Sopenharmony_ci} 21311fccf17Sopenharmony_ci 21411fccf17Sopenharmony_civoid HRilEvent::CopyReadFds(fd_set *rfds) 21511fccf17Sopenharmony_ci{ 21611fccf17Sopenharmony_ci std::lock_guard<std::mutex> mutexLock(listLock_); 21711fccf17Sopenharmony_ci (void)memcpy_s(rfds, sizeof(fd_set), &readFds_, sizeof(fd_set)); 21811fccf17Sopenharmony_ci} 21911fccf17Sopenharmony_ci 22011fccf17Sopenharmony_civoid HRilEvent::EventMessageLoop() 22111fccf17Sopenharmony_ci{ 22211fccf17Sopenharmony_ci int32_t ret; 22311fccf17Sopenharmony_ci fd_set rfds; 22411fccf17Sopenharmony_ci struct timeval timeout; 22511fccf17Sopenharmony_ci struct timeval *pTimeOut; 22611fccf17Sopenharmony_ci 22711fccf17Sopenharmony_ci TELEPHONY_LOGD("****** EventMessageLoop start ******"); 22811fccf17Sopenharmony_ci while (1) { 22911fccf17Sopenharmony_ci CopyReadFds(&rfds); 23011fccf17Sopenharmony_ci if (!GetNextTimeOut(timeout)) { 23111fccf17Sopenharmony_ci // Enter blocking wait without setting a timer. 23211fccf17Sopenharmony_ci TELEPHONY_LOGD("Enter blocking wait without setting a timer."); 23311fccf17Sopenharmony_ci pTimeOut = nullptr; 23411fccf17Sopenharmony_ci } else { 23511fccf17Sopenharmony_ci TELEPHONY_LOGD( 23611fccf17Sopenharmony_ci "Setting timeout for %{public}ds + %{public}dus", (int32_t)timeout.tv_sec, (int32_t)timeout.tv_usec); 23711fccf17Sopenharmony_ci pTimeOut = &timeout; 23811fccf17Sopenharmony_ci } 23911fccf17Sopenharmony_ci ret = select(nfds_, &rfds, nullptr, nullptr, pTimeOut); 24011fccf17Sopenharmony_ci TELEPHONY_LOGD("There are %{public}d events fired, isNormalDestory: %{public}d.", ret, isNormalDestory); 24111fccf17Sopenharmony_ci if (isNormalDestory) { 24211fccf17Sopenharmony_ci return; 24311fccf17Sopenharmony_ci } 24411fccf17Sopenharmony_ci if (ret < 0) { 24511fccf17Sopenharmony_ci if (errno == EINTR) { 24611fccf17Sopenharmony_ci continue; 24711fccf17Sopenharmony_ci } 24811fccf17Sopenharmony_ci TELEPHONY_LOGE("select error (%{public}d)", errno); 24911fccf17Sopenharmony_ci return; 25011fccf17Sopenharmony_ci } 25111fccf17Sopenharmony_ci ProcessTimerList(); 25211fccf17Sopenharmony_ci ProcessEvents(&rfds, ret); 25311fccf17Sopenharmony_ci ProcessPendingList(); 25411fccf17Sopenharmony_ci } 25511fccf17Sopenharmony_ci} 25611fccf17Sopenharmony_ci 25711fccf17Sopenharmony_civoid HRilEvent::SetNormalDestory(bool isDestory) 25811fccf17Sopenharmony_ci{ 25911fccf17Sopenharmony_ci isNormalDestory = isDestory; 26011fccf17Sopenharmony_ci} 26111fccf17Sopenharmony_cibool HRilEvent::IsNormalDestory() 26211fccf17Sopenharmony_ci{ 26311fccf17Sopenharmony_ci return isNormalDestory; 26411fccf17Sopenharmony_ci} 26511fccf17Sopenharmony_ci 26611fccf17Sopenharmony_ci} // namespace Telephony 26711fccf17Sopenharmony_ci} // namespace OHOS 268