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