1 /*
2 * Copyright (c) 2025 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 "comm_log.h"
17 #include "lnn_async_callback_utils.h"
18 #include "lnn_heartbeat_ctrl.h"
19 #include "lnn_init_monitor.h"
20 #include "lnn_log.h"
21 #include "lnn_network_manager.h"
22 #include "message_handler.h"
23 #include "securec.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_error_code.h"
26 #include "softbus_type_def.h"
27
28 typedef struct {
29 InitDepsStatus status;
30 ModuleInitCallBack callback;
31 int32_t ret;
32 SoftBusMutex lock;
33 } InitDepsInfo;
34
35 typedef struct {
36 uint32_t module;
37 uint32_t retryMax;
38 ModuleInitCallBack callback;
39 uint32_t retry;
40 uint32_t delay;
41 } InitDepsCbParam;
42
43 typedef struct {
44 uint8_t depInitEnd;
45 uint8_t deviceInfoReady;
46 } LnnInitMonitorInfo;
47
48 static InitDepsInfo g_lnnEnableModuleDeps[INIT_DEPS_MODULE_BUTT];
49 static InitDepsInfo g_lnnDeviceInfoDeps[LEDGER_INFO_BUTT];
50 static LnnInitMonitorInfo g_lnnInitMonitorInfoMgr = { 0 };
51
LnnInitModuleReturnSet(uint32_t module,int32_t ret)52 void LnnInitModuleReturnSet(uint32_t module, int32_t ret)
53 {
54 if (module < INIT_DEPS_MODULE_BUTT) {
55 SoftBusMutexLock(&g_lnnEnableModuleDeps[module].lock);
56 g_lnnEnableModuleDeps[module].ret = ret;
57 SoftBusMutexUnlock(&g_lnnEnableModuleDeps[module].lock);
58 }
59 }
60
LnnInitModuleCbRegister(uint32_t module,ModuleInitCallBack callback)61 void LnnInitModuleCbRegister(uint32_t module, ModuleInitCallBack callback)
62 {
63 if (module < INIT_DEPS_MODULE_BUTT) {
64 SoftBusMutexLock(&g_lnnEnableModuleDeps[module].lock);
65 g_lnnEnableModuleDeps[module].callback = callback;
66 SoftBusMutexUnlock(&g_lnnEnableModuleDeps[module].lock);
67 }
68 }
69
LnnInitModuleStatusGet(uint32_t module)70 static InitDepsStatus LnnInitModuleStatusGet(uint32_t module)
71 {
72 if (module >= INIT_DEPS_MODULE_BUTT) {
73 LNN_LOGE(LNN_INIT, "Module({public}%u) is invalid.", module);
74 return DEPS_STATUS_NOT_INIT;
75 }
76 SoftBusMutexLock(&g_lnnEnableModuleDeps[module].lock);
77 InitDepsStatus status = g_lnnEnableModuleDeps[module].status;
78 SoftBusMutexUnlock(&g_lnnEnableModuleDeps[module].lock);
79 return status;
80 }
81
LnnModuleMonitorRestartNetwork(void)82 void LnnModuleMonitorRestartNetwork(void)
83 {
84 RestartCoapDiscovery();
85 HbEnableDiscovery();
86 LNN_LOGI(LNN_INIT, "Module monitors and changes heartbeat (HB) conditions, and restarts CoAP discovery.");
87 }
88
LnnInitMonitorInitComplete(void * para)89 static void LnnInitMonitorInitComplete(void *para)
90 {
91 (void)para;
92 g_lnnInitMonitorInfoMgr.depInitEnd = true;
93 if (g_lnnInitMonitorInfoMgr.deviceInfoReady) {
94 LnnModuleMonitorRestartNetwork();
95 }
96 }
97
LnnInitModuleCheckEach(void)98 static void LnnInitModuleCheckEach(void)
99 {
100 for (uint32_t depModule = 0; depModule < INIT_DEPS_MODULE_BUTT; depModule++) {
101 if (LnnInitModuleStatusGet(depModule) == DEPS_STATUS_NOT_INIT) {
102 return;
103 }
104 }
105 LnnAsyncCallbackHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnInitMonitorInitComplete, NULL);
106 }
107
LnnInitModuleStatusSet(uint32_t module,InitDepsStatus status)108 void LnnInitModuleStatusSet(uint32_t module, InitDepsStatus status)
109 {
110 if (module < INIT_DEPS_MODULE_BUTT) {
111 SoftBusMutexLock(&g_lnnEnableModuleDeps[module].lock);
112 g_lnnEnableModuleDeps[module].status = status;
113 SoftBusMutexUnlock(&g_lnnEnableModuleDeps[module].lock);
114 LnnInitModuleCheckEach();
115 }
116 }
117
LnnInitDeviceInfoStatusSet(uint32_t module,InitDepsStatus status)118 void LnnInitDeviceInfoStatusSet(uint32_t module, InitDepsStatus status)
119 {
120 if (module < LEDGER_INFO_BUTT) {
121 SoftBusMutexLock(&g_lnnDeviceInfoDeps[module].lock);
122 g_lnnDeviceInfoDeps[module].status = status;
123 SoftBusMutexUnlock(&g_lnnDeviceInfoDeps[module].lock);
124 }
125 }
126
LnnInitDeviceInfoStatusGet(uint32_t module)127 static InitDepsStatus LnnInitDeviceInfoStatusGet(uint32_t module)
128 {
129 if (module >= LEDGER_INFO_BUTT) {
130 LNN_LOGE(LNN_INIT, "Device info(%u) is invalid.", module);
131 return DEPS_STATUS_NOT_INIT;
132 }
133 SoftBusMutexLock(&g_lnnDeviceInfoDeps[module].lock);
134 InitDepsStatus status = g_lnnDeviceInfoDeps[module].status;
135 SoftBusMutexUnlock(&g_lnnDeviceInfoDeps[module].lock);
136 return status;
137 }
138
LnnInitSetDeviceInfoReady(void)139 void LnnInitSetDeviceInfoReady(void)
140 {
141 g_lnnInitMonitorInfoMgr.deviceInfoReady = true;
142 if (g_lnnInitMonitorInfoMgr.depInitEnd) {
143 LnnModuleMonitorRestartNetwork();
144 }
145 }
146
LnnInitMonitorInit(void)147 void LnnInitMonitorInit(void)
148 {
149 LNN_LOGI(LNN_INIT, "Module init monitor start.");
150 for (uint32_t depModule = 0; depModule < INIT_DEPS_MODULE_BUTT; depModule++) {
151 SoftBusMutexInit(&g_lnnEnableModuleDeps[depModule].lock, NULL);
152 g_lnnEnableModuleDeps[depModule].status = DEPS_STATUS_NOT_INIT;
153 g_lnnEnableModuleDeps[depModule].callback = NULL;
154 g_lnnEnableModuleDeps[depModule].ret = SOFTBUS_OK;
155 }
156 for (uint32_t depLeger = 0; depLeger < LEDGER_INFO_BUTT; depLeger++) {
157 SoftBusMutexInit(&g_lnnDeviceInfoDeps[depLeger].lock, NULL);
158 g_lnnDeviceInfoDeps[depLeger].status = DEPS_STATUS_NOT_INIT;
159 }
160 g_lnnInitMonitorInfoMgr.depInitEnd = false;
161 g_lnnInitMonitorInfoMgr.deviceInfoReady = false;
162 /* The passive listening module is set to a state of "failed" in initialization. */
163 g_lnnEnableModuleDeps[INIT_DEPS_DATA_SHARE].status = DEPS_STATUS_FAILED;
164 g_lnnEnableModuleDeps[INIT_DEPS_PROCESS_BOOT].status = DEPS_STATUS_FAILED;
165 }
166
IsLnnInitCheckSucceed(uint32_t netType)167 bool IsLnnInitCheckSucceed(uint32_t netType)
168 {
169 if (g_lnnInitMonitorInfoMgr.depInitEnd && g_lnnInitMonitorInfoMgr.deviceInfoReady) {
170 return true;
171 }
172 if (netType == MONITOR_WIFI_NET) {
173 LNN_LOGI(LNN_INIT, "CoapDiscovery need restart, because the monitor is not ready.");
174 } else if (netType == MONITOR_BLE_NET) {
175 LNN_LOGI(LNN_INIT, "Hb condition need to change, because the monitor is not ready.");
176 }
177
178 return false;
179 }
180
LnnModuleInitRetryCallback(void * param)181 static void LnnModuleInitRetryCallback(void *param)
182 {
183 InitDepsCbParam *retryParam = (InitDepsCbParam *)param;
184 ModuleInitCallBack callback = g_lnnEnableModuleDeps[retryParam->module].callback;
185
186 LNN_LOGI(LNN_INIT, "module(%{public}u) is retrying.", retryParam->module);
187 if ((retryParam->retry >= retryParam->retryMax) || (callback == NULL)) {
188 LnnInitModuleStatusSet(retryParam->module, DEPS_STATUS_FAILED);
189 LNN_LOGE(LNN_INIT, "Module(%{public}u) retry to max times(%{public}s) ", retryParam->module,
190 callback == NULL ? ", callback is null" : "");
191 SoftBusFree(retryParam);
192 return;
193 }
194
195 int32_t ret = callback();
196 if (ret != SOFTBUS_OK) {
197 LNN_LOGE(LNN_INIT, "Module(%{public}u) hast tried %{public}u times", retryParam->module, retryParam->retry + 1);
198 LnnInitModuleReturnSet(retryParam->module, ret);
199 retryParam->retry++;
200 if (LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnModuleInitRetryCallback, param,
201 retryParam->delay) != SOFTBUS_OK) {
202 LNN_LOGE(LNN_LEDGER, "LnnAsyncCallbackDelayHelper fail");
203 LnnInitModuleStatusSet(retryParam->module, DEPS_STATUS_FAILED);
204 SoftBusFree(retryParam);
205 }
206 } else {
207 LNN_LOGI(LNN_INIT, "Module(%{public}u) retry success.", retryParam->module);
208 LnnInitModuleStatusSet(retryParam->module, DEPS_STATUS_SUCCESS);
209 SoftBusFree(retryParam);
210 }
211 }
212
LnnInitModuleNotifyWithRetryAsync(uint32_t module,ModuleInitCallBack callback,uint32_t retryMax,uint32_t delay,bool isFirstDelay)213 int32_t LnnInitModuleNotifyWithRetryAsync(uint32_t module, ModuleInitCallBack callback, uint32_t retryMax,
214 uint32_t delay, bool isFirstDelay)
215 {
216 if (callback == NULL || module >= INIT_DEPS_MODULE_BUTT) {
217 LNN_LOGE(LNN_LEDGER, "Invalid param");
218 return SOFTBUS_INVALID_PARAM;
219 }
220
221 LnnInitModuleCbRegister(module, callback);
222 LnnInitModuleStatusSet(module, DEPS_STATUS_INIT_PROGRESS);
223 InitDepsCbParam *retryParam = (InitDepsCbParam *)SoftBusCalloc(sizeof(InitDepsCbParam));
224 if (retryParam == NULL) {
225 LNN_LOGE(LNN_LEDGER, "SoftBusCalloc fail");
226 LnnInitModuleStatusSet(module, DEPS_STATUS_FAILED);
227 return SOFTBUS_MEM_ERR;
228 }
229 retryParam->module = module;
230 retryParam->retryMax = retryMax + 1;
231 retryParam->delay = delay;
232 retryParam->retry = 0;
233 int32_t ret = LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnModuleInitRetryCallback, retryParam,
234 isFirstDelay ? delay : 0);
235 if (ret != SOFTBUS_OK) {
236 LNN_LOGE(LNN_LEDGER, "LnnAsyncCallbackDelayHelper fail");
237 LnnInitModuleStatusSet(module, DEPS_STATUS_FAILED);
238 SoftBusFree(retryParam);
239 return ret;
240 }
241 return SOFTBUS_OK;
242 }
243
LnnInitModuleNotifyWithRetrySync(uint32_t module,ModuleInitCallBack callback,uint32_t retryMax,uint32_t delay)244 int32_t LnnInitModuleNotifyWithRetrySync(uint32_t module, ModuleInitCallBack callback, uint32_t retryMax,
245 uint32_t delay)
246 {
247 if (callback == NULL || module >= INIT_DEPS_MODULE_BUTT) {
248 LNN_LOGE(LNN_LEDGER, "Invalid param");
249 return SOFTBUS_INVALID_PARAM;
250 }
251
252 int32_t ret = callback();
253 if (ret != SOFTBUS_OK) {
254 LnnInitModuleReturnSet(module, ret);
255 LnnInitModuleStatusSet(module, DEPS_STATUS_INIT_PROGRESS);
256 LnnInitModuleCbRegister(module, callback);
257 InitDepsCbParam *retryParam = (InitDepsCbParam *)SoftBusCalloc(sizeof(InitDepsCbParam));
258 if (retryParam == NULL) {
259 LNN_LOGE(LNN_LEDGER, "SoftBusCalloc fail");
260 LnnInitModuleStatusSet(module, DEPS_STATUS_FAILED);
261 return SOFTBUS_MEM_ERR;
262 }
263 retryParam->module = module;
264 retryParam->retryMax = retryMax;
265 retryParam->delay = delay;
266 retryParam->retry = 0;
267 ret = LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnModuleInitRetryCallback, retryParam, delay);
268 if (ret != SOFTBUS_OK) {
269 LNN_LOGE(LNN_LEDGER, "LnnAsyncCallbackDelayHelper fail");
270 LnnInitModuleStatusSet(module, DEPS_STATUS_FAILED);
271 SoftBusFree(retryParam);
272 return ret;
273 }
274 return SOFTBUS_OK;
275 }
276 LnnInitModuleStatusSet(module, DEPS_STATUS_SUCCESS);
277 return SOFTBUS_OK;
278 }
279
LnnInitModuleFailedLog(void * param)280 static void LnnInitModuleFailedLog(void *param)
281 {
282 (void)param;
283 char failedModules[DEP_INFO_LEN] = { 0 };
284 size_t offset = 0;
285 int32_t ret;
286 bool reCheck = false;
287
288 if (!g_lnnInitMonitorInfoMgr.depInitEnd) {
289 LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnInitModuleFailedLog, NULL, DELAY_FIVE_MIN_LEN);
290 return;
291 }
292 for (uint32_t depModule = 0; depModule < INIT_DEPS_MODULE_BUTT; depModule++) {
293 if (LnnInitModuleStatusGet(depModule) == DEPS_STATUS_FAILED) {
294 ret = snprintf_s(failedModules + offset, DEP_INFO_LEN - offset, DEP_INFO_LEN - offset - 1,
295 "Module(%u), ret(%d); ", depModule, g_lnnEnableModuleDeps[depModule].ret);
296 if (ret < 0) {
297 LNN_LOGE(LNN_LEDGER, "snprintf_s failed");
298 break;
299 }
300 offset += (size_t)ret;
301 reCheck = true;
302 } else if (LnnInitModuleStatusGet(depModule) == DEPS_STATUS_INIT_PROGRESS) {
303 reCheck = true;
304 }
305 }
306 if (failedModules[0] != '\0') {
307 LNN_LOGE(LNN_INIT, "Module init failed: %{public}s", failedModules);
308 }
309 if (reCheck) {
310 LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnInitModuleFailedLog, NULL, DELAY_FIVE_MIN_LEN);
311 }
312 }
313
LnnInitDeviceInfoFailLog(void * param)314 static void LnnInitDeviceInfoFailLog(void *param)
315 {
316 (void)param;
317 bool reCheck = false;
318 char depLegerInfo[DEP_INFO_LEN] = { 0 };
319 size_t offset = 0;
320 int32_t ret;
321
322 for (uint32_t depLeger = 0; depLeger < LEDGER_INFO_BUTT; depLeger++) {
323 InitDepsStatus status = LnnInitDeviceInfoStatusGet(depLeger);
324 if (status == DEPS_STATUS_FAILED) {
325 ret = snprintf_s(depLegerInfo + offset, DEP_INFO_LEN - offset, DEP_INFO_LEN - offset - 1, "Leger(%u); ",
326 depLeger);
327 if (ret < 0) {
328 LNN_LOGE(LNN_LEDGER, "snprintf_s failed");
329 break;
330 }
331 offset += (size_t)ret;
332 reCheck = true;
333 } else if (status == DEPS_STATUS_NOT_INIT) {
334 reCheck = true;
335 }
336 }
337 if (depLegerInfo[0] != '\0') {
338 LNN_LOGE(LNN_INIT, "Device init failed: %{public}s", depLegerInfo);
339 }
340 if (reCheck) {
341 LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnInitDeviceInfoFailLog, NULL, DELAY_FIVE_MIN_LEN);
342 }
343 }
344
LnnModuleInitMonitorCheckStart(void)345 void LnnModuleInitMonitorCheckStart(void)
346 {
347 LnnInitDeviceInfoFailLog(NULL);
348 LnnInitModuleFailedLog(NULL);
349 }
350