1f1549183Sopenharmony_ci/*
2f1549183Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3f1549183Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f1549183Sopenharmony_ci * you may not use this file except in compliance with the License.
5f1549183Sopenharmony_ci * You may obtain a copy of the License at
6f1549183Sopenharmony_ci *
7f1549183Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f1549183Sopenharmony_ci *
9f1549183Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f1549183Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f1549183Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f1549183Sopenharmony_ci * See the License for the specific language governing permissions and
13f1549183Sopenharmony_ci * limitations under the License.
14f1549183Sopenharmony_ci */
15f1549183Sopenharmony_ci#include "handler.h"
16f1549183Sopenharmony_ci#include <iostream>
17f1549183Sopenharmony_ci#include <sys/time.h>
18f1549183Sopenharmony_ci#include "wifi_log.h"
19f1549183Sopenharmony_ci#include "wifi_config_center.h"
20f1549183Sopenharmony_ci#include "wifi_watchdog_utils.h"
21f1549183Sopenharmony_ci#undef LOG_TAG
22f1549183Sopenharmony_ci#define LOG_TAG "OHWIFI_HANDLER"
23f1549183Sopenharmony_ci
24f1549183Sopenharmony_cinamespace OHOS {
25f1549183Sopenharmony_cinamespace Wifi {
26f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
27f1549183Sopenharmony_ciHandler::Handler() : pMyQueue(nullptr), handleThread(0), isRunning(true)
28f1549183Sopenharmony_ci{}
29f1549183Sopenharmony_ci#else
30f1549183Sopenharmony_ciHandler::Handler() : pMyTaskQueue(nullptr)
31f1549183Sopenharmony_ci{}
32f1549183Sopenharmony_ci#endif
33f1549183Sopenharmony_ciHandler::~Handler()
34f1549183Sopenharmony_ci{
35f1549183Sopenharmony_ci    LOGI("Handler::~Handler");
36f1549183Sopenharmony_ci    StopHandlerThread();
37f1549183Sopenharmony_ci    return;
38f1549183Sopenharmony_ci}
39f1549183Sopenharmony_ci
40f1549183Sopenharmony_cibool Handler::InitialHandler(const std::string &name)
41f1549183Sopenharmony_ci{
42f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
43f1549183Sopenharmony_ci    if (handleThread != 0) {
44f1549183Sopenharmony_ci        return true;
45f1549183Sopenharmony_ci    }
46f1549183Sopenharmony_ci    if (pMyQueue == nullptr) {
47f1549183Sopenharmony_ci        pMyQueue = std::make_unique<MessageQueue>();
48f1549183Sopenharmony_ci    }
49f1549183Sopenharmony_ci
50f1549183Sopenharmony_ci    int ret = pthread_create(&handleThread, nullptr, RunHandleThreadFunc, this);
51f1549183Sopenharmony_ci    if (ret != 0) {
52f1549183Sopenharmony_ci        LOGE("pthread_create failed.\n");
53f1549183Sopenharmony_ci        return false;
54f1549183Sopenharmony_ci    }
55f1549183Sopenharmony_ci    LOGI("pthread_create ret: %{public}d\n", ret);
56f1549183Sopenharmony_ci    pthread_setname_np(handleThread, name.c_str());
57f1549183Sopenharmony_ci#else
58f1549183Sopenharmony_ci    if (pMyTaskQueue == nullptr) {
59f1549183Sopenharmony_ci        pMyTaskQueue = std::make_unique<WifiEventHandler>(name);
60f1549183Sopenharmony_ci    }
61f1549183Sopenharmony_ci    WifiWatchDogUtils::GetInstance();
62f1549183Sopenharmony_ci#endif
63f1549183Sopenharmony_ci    LOGI("InitialHandler success: %{public}s", mThreadName.c_str());
64f1549183Sopenharmony_ci    mThreadName = name;
65f1549183Sopenharmony_ci    return true;
66f1549183Sopenharmony_ci}
67f1549183Sopenharmony_ci
68f1549183Sopenharmony_civoid Handler::StopHandlerThread()
69f1549183Sopenharmony_ci{
70f1549183Sopenharmony_ci    LOGI("Enter StopHandlerThread %{public}s", mThreadName.c_str());
71f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
72f1549183Sopenharmony_ci    if (isRunning) {
73f1549183Sopenharmony_ci        isRunning = false;
74f1549183Sopenharmony_ci        if (pMyQueue != nullptr) {
75f1549183Sopenharmony_ci            pMyQueue->StopQueueLoop();
76f1549183Sopenharmony_ci        }
77f1549183Sopenharmony_ci        if (handleThread != 0) {
78f1549183Sopenharmony_ci            pthread_join(handleThread, nullptr);
79f1549183Sopenharmony_ci        }
80f1549183Sopenharmony_ci    }
81f1549183Sopenharmony_ci#else
82f1549183Sopenharmony_ci    if (pMyTaskQueue != nullptr) {
83f1549183Sopenharmony_ci        pMyTaskQueue.reset();
84f1549183Sopenharmony_ci    }
85f1549183Sopenharmony_ci#endif
86f1549183Sopenharmony_ci    LOGI("Leave StopHandlerThread %{public}s", mThreadName.c_str());
87f1549183Sopenharmony_ci    return;
88f1549183Sopenharmony_ci}
89f1549183Sopenharmony_ci
90f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
91f1549183Sopenharmony_civoid *Handler::RunHandleThreadFunc(void *pInstance)
92f1549183Sopenharmony_ci{
93f1549183Sopenharmony_ci    if (pInstance == nullptr) {
94f1549183Sopenharmony_ci        LOGE("pInstance is null.\n");
95f1549183Sopenharmony_ci        return nullptr;
96f1549183Sopenharmony_ci    }
97f1549183Sopenharmony_ci
98f1549183Sopenharmony_ci    LOGI("Run handler func.");
99f1549183Sopenharmony_ci    Handler *pHandler = (Handler *)pInstance;
100f1549183Sopenharmony_ci    pHandler->GetAndDistributeMessage();
101f1549183Sopenharmony_ci
102f1549183Sopenharmony_ci    return nullptr;
103f1549183Sopenharmony_ci}
104f1549183Sopenharmony_ci
105f1549183Sopenharmony_civoid Handler::GetAndDistributeMessage()
106f1549183Sopenharmony_ci{
107f1549183Sopenharmony_ci    if (pMyQueue == nullptr) {
108f1549183Sopenharmony_ci        LOGE("pMyQueue is null.\n");
109f1549183Sopenharmony_ci        return;
110f1549183Sopenharmony_ci    }
111f1549183Sopenharmony_ci
112f1549183Sopenharmony_ci    while (isRunning) {
113f1549183Sopenharmony_ci        InternalMessagePtr msg = pMyQueue->GetNextMessage();
114f1549183Sopenharmony_ci        if (msg == nullptr) {
115f1549183Sopenharmony_ci            LOGE("GetNextMessage null.\n");
116f1549183Sopenharmony_ci            continue;
117f1549183Sopenharmony_ci        }
118f1549183Sopenharmony_ci        LOGD("Handler get message: %{public}d\n", msg->GetMessageName());
119f1549183Sopenharmony_ci        WifiConfigCenter::GetInstance().SetThreadStatusFlag(true);
120f1549183Sopenharmony_ci        DistributeMessage(msg);
121f1549183Sopenharmony_ci        MessageManage::GetInstance().ReclaimMsg(msg);
122f1549183Sopenharmony_ci        WifiConfigCenter::GetInstance().SetThreadStatusFlag(false);
123f1549183Sopenharmony_ci    }
124f1549183Sopenharmony_ci
125f1549183Sopenharmony_ci    return;
126f1549183Sopenharmony_ci}
127f1549183Sopenharmony_ci#endif
128f1549183Sopenharmony_ci
129f1549183Sopenharmony_civoid Handler::SendMessage(InternalMessagePtr msg)
130f1549183Sopenharmony_ci{
131f1549183Sopenharmony_ci    if (msg == nullptr) {
132f1549183Sopenharmony_ci        LOGE("%{public}s SendMessage: msg is null.", mThreadName.c_str());
133f1549183Sopenharmony_ci        return;
134f1549183Sopenharmony_ci    }
135f1549183Sopenharmony_ci    LOGD("%{public}s SendMessage msg:%{public}d", mThreadName.c_str(), msg->GetMessageName());
136f1549183Sopenharmony_ci    MessageExecutedLater(msg, 0);
137f1549183Sopenharmony_ci    return;
138f1549183Sopenharmony_ci}
139f1549183Sopenharmony_ci
140f1549183Sopenharmony_civoid Handler::MessageExecutedLater(InternalMessagePtr msg, int64_t delayTimeMs)
141f1549183Sopenharmony_ci{
142f1549183Sopenharmony_ci    if (msg == nullptr) {
143f1549183Sopenharmony_ci        LOGE("%{public}s MessageExecutedLater: msg is null.", mThreadName.c_str());
144f1549183Sopenharmony_ci        return;
145f1549183Sopenharmony_ci    }
146f1549183Sopenharmony_ci
147f1549183Sopenharmony_ci    LOGD("%{public}s MessageExecutedLater msg:%{public}d %{public}" PRId64,
148f1549183Sopenharmony_ci        mThreadName.c_str(), msg->GetMessageName(), delayTimeMs);
149f1549183Sopenharmony_ci    int64_t delayTime = delayTimeMs;
150f1549183Sopenharmony_ci    if (delayTime < 0) {
151f1549183Sopenharmony_ci        delayTime = 0;
152f1549183Sopenharmony_ci    }
153f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
154f1549183Sopenharmony_ci    /* Obtains the current time, accurate to milliseconds. */
155f1549183Sopenharmony_ci    struct timespec curTime = {0, 0};
156f1549183Sopenharmony_ci    if (clock_gettime(CLOCK_MONOTONIC, &curTime) != 0) {
157f1549183Sopenharmony_ci        LOGE("clock_gettime failed.");
158f1549183Sopenharmony_ci        MessageManage::GetInstance().ReclaimMsg(msg);
159f1549183Sopenharmony_ci        return;
160f1549183Sopenharmony_ci    }
161f1549183Sopenharmony_ci    int64_t nowTime = static_cast<int64_t>(curTime.tv_sec) * USEC_1000 +
162f1549183Sopenharmony_ci        curTime.tv_nsec / (USEC_1000 * USEC_1000);
163f1549183Sopenharmony_ci
164f1549183Sopenharmony_ci    MessageExecutedAtTime(msg, nowTime + delayTime);
165f1549183Sopenharmony_ci#else
166f1549183Sopenharmony_ci    if (pMyTaskQueue == nullptr) {
167f1549183Sopenharmony_ci        LOGE("%{public}s pMyTaskQueue is null.\n", mThreadName.c_str());
168f1549183Sopenharmony_ci        MessageManage::GetInstance().ReclaimMsg(msg);
169f1549183Sopenharmony_ci        return;
170f1549183Sopenharmony_ci    }
171f1549183Sopenharmony_ci    std::function<void()> func = std::bind([this, msg]() {
172f1549183Sopenharmony_ci        LOGI("%{public}s ExecuteMessage msg:%{public}d", mThreadName.c_str(), msg->GetMessageName());
173f1549183Sopenharmony_ci        ExecuteMessage(msg);
174f1549183Sopenharmony_ci        MessageManage::GetInstance().ReclaimMsg(msg);
175f1549183Sopenharmony_ci    });
176f1549183Sopenharmony_ci    pMyTaskQueue->PostAsyncTask(func, std::to_string(msg->GetMessageName()), delayTime);
177f1549183Sopenharmony_ci#endif
178f1549183Sopenharmony_ci    return;
179f1549183Sopenharmony_ci}
180f1549183Sopenharmony_ci
181f1549183Sopenharmony_civoid Handler::MessageExecutedAtTime(InternalMessagePtr msg, int64_t execTime)
182f1549183Sopenharmony_ci{
183f1549183Sopenharmony_ci    if (msg == nullptr) {
184f1549183Sopenharmony_ci        LOGE("%{public}s MessageExecutedAtTime: msg is null.", mThreadName.c_str());
185f1549183Sopenharmony_ci        return;
186f1549183Sopenharmony_ci    }
187f1549183Sopenharmony_ci
188f1549183Sopenharmony_ci    LOGD("{%public}s MessageExecutedAtTime msg: %{public}d", mThreadName.c_str(), msg->GetMessageName());
189f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
190f1549183Sopenharmony_ci    if (pMyQueue == nullptr) {
191f1549183Sopenharmony_ci        LOGE("pMyQueue is null.\n");
192f1549183Sopenharmony_ci        MessageManage::GetInstance().ReclaimMsg(msg);
193f1549183Sopenharmony_ci        return;
194f1549183Sopenharmony_ci    }
195f1549183Sopenharmony_ci
196f1549183Sopenharmony_ci    if (pMyQueue->AddMessageToQueue(msg, execTime) != true) {
197f1549183Sopenharmony_ci        LOGE("AddMessageToQueue failed.\n");
198f1549183Sopenharmony_ci        return;
199f1549183Sopenharmony_ci    }
200f1549183Sopenharmony_ci#else
201f1549183Sopenharmony_ci    /* Obtains the current time, accurate to milliseconds. */
202f1549183Sopenharmony_ci    struct timespec curTime = {0, 0};
203f1549183Sopenharmony_ci    if (clock_gettime(CLOCK_MONOTONIC, &curTime) != 0) {
204f1549183Sopenharmony_ci        LOGE("clock_gettime failed.");
205f1549183Sopenharmony_ci        MessageManage::GetInstance().ReclaimMsg(msg);
206f1549183Sopenharmony_ci        return;
207f1549183Sopenharmony_ci    }
208f1549183Sopenharmony_ci    int64_t nowTime = static_cast<int64_t>(curTime.tv_sec) * USEC_1000 +
209f1549183Sopenharmony_ci        curTime.tv_nsec / (USEC_1000 * USEC_1000);
210f1549183Sopenharmony_ci    MessageExecutedLater(msg, execTime - nowTime);
211f1549183Sopenharmony_ci#endif
212f1549183Sopenharmony_ci    return;
213f1549183Sopenharmony_ci}
214f1549183Sopenharmony_ci
215f1549183Sopenharmony_civoid Handler::PlaceMessageTopOfQueue(InternalMessagePtr msg)
216f1549183Sopenharmony_ci{
217f1549183Sopenharmony_ci    if (msg == nullptr) {
218f1549183Sopenharmony_ci        LOGE("%{public}s PlaceMessageTopOfQueue: msg is null.", mThreadName.c_str());
219f1549183Sopenharmony_ci        return;
220f1549183Sopenharmony_ci    }
221f1549183Sopenharmony_ci
222f1549183Sopenharmony_ci    LOGD("%{public}s PlaceMessageTopOfQueue msg: %{public}d", mThreadName.c_str(), msg->GetMessageName());
223f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
224f1549183Sopenharmony_ci    if (pMyQueue == nullptr) {
225f1549183Sopenharmony_ci        LOGE("pMyQueue is null.\n");
226f1549183Sopenharmony_ci        MessageManage::GetInstance().ReclaimMsg(msg);
227f1549183Sopenharmony_ci        return;
228f1549183Sopenharmony_ci    }
229f1549183Sopenharmony_ci
230f1549183Sopenharmony_ci    if (!pMyQueue->AddMessageToQueue(msg, 0)) {
231f1549183Sopenharmony_ci        LOGE("AddMessageToQueue failed.\n");
232f1549183Sopenharmony_ci        return;
233f1549183Sopenharmony_ci    }
234f1549183Sopenharmony_ci#else
235f1549183Sopenharmony_ci    MessageExecutedLater(msg, 0);
236f1549183Sopenharmony_ci#endif
237f1549183Sopenharmony_ci    return;
238f1549183Sopenharmony_ci}
239f1549183Sopenharmony_ci
240f1549183Sopenharmony_civoid Handler::DeleteMessageFromQueue(int messageName)
241f1549183Sopenharmony_ci{
242f1549183Sopenharmony_ci    LOGD("%{public}s DeleteMessageFromQueue msg is: %{public}d", mThreadName.c_str(), messageName);
243f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
244f1549183Sopenharmony_ci    if (pMyQueue == nullptr) {
245f1549183Sopenharmony_ci        LOGE("pMyQueue is null.\n");
246f1549183Sopenharmony_ci        return;
247f1549183Sopenharmony_ci    }
248f1549183Sopenharmony_ci
249f1549183Sopenharmony_ci    if (!pMyQueue->DeleteMessageFromQueue(messageName)) {
250f1549183Sopenharmony_ci        LOGE("DeleteMessageFromQueue failed.\n");
251f1549183Sopenharmony_ci        return;
252f1549183Sopenharmony_ci    }
253f1549183Sopenharmony_ci#else
254f1549183Sopenharmony_ci    if (pMyTaskQueue == nullptr) {
255f1549183Sopenharmony_ci        LOGE("%{public}s pMyQueue is null.\n", mThreadName.c_str());
256f1549183Sopenharmony_ci        return;
257f1549183Sopenharmony_ci    }
258f1549183Sopenharmony_ci    pMyTaskQueue->RemoveAsyncTask(std::to_string(messageName));
259f1549183Sopenharmony_ci#endif
260f1549183Sopenharmony_ci    return;
261f1549183Sopenharmony_ci}
262f1549183Sopenharmony_ci#ifdef OHOS_ARCH_LITE
263f1549183Sopenharmony_civoid Handler::DistributeMessage(InternalMessagePtr msg)
264f1549183Sopenharmony_ci{
265f1549183Sopenharmony_ci    if (msg == nullptr) {
266f1549183Sopenharmony_ci        return;
267f1549183Sopenharmony_ci    }
268f1549183Sopenharmony_ci    ExecuteMessage(msg);
269f1549183Sopenharmony_ci    return;
270f1549183Sopenharmony_ci}
271f1549183Sopenharmony_ci#endif
272f1549183Sopenharmony_ci}  // namespace Wifi
273f1549183Sopenharmony_ci}  // namespace OHOS