• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "hril_timer_callback.h"
17 
18 #include <cerrno>
19 #include <fcntl.h>
20 #include <csignal>
21 #include <sys/select.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include "securec.h"
26 
27 #include "telephony_log_wrapper.h"
28 
29 namespace OHOS {
30 namespace Telephony {
FdTriggerCallback(int32_t fd,int16_t events,std::shared_ptr<void> param)31 void HRilTimerCallback::FdTriggerCallback(int32_t fd, int16_t events, std::shared_ptr<void> param)
32 {
33     int32_t ret;
34     int8_t buff[READ_FD_BUFF_SIZE];
35 
36     do {
37         ret = read(triggerReadFd_, &buff, sizeof(buff));
38     } while (ret > 0 || (ret < 0 && errno == EINTR));
39 }
40 
TimerCallback(int32_t fd,int16_t events,std::shared_ptr<void> param)41 void HRilTimerCallback::TimerCallback(int32_t fd, int16_t events, std::shared_ptr<void> param)
42 {
43     HRilTimerCallbackMessage *pCbMsg = (HRilTimerCallbackMessage *)(param.get());
44     if (pCbMsg == nullptr) {
45         TELEPHONY_LOGE("Argument conversion failed. pCbMsg is nullptr!");
46         return;
47     }
48     if (pCbMsg->func != nullptr) {
49         pCbMsg->func(pCbMsg->param);
50     } else {
51         TELEPHONY_LOGE("HRilTimerCallbackMessage func is nullptr");
52     }
53 }
54 
OnTriggerEvent()55 void HRilTimerCallback::OnTriggerEvent()
56 {
57     if (std::this_thread::get_id() == eventLoopTid_) {
58         // Write operations are prohibited in read threads.
59         TELEPHONY_LOGE("Currently in a read thread.");
60         return;
61     }
62     int ret;
63     do {
64         ret = write(triggerWriteFd_, " ", 1);
65     } while (ret < 0 && errno == EINTR);
66 }
67 
HRilSetTimerCallbackInfo(HRilCallbackFun func,uint8_t * param,const struct timeval * tv)68 std::shared_ptr<HRilTimerCallbackMessage> HRilTimerCallback::HRilSetTimerCallbackInfo(
69     HRilCallbackFun func, uint8_t *param, const struct timeval *tv)
70 {
71     struct timeval timeout;
72     std::shared_ptr<HRilTimerCallbackMessage> pCbMsg = std::make_shared<HRilTimerCallbackMessage>();
73     if (event_ == nullptr || pCbMsg == nullptr) {
74         TELEPHONY_LOGE("HRilSetTimerCallbackInfo event_ or pCbMsg is nullptr");
75         return nullptr;
76     }
77     pCbMsg->func = func;
78     pCbMsg->param = param;
79 
80     if (tv == NULL) {
81         (void)memset_s(&timeout, sizeof(timeout), 0, sizeof(timeout));
82     } else {
83         (void)memcpy_s(&timeout, sizeof(timeout), tv, sizeof(timeout));
84     }
85 
86     HRilEventMessage eventMsg = { 0 };
87     auto funcCallback = std::bind(
88         &HRilTimerCallback::TimerCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
89     event_->SetTimerEvent(eventMsg, event_->IVNALID_FD, false, funcCallback, pCbMsg);
90     event_->AddTimerEvent(eventMsg, timeout);
91     OnTriggerEvent();
92     return pCbMsg;
93 }
94 
EventLoop()95 void HRilTimerCallback::EventLoop()
96 {
97     TELEPHONY_LOGI("EventLoop start");
98     eventLoopTid_ = std::this_thread::get_id();
99     event_ = std::make_unique<HRilEvent>();
100     event_->TimerEventInit();
101 
102     int32_t pipedes[PIPE_SIZE_MAX];
103     int32_t ret = pipe(pipedes);
104     if (ret < 0) {
105         TELEPHONY_LOGE("Call pipe() is failed, errno:%{public}d", errno);
106         return;
107     }
108 
109     triggerReadFd_ = pipedes[0];
110     triggerWriteFd_ = pipedes[1];
111 
112     fcntl(triggerReadFd_, F_SETFL, O_NONBLOCK);
113     auto func = std::bind(&HRilTimerCallback::FdTriggerCallback, this, std::placeholders::_1, std::placeholders::_2,
114         std::placeholders::_3);
115     event_->SetTimerEvent(fdTriggerEvent_, triggerReadFd_, true, func, NULL);
116     event_->AddEventMessage(fdTriggerEvent_);
117     event_->EventMessageLoop();
118     TELEPHONY_LOGE("error in EventMessageLoop errno:%{public}d, isNormalDestory:%{public}d",
119         errno, event_->IsNormalDestory());
120     if (!event_->IsNormalDestory()) {
121         EventLoop();
122     }
123 }
124 } // namespace Telephony
125 } // namespace OHOS