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