111fccf17Sopenharmony_ci/* 211fccf17Sopenharmony_ci * Copyright (C) 2021 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_timer_callback.h" 1711fccf17Sopenharmony_ci 1811fccf17Sopenharmony_ci#include <cerrno> 1911fccf17Sopenharmony_ci#include <fcntl.h> 2011fccf17Sopenharmony_ci#include <csignal> 2111fccf17Sopenharmony_ci#include <sys/select.h> 2211fccf17Sopenharmony_ci#include <sys/types.h> 2311fccf17Sopenharmony_ci#include <unistd.h> 2411fccf17Sopenharmony_ci 2511fccf17Sopenharmony_ci#include "securec.h" 2611fccf17Sopenharmony_ci 2711fccf17Sopenharmony_ci#include "telephony_log_wrapper.h" 2811fccf17Sopenharmony_ci 2911fccf17Sopenharmony_cinamespace OHOS { 3011fccf17Sopenharmony_cinamespace Telephony { 3111fccf17Sopenharmony_civoid HRilTimerCallback::FdTriggerCallback(int32_t fd, int16_t events, std::shared_ptr<void> param) 3211fccf17Sopenharmony_ci{ 3311fccf17Sopenharmony_ci int32_t ret; 3411fccf17Sopenharmony_ci int8_t buff[READ_FD_BUFF_SIZE]; 3511fccf17Sopenharmony_ci 3611fccf17Sopenharmony_ci do { 3711fccf17Sopenharmony_ci ret = read(triggerReadFd_, &buff, sizeof(buff)); 3811fccf17Sopenharmony_ci } while (ret > 0 || (ret < 0 && errno == EINTR)); 3911fccf17Sopenharmony_ci} 4011fccf17Sopenharmony_ci 4111fccf17Sopenharmony_civoid HRilTimerCallback::TimerCallback(int32_t fd, int16_t events, std::shared_ptr<void> param) 4211fccf17Sopenharmony_ci{ 4311fccf17Sopenharmony_ci HRilTimerCallbackMessage *pCbMsg = (HRilTimerCallbackMessage *)(param.get()); 4411fccf17Sopenharmony_ci if (pCbMsg == nullptr) { 4511fccf17Sopenharmony_ci TELEPHONY_LOGE("Argument conversion failed. pCbMsg is nullptr!"); 4611fccf17Sopenharmony_ci return; 4711fccf17Sopenharmony_ci } 4811fccf17Sopenharmony_ci if (pCbMsg->func != nullptr) { 4911fccf17Sopenharmony_ci pCbMsg->func(pCbMsg->param); 5011fccf17Sopenharmony_ci } else { 5111fccf17Sopenharmony_ci TELEPHONY_LOGE("HRilTimerCallbackMessage func is nullptr"); 5211fccf17Sopenharmony_ci } 5311fccf17Sopenharmony_ci} 5411fccf17Sopenharmony_ci 5511fccf17Sopenharmony_civoid HRilTimerCallback::OnTriggerEvent() 5611fccf17Sopenharmony_ci{ 5711fccf17Sopenharmony_ci if (std::this_thread::get_id() == eventLoopTid_) { 5811fccf17Sopenharmony_ci // Write operations are prohibited in read threads. 5911fccf17Sopenharmony_ci TELEPHONY_LOGE("Currently in a read thread."); 6011fccf17Sopenharmony_ci return; 6111fccf17Sopenharmony_ci } 6211fccf17Sopenharmony_ci int ret; 6311fccf17Sopenharmony_ci do { 6411fccf17Sopenharmony_ci ret = write(triggerWriteFd_, " ", 1); 6511fccf17Sopenharmony_ci } while (ret < 0 && errno == EINTR); 6611fccf17Sopenharmony_ci} 6711fccf17Sopenharmony_ci 6811fccf17Sopenharmony_cistd::shared_ptr<HRilTimerCallbackMessage> HRilTimerCallback::HRilSetTimerCallbackInfo( 6911fccf17Sopenharmony_ci HRilCallbackFun func, uint8_t *param, const struct timeval *tv) 7011fccf17Sopenharmony_ci{ 7111fccf17Sopenharmony_ci struct timeval timeout; 7211fccf17Sopenharmony_ci std::shared_ptr<HRilTimerCallbackMessage> pCbMsg = std::make_shared<HRilTimerCallbackMessage>(); 7311fccf17Sopenharmony_ci if (event_ == nullptr || pCbMsg == nullptr) { 7411fccf17Sopenharmony_ci TELEPHONY_LOGE("HRilSetTimerCallbackInfo event_ or pCbMsg is nullptr"); 7511fccf17Sopenharmony_ci return nullptr; 7611fccf17Sopenharmony_ci } 7711fccf17Sopenharmony_ci pCbMsg->func = func; 7811fccf17Sopenharmony_ci pCbMsg->param = param; 7911fccf17Sopenharmony_ci 8011fccf17Sopenharmony_ci if (tv == NULL) { 8111fccf17Sopenharmony_ci (void)memset_s(&timeout, sizeof(timeout), 0, sizeof(timeout)); 8211fccf17Sopenharmony_ci } else { 8311fccf17Sopenharmony_ci (void)memcpy_s(&timeout, sizeof(timeout), tv, sizeof(timeout)); 8411fccf17Sopenharmony_ci } 8511fccf17Sopenharmony_ci 8611fccf17Sopenharmony_ci HRilEventMessage eventMsg = { 0 }; 8711fccf17Sopenharmony_ci auto funcCallback = 8811fccf17Sopenharmony_ci [this](int32_t fd, int16_t events, std::shared_ptr<void> param) { this->TimerCallback(fd, events, param); }; 8911fccf17Sopenharmony_ci event_->SetTimerEvent(eventMsg, event_->IVNALID_FD, false, funcCallback, pCbMsg); 9011fccf17Sopenharmony_ci event_->AddTimerEvent(eventMsg, timeout); 9111fccf17Sopenharmony_ci OnTriggerEvent(); 9211fccf17Sopenharmony_ci return pCbMsg; 9311fccf17Sopenharmony_ci} 9411fccf17Sopenharmony_ci 9511fccf17Sopenharmony_civoid HRilTimerCallback::EventLoop() 9611fccf17Sopenharmony_ci{ 9711fccf17Sopenharmony_ci TELEPHONY_LOGI("EventLoop start"); 9811fccf17Sopenharmony_ci eventLoopTid_ = std::this_thread::get_id(); 9911fccf17Sopenharmony_ci event_ = std::make_unique<HRilEvent>(); 10011fccf17Sopenharmony_ci event_->TimerEventInit(); 10111fccf17Sopenharmony_ci 10211fccf17Sopenharmony_ci int32_t pipedes[PIPE_SIZE_MAX]; 10311fccf17Sopenharmony_ci int32_t ret = pipe(pipedes); 10411fccf17Sopenharmony_ci if (ret < 0) { 10511fccf17Sopenharmony_ci TELEPHONY_LOGE("Call pipe() is failed, errno:%{public}d", errno); 10611fccf17Sopenharmony_ci return; 10711fccf17Sopenharmony_ci } 10811fccf17Sopenharmony_ci 10911fccf17Sopenharmony_ci triggerReadFd_ = pipedes[0]; 11011fccf17Sopenharmony_ci triggerWriteFd_ = pipedes[1]; 11111fccf17Sopenharmony_ci 11211fccf17Sopenharmony_ci fcntl(triggerReadFd_, F_SETFL, O_NONBLOCK); 11311fccf17Sopenharmony_ci auto func = 11411fccf17Sopenharmony_ci [this](int32_t fd, int16_t events, std::shared_ptr<void> param) { this->FdTriggerCallback(fd, events, param); }; 11511fccf17Sopenharmony_ci event_->SetTimerEvent(fdTriggerEvent_, triggerReadFd_, true, func, NULL); 11611fccf17Sopenharmony_ci event_->AddEventMessage(fdTriggerEvent_); 11711fccf17Sopenharmony_ci event_->EventMessageLoop(); 11811fccf17Sopenharmony_ci TELEPHONY_LOGE("error in EventMessageLoop errno:%{public}d, isNormalDestory:%{public}d", 11911fccf17Sopenharmony_ci errno, event_->IsNormalDestory()); 12011fccf17Sopenharmony_ci if (!event_->IsNormalDestory()) { 12111fccf17Sopenharmony_ci EventLoop(); 12211fccf17Sopenharmony_ci } 12311fccf17Sopenharmony_ci} 12411fccf17Sopenharmony_ci} // namespace Telephony 12511fccf17Sopenharmony_ci} // namespace OHOS