1/*
2 * Copyright (C) 2024 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 <csignal>
17#include <fcntl.h>
18#include "securec.h"
19#include <unistd.h>
20#ifndef OHOS_ARCH_LITE
21#ifdef WIFI_FFRT_ENABLE
22#include "c/ffrt_dump.h"
23#endif
24#include "xcollie/watchdog.h"
25#include "xcollie/xcollie.h"
26#include "xcollie/xcollie_define.h"
27#endif
28#include "wifi_watchdog_utils.h"
29#include "wifi_logger.h"
30#undef LOG_TAG
31
32namespace OHOS {
33namespace Wifi {
34DEFINE_WIFILOG_LABEL("WifiWatchDogUtils");
35constexpr int RESET_NOW = 1; //1s
36constexpr int TIME_OUT_WATCHDOG = 10; // 10s
37constexpr uint32_t FFRT_CALLBACK_TIME = 5 * 60 * 1000; // 5min
38constexpr uint32_t TIME_MS_TO_S = 1000;
39std::shared_ptr<WifiWatchDogUtils> WifiWatchDogUtils::GetInstance()
40{
41    static std::shared_ptr<WifiWatchDogUtils> instance = std::make_shared<WifiWatchDogUtils>();
42    return instance;
43}
44
45WifiWatchDogUtils::WifiWatchDogUtils()
46{
47    StartAllWatchDog();
48}
49
50WifiWatchDogUtils::~WifiWatchDogUtils()
51{}
52
53bool WifiWatchDogUtils::ResetProcess(bool usingHiviewDfx, const std::string &threadName, bool notResetProcess)
54{
55#ifndef OHOS_ARCH_LITE
56    ReportResetEvent(threadName);
57    if (notResetProcess) {
58        WIFI_LOGI("ResetProcess enter, but should not reset process");
59        HiviewDFX::XCollie::GetInstance().SetTimer("WifiResetTimer", TIME_OUT_WATCHDOG,
60            nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG|HiviewDFX::XCOLLIE_FLAG_RECOVERY);
61        return false;
62    }
63    if (usingHiviewDfx) {
64        WIFI_LOGI("ResetProcess through HiviewDfx");
65        //generate sysfreeze file in faultlogger, report to hiview
66        HiviewDFX::XCollie::GetInstance().SetTimer("WifiResetTimer", RESET_NOW,
67            nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG|HiviewDFX::XCOLLIE_FLAG_RECOVERY);
68    } else {
69        WIFI_LOGI("ResetProcess enter, please check crash.cpp for more information");
70        //generate crash file in faultlogger, report to hiview
71        kill(getpid(), SIGSEGV);
72    }
73#endif
74    return true;
75}
76
77int WifiWatchDogUtils::StartWatchDogForFunc(const std::string &funcName)
78{
79    #ifndef OHOS_ARCH_LITE
80    WIFI_LOGD("StartWatchDogForFunc enter for funcName:%{public}s", funcName.c_str());
81    // this will generate a watchdog file in faultlogger but will not reset process
82    return HiviewDFX::XCollie::GetInstance().SetTimer(funcName, TIME_OUT_WATCHDOG,
83        nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
84    #endif
85    return -1;
86}
87
88bool WifiWatchDogUtils::StopWatchDogForFunc(const std::string &funcName, int id)
89{
90    #ifndef OHOS_ARCH_LITE
91    WIFI_LOGD("StopWatchDogForFunc enter for funcName:%{public}s", funcName.c_str());
92    HiviewDFX::XCollie::GetInstance().CancelTimer(id);
93    #endif
94    return true;
95}
96
97void WifiWatchDogUtils::FfrtCallback(uint64_t taskId, const char *taskInfo, uint32_t delayedTaskCount)
98{
99    std::string description = "FfrtCallback: task(";
100    description += taskInfo;
101    description += ") blocked " + std::to_string(FFRT_CALLBACK_TIME / TIME_MS_TO_S) + "s";
102    WIFI_LOGI("%{public}s", description.c_str());
103#ifndef OHOS_ARCH_LITE
104    HiviewDFX::XCollie::GetInstance().SetTimer("WifiResetTimer", RESET_NOW,
105        nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG|HiviewDFX::XCOLLIE_FLAG_RECOVERY);
106#endif
107}
108
109void WifiWatchDogUtils::StartAllWatchDog()
110{
111#ifndef OHOS_ARCH_LITE
112    WIFI_LOGI("StartAllWatchDog enter");
113#ifdef WIFI_FFRT_ENABLE
114    ffrt_task_timeout_set_cb(FfrtCallback);
115    ffrt_task_timeout_set_threshold(FFRT_CALLBACK_TIME);
116#endif
117#endif
118}
119
120bool WifiWatchDogUtils::ReportResetEvent(const std::string &threadName)
121{
122    WIFI_LOGI("ReportResetEvent enter for threadName:%{public}s", threadName.c_str());
123    return true;
124}
125}  // namespace Wifi
126}  // namespace OHOSs