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 #include "handler.h"
16 #include <iostream>
17 #include <sys/time.h>
18 #include "wifi_log.h"
19 #include "wifi_config_center.h"
20 #include "wifi_watchdog_utils.h"
21 #undef LOG_TAG
22 #define LOG_TAG "OHWIFI_HANDLER"
23 
24 namespace OHOS {
25 namespace Wifi {
26 #ifdef OHOS_ARCH_LITE
Handler()27 Handler::Handler() : pMyQueue(nullptr), handleThread(0), isRunning(true)
28 {}
29 #else
30 Handler::Handler() : pMyTaskQueue(nullptr)
31 {}
32 #endif
~Handler()33 Handler::~Handler()
34 {
35     LOGI("Handler::~Handler");
36     StopHandlerThread();
37     return;
38 }
39 
InitialHandler(const std::string & name)40 bool Handler::InitialHandler(const std::string &name)
41 {
42 #ifdef OHOS_ARCH_LITE
43     if (handleThread != 0) {
44         return true;
45     }
46     if (pMyQueue == nullptr) {
47         pMyQueue = std::make_unique<MessageQueue>();
48         if (pMyQueue == nullptr) {
49             LOGE("pMyQueue alloc failed.\n");
50             return false;
51         }
52     }
53 
54     int ret = pthread_create(&handleThread, nullptr, RunHandleThreadFunc, this);
55     if (ret != 0) {
56         LOGE("pthread_create failed.\n");
57         return false;
58     }
59     LOGI("pthread_create ret: %{public}d\n", ret);
60     pthread_setname_np(handleThread, name.c_str());
61 #else
62     if (pMyTaskQueue == nullptr) {
63         pMyTaskQueue = std::make_unique<WifiEventHandler>(name);
64         if (pMyTaskQueue == nullptr) {
65             LOGE("pMyTaskQueue alloc failed.\n");
66             return false;
67         }
68     }
69 #endif
70     LOGI("InitialHandler success: %{public}s", mThreadName.c_str());
71     mThreadName = name;
72     return true;
73 }
74 
StopHandlerThread()75 void Handler::StopHandlerThread()
76 {
77     LOGI("Enter StopHandlerThread %{public}s", mThreadName.c_str());
78 #ifdef OHOS_ARCH_LITE
79     if (isRunning) {
80         isRunning = false;
81         if (pMyQueue != nullptr) {
82             pMyQueue->StopQueueLoop();
83         }
84         if (handleThread != 0) {
85             pthread_join(handleThread, nullptr);
86         }
87     }
88 #else
89     if (pMyTaskQueue != nullptr) {
90         pMyTaskQueue.reset();
91     }
92 #endif
93     LOGI("Leave StopHandlerThread %{public}s", mThreadName.c_str());
94     return;
95 }
96 
97 #ifdef OHOS_ARCH_LITE
RunHandleThreadFunc(void * pInstance)98 void *Handler::RunHandleThreadFunc(void *pInstance)
99 {
100     if (pInstance == nullptr) {
101         LOGE("pInstance is null.\n");
102         return nullptr;
103     }
104 
105     LOGI("Run handler func.");
106     Handler *pHandler = (Handler *)pInstance;
107     pHandler->GetAndDistributeMessage();
108 
109     return nullptr;
110 }
111 
GetAndDistributeMessage()112 void Handler::GetAndDistributeMessage()
113 {
114     if (pMyQueue == nullptr) {
115         LOGE("pMyQueue is null.\n");
116         return;
117     }
118 
119     while (isRunning) {
120         InternalMessagePtr msg = pMyQueue->GetNextMessage();
121         if (msg == nullptr) {
122             LOGE("GetNextMessage null.\n");
123             continue;
124         }
125         LOGD("Handler get message: %{public}d\n", msg->GetMessageName());
126         WifiConfigCenter::GetInstance().SetThreadStatusFlag(true);
127         DistributeMessage(msg);
128         MessageManage::GetInstance().ReclaimMsg(msg);
129         WifiConfigCenter::GetInstance().SetThreadStatusFlag(false);
130     }
131 
132     return;
133 }
134 #endif
135 
SendMessage(InternalMessagePtr msg)136 void Handler::SendMessage(InternalMessagePtr msg)
137 {
138     if (msg == nullptr) {
139         LOGE("%{public}s SendMessage: msg is null.", mThreadName.c_str());
140         return;
141     }
142     LOGD("%{public}s SendMessage msg:%{public}d", mThreadName.c_str(), msg->GetMessageName());
143 #ifdef OHOS_ARCH_LITE
144     MessageExecutedLater(msg, 0);
145 #else
146     std::function<void()> func = std::bind([this, msg]() {
147         LOGI("%{public}s ExecuteMessage msg:%{public}d", mThreadName.c_str(), msg->GetMessageName());
148         ExecuteMessage(msg);
149         MessageManage::GetInstance().ReclaimMsg(msg);
150         });
151     if (pMyTaskQueue != nullptr) {
152         pMyTaskQueue->PostAsyncTask(func, std::to_string(msg->GetMessageName()), 0);
153     }
154 #endif
155     return;
156 }
157 
MessageExecutedLater(InternalMessagePtr msg,int64_t delayTimeMs)158 void Handler::MessageExecutedLater(InternalMessagePtr msg, int64_t delayTimeMs)
159 {
160     if (msg == nullptr) {
161         LOGE("%{public}s MessageExecutedLater: msg is null.", mThreadName.c_str());
162         return;
163     }
164 
165     LOGD("%{public}s MessageExecutedLater msg:%{public}d %{public}" PRId64,
166         mThreadName.c_str(), msg->GetMessageName(), delayTimeMs);
167     int64_t delayTime = delayTimeMs;
168     if (delayTime < 0) {
169         delayTime = 0;
170     }
171 #ifdef OHOS_ARCH_LITE
172     /* Obtains the current time, accurate to milliseconds. */
173     struct timespec curTime = {0, 0};
174     if (clock_gettime(CLOCK_MONOTONIC, &curTime) != 0) {
175         LOGE("clock_gettime failed.");
176         MessageManage::GetInstance().ReclaimMsg(msg);
177         return;
178     }
179     int64_t nowTime = static_cast<int64_t>(curTime.tv_sec) * USEC_1000 +
180         curTime.tv_nsec / (USEC_1000 * USEC_1000);
181 
182     MessageExecutedAtTime(msg, nowTime + delayTime);
183 #else
184     if (pMyTaskQueue == nullptr) {
185         LOGE("%{public}s pMyTaskQueue is null.\n", mThreadName.c_str());
186         MessageManage::GetInstance().ReclaimMsg(msg);
187         return;
188     }
189     std::function<void()> func = std::bind([this, msg]() {
190         LOGI("%{public}s ExecuteMessage msg:%{public}d", mThreadName.c_str(), msg->GetMessageName());
191         ExecuteMessage(msg);
192         MessageManage::GetInstance().ReclaimMsg(msg);
193         });
194     pMyTaskQueue->PostAsyncTask(func, std::to_string(msg->GetMessageName()), delayTime);
195 #endif
196     return;
197 }
198 
MessageExecutedAtTime(InternalMessagePtr msg,int64_t execTime)199 void Handler::MessageExecutedAtTime(InternalMessagePtr msg, int64_t execTime)
200 {
201     if (msg == nullptr) {
202         LOGE("%{public}s MessageExecutedAtTime: msg is null.", mThreadName.c_str());
203         return;
204     }
205 
206     LOGD("{%public}s MessageExecutedAtTime msg: %{public}d", mThreadName.c_str(), msg->GetMessageName());
207 #ifdef OHOS_ARCH_LITE
208     if (pMyQueue == nullptr) {
209         LOGE("pMyQueue is null.\n");
210         MessageManage::GetInstance().ReclaimMsg(msg);
211         return;
212     }
213 
214     if (pMyQueue->AddMessageToQueue(msg, execTime) != true) {
215         LOGE("AddMessageToQueue failed.\n");
216         return;
217     }
218 #else
219     /* Obtains the current time, accurate to milliseconds. */
220     struct timespec curTime = {0, 0};
221     if (clock_gettime(CLOCK_MONOTONIC, &curTime) != 0) {
222         LOGE("clock_gettime failed.");
223         MessageManage::GetInstance().ReclaimMsg(msg);
224         return;
225     }
226     int64_t nowTime = static_cast<int64_t>(curTime.tv_sec) * USEC_1000 +
227         curTime.tv_nsec / (USEC_1000 * USEC_1000);
228     MessageExecutedLater(msg, execTime - nowTime);
229 #endif
230     return;
231 }
232 
PlaceMessageTopOfQueue(InternalMessagePtr msg)233 void Handler::PlaceMessageTopOfQueue(InternalMessagePtr msg)
234 {
235     if (msg == nullptr) {
236         LOGE("%{public}s PlaceMessageTopOfQueue: msg is null.", mThreadName.c_str());
237         return;
238     }
239 
240     LOGD("%{public}s PlaceMessageTopOfQueue msg: %{public}d", mThreadName.c_str(), msg->GetMessageName());
241 #ifdef OHOS_ARCH_LITE
242     if (pMyQueue == nullptr) {
243         LOGE("pMyQueue is null.\n");
244         MessageManage::GetInstance().ReclaimMsg(msg);
245         return;
246     }
247 
248     if (!pMyQueue->AddMessageToQueue(msg, 0)) {
249         LOGE("AddMessageToQueue failed.\n");
250         return;
251     }
252 #else
253     MessageExecutedLater(msg, 0);
254 #endif
255     return;
256 }
257 
DeleteMessageFromQueue(int messageName)258 void Handler::DeleteMessageFromQueue(int messageName)
259 {
260     LOGD("%{public}s DeleteMessageFromQueue msg is: %{public}d", mThreadName.c_str(), messageName);
261 #ifdef OHOS_ARCH_LITE
262     if (pMyQueue == nullptr) {
263         LOGE("pMyQueue is null.\n");
264         return;
265     }
266 
267     if (!pMyQueue->DeleteMessageFromQueue(messageName)) {
268         LOGE("DeleteMessageFromQueue failed.\n");
269         return;
270     }
271 #else
272     if (pMyTaskQueue == nullptr) {
273         LOGE("%{public}s pMyQueue is null.\n", mThreadName.c_str());
274         return;
275     }
276     pMyTaskQueue->RemoveAsyncTask(std::to_string(messageName));
277 #endif
278     return;
279 }
280 #ifdef OHOS_ARCH_LITE
DistributeMessage(InternalMessagePtr msg)281 void Handler::DistributeMessage(InternalMessagePtr msg)
282 {
283     if (msg == nullptr) {
284         return;
285     }
286     ExecuteMessage(msg);
287     return;
288 }
289 #endif
290 }  // namespace Wifi
291 }  // namespace OHOS