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 
32 namespace OHOS {
33 namespace Wifi {
34 DEFINE_WIFILOG_LABEL("WifiWatchDogUtils");
35 constexpr int RESET_NOW = 1; //1s
36 constexpr int TIME_OUT_WATCHDOG = 10; // 10s
37 constexpr uint32_t FFRT_CALLBACK_TIME = 5 * 60 * 1000; // 5min
38 constexpr uint32_t TIME_MS_TO_S = 1000;
GetInstance()39 std::shared_ptr<WifiWatchDogUtils> WifiWatchDogUtils::GetInstance()
40 {
41     static std::shared_ptr<WifiWatchDogUtils> instance = std::make_shared<WifiWatchDogUtils>();
42     return instance;
43 }
44 
WifiWatchDogUtils()45 WifiWatchDogUtils::WifiWatchDogUtils()
46 {
47     StartAllWatchDog();
48 }
49 
~WifiWatchDogUtils()50 WifiWatchDogUtils::~WifiWatchDogUtils()
51 {}
52 
ResetProcess(bool usingHiviewDfx,const std::string & threadName,bool notResetProcess)53 bool 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 
StartWatchDogForFunc(const std::string & funcName)77 int WifiWatchDogUtils::StartWatchDogForFunc(const std::string &funcName)
78 {
79     #ifndef OHOS_ARCH_LITE
80     WIFI_LOGI("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 
StopWatchDogForFunc(const std::string & funcName,int id)88 bool WifiWatchDogUtils::StopWatchDogForFunc(const std::string &funcName, int id)
89 {
90     #ifndef OHOS_ARCH_LITE
91     WIFI_LOGI("StopWatchDogForFunc enter for funcName:%{public}s", funcName.c_str());
92     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
93     #endif
94     return true;
95 }
96 
FfrtCallback(uint64_t taskId,const char * taskInfo,uint32_t delayedTaskCount)97 void 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 
StartAllWatchDog()109 void 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 
ReportResetEvent(const std::string & threadName)120 bool 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