• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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