1 /*
2  * Copyright (c) 2021 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 "lnn_heartbeat_strategy.h"
17 
18 #include <securec.h>
19 
20 #include "anonymizer.h"
21 #include "common_list.h"
22 #include "lnn_heartbeat_ctrl.h"
23 #include "lnn_heartbeat_fsm.h"
24 #include "lnn_heartbeat_medium_mgr.h"
25 #include "lnn_heartbeat_utils.h"
26 #include "lnn_log.h"
27 
28 #include "bus_center_manager.h"
29 #include "lnn_distributed_net_ledger.h"
30 #include "lnn_feature_capability.h"
31 #include "softbus_adapter_mem.h"
32 #include "softbus_adapter_thread.h"
33 #include "softbus_adapter_timer.h"
34 #include "softbus_def.h"
35 #include "softbus_errcode.h"
36 #include "softbus_utils.h"
37 
38 #define HB_GEARMODE_MAX_SET_CNT        100
39 #define HB_GEARMODE_LIFETIME_PERMANENT (-1)
40 #define HB_DEFAULT_CALLER_ID           "HEARTBEAT_DEFAULT_CALLER_ID"
41 #define HB_SUPER_DEVICE_CALLER_ID      "hmos.collaborationfwk.deviceDetect"
42 
43 typedef struct {
44     const char *callerId;
45     ListNode node;
46     GearMode mode;
47     int64_t lifetimeStamp; // unit is milliseconds
48 } GearModeStorageInfo;
49 
50 typedef struct {
51     LnnHeartbeatType type;
52     LnnHeartbeatMediumParam *param;
53     int32_t gearModeCnt;
54     ListNode gearModeList;
55     bool isEnable;
56 } LnnHeartbeatParamManager;
57 
58 static SoftBusMutex g_hbStrategyMutex;
59 static LnnHeartbeatFsm *g_hbFsm = NULL;
60 static LnnHeartbeatParamManager *g_hbParamMgr[HB_MAX_TYPE_COUNT] = { 0 };
61 
62 static int32_t SingleSendStrategy(LnnHeartbeatFsm *hbFsm, void *obj);
63 static int32_t FixedPeriodSendStrategy(LnnHeartbeatFsm *hbFsm, void *obj);
64 static int32_t AdjustablePeriodSendStrategy(LnnHeartbeatFsm *hbFsm, void *obj);
65 
66 static LnnHeartbeatStrategyManager g_hbStrategyMgr[] = {
67     [STRATEGY_HB_SEND_SINGLE] = {
68         .supportType = HEARTBEAT_TYPE_UDP | HEARTBEAT_TYPE_BLE_V0 | HEARTBEAT_TYPE_BLE_V1 | HEARTBEAT_TYPE_BLE_V3 |
69             HEARTBEAT_TYPE_TCP_FLUSH,
70         .onProcess = SingleSendStrategy,
71     },
72     [STRATEGY_HB_SEND_FIXED_PERIOD] = {
73         .supportType = HEARTBEAT_TYPE_UDP | HEARTBEAT_TYPE_BLE_V1,
74         .onProcess = FixedPeriodSendStrategy,
75     },
76     [STRATEGY_HB_SEND_ADJUSTABLE_PERIOD] = {
77         .supportType = HEARTBEAT_TYPE_BLE_V0 | HEARTBEAT_TYPE_BLE_V3,
78         .onProcess = AdjustablePeriodSendStrategy,
79     },
80     [STRATEGY_HB_RECV_SINGLE] = {
81         .supportType = HEARTBEAT_TYPE_UDP | HEARTBEAT_TYPE_TCP_FLUSH,
82         .onProcess = NULL,
83     },
84     [STRATEGY_HB_RECV_REMOVE_REPEAT] = {
85         .supportType = HEARTBEAT_TYPE_BLE_V0 | HEARTBEAT_TYPE_BLE_V1,
86         .onProcess = NULL,
87     },
88 };
89 
DumpGearModeSettingList(int64_t nowTime,const ListNode * gearModeList)90 static void DumpGearModeSettingList(int64_t nowTime, const ListNode *gearModeList)
91 {
92 #define HB_DUMP_GEAR_MODE_LIST_MAX_NUM 10
93     int32_t dumpCount = 0;
94     GearModeStorageInfo *info = NULL;
95 
96     LIST_FOR_EACH_ENTRY(info, gearModeList, GearModeStorageInfo, node) {
97         dumpCount++;
98         if (dumpCount > HB_DUMP_GEAR_MODE_LIST_MAX_NUM) {
99             break;
100         }
101         LNN_LOGD(LNN_HEART_BEAT,
102             "DumpGearModeSettingList count=%{public}d, callerId=%{public}s, cycle=%{public}d, "
103             "duration=%{public}d, wakeupFlag=%{public}d, lifeTimestamp=%{public}" PRId64 ", needClean=%{public}s",
104             dumpCount, info->callerId, info->mode.cycle, info->mode.duration, info->mode.wakeupFlag,
105              info->lifetimeStamp,
106             info->lifetimeStamp != HB_GEARMODE_LIFETIME_PERMANENT && info->lifetimeStamp <= nowTime ? "true" : "false");
107     }
108 }
109 
GetGearModeFromSettingList(GearMode * mode,char * callerId,const ListNode * gearModeList,int32_t * gearModeCnt)110 static int32_t GetGearModeFromSettingList(GearMode *mode, char *callerId, const ListNode *gearModeList,
111     int32_t *gearModeCnt)
112 {
113     int64_t nowTime;
114     const char *tmpCallerId = NULL;
115     SoftBusSysTime times;
116     GearModeStorageInfo *info = NULL;
117     GearModeStorageInfo *nextInfo = NULL;
118 
119     SoftBusGetTime(&times);
120     nowTime = times.sec * HB_TIME_FACTOR + times.usec / HB_TIME_FACTOR;
121     DumpGearModeSettingList(nowTime, gearModeList);
122     LIST_FOR_EACH_ENTRY_SAFE(info, nextInfo, gearModeList, GearModeStorageInfo, node) {
123         if (*gearModeCnt == 0) {
124             LNN_LOGD(LNN_HEART_BEAT, "HB get Gearmode from setting list is empty");
125             return SOFTBUS_NETWORK_HEARTBEAT_EMPTY_LIST;
126         }
127         if (info->lifetimeStamp < nowTime && info->lifetimeStamp != HB_GEARMODE_LIFETIME_PERMANENT) {
128             ListDelete(&info->node);
129             SoftBusFree((void *)info->callerId);
130             SoftBusFree(info);
131             (*gearModeCnt)--;
132             continue;
133         }
134         /* Priority to send high-frequency heartbeat */
135         if (mode->cycle != 0 && mode->cycle < info->mode.cycle) {
136             continue;
137         }
138         if (mode->cycle == info->mode.cycle && !info->mode.wakeupFlag) {
139             continue;
140         }
141         if (memcpy_s(mode, sizeof(GearMode), &info->mode, sizeof(GearMode)) != EOK) {
142             LNN_LOGE(LNN_HEART_BEAT, "HB get Gearmode from setting list memcpy_s err");
143             return SOFTBUS_MEM_ERR;
144         }
145         tmpCallerId = info->callerId;
146     }
147     if (tmpCallerId != NULL) {
148         if (callerId != NULL && strcpy_s(callerId, PKG_NAME_SIZE_MAX, tmpCallerId) != EOK) {
149             LNN_LOGE(LNN_HEART_BEAT, "strcpy callerId fail");
150         }
151         LNN_LOGD(LNN_HEART_BEAT,
152             "HB get Gearmode from list, id=%{public}s, cycle=%{public}d, duration=%{public}d, wakeupFlag=%{public}d",
153             tmpCallerId, mode->cycle, mode->duration, mode->wakeupFlag);
154     }
155     return SOFTBUS_OK;
156 }
157 
GetParamMgrByTypeLocked(LnnHeartbeatType type)158 static LnnHeartbeatParamManager *GetParamMgrByTypeLocked(LnnHeartbeatType type)
159 {
160     int32_t id;
161 
162     id = LnnConvertHbTypeToId(type);
163     if (id == HB_INVALID_TYPE_ID) {
164         LNN_LOGE(LNN_HEART_BEAT, "HB get param mgr convert type fail");
165         return NULL;
166     }
167     return g_hbParamMgr[id];
168 }
169 
LnnGetGearModeBySpecificType(GearMode * mode,char * callerId,LnnHeartbeatType type)170 int32_t LnnGetGearModeBySpecificType(GearMode *mode, char *callerId, LnnHeartbeatType type)
171 {
172     LnnHeartbeatParamManager *paramMgr = NULL;
173 
174     if (mode == NULL) {
175         LNN_LOGE(LNN_HEART_BEAT, "HB get Gearmode invalid param");
176         return SOFTBUS_INVALID_PARAM;
177     }
178     if (memset_s(mode, sizeof(GearMode), 0, sizeof(GearMode) != EOK)) {
179         LNN_LOGE(LNN_HEART_BEAT, "HB get Gearmode memset_s err");
180         return SOFTBUS_MEM_ERR;
181     }
182     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
183         LNN_LOGE(LNN_HEART_BEAT, "HB get Gearmode lock mutex fail");
184         return SOFTBUS_LOCK_ERR;
185     }
186     paramMgr = GetParamMgrByTypeLocked(type);
187     if (paramMgr == NULL) {
188         LNN_LOGE(LNN_HEART_BEAT, "HB get Gearmode get NULL paramMgr");
189         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
190         return SOFTBUS_ERR;
191     }
192     if (IsListEmpty(&paramMgr->gearModeList)) {
193         LNN_LOGD(LNN_HEART_BEAT, "HB get Gearmode from setting list is empty");
194         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
195         return SOFTBUS_NETWORK_HEARTBEAT_EMPTY_LIST;
196     }
197     int32_t ret = GetGearModeFromSettingList(mode, callerId, &paramMgr->gearModeList, &paramMgr->gearModeCnt);
198     if (ret != SOFTBUS_OK && ret != SOFTBUS_NETWORK_HEARTBEAT_EMPTY_LIST) {
199         LNN_LOGE(LNN_HEART_BEAT, "HB get Gearmode from setting list err");
200     }
201     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
202     return ret;
203 }
204 
FirstSetGearModeByCallerId(const char * callerId,int64_t nowTime,ListNode * list,const GearMode * mode)205 static int32_t FirstSetGearModeByCallerId(const char *callerId, int64_t nowTime, ListNode *list, const GearMode *mode)
206 {
207     GearModeStorageInfo *info = NULL;
208 
209     info = (GearModeStorageInfo *)SoftBusCalloc(sizeof(GearModeStorageInfo));
210     if (info == NULL) {
211         LNN_LOGE(LNN_HEART_BEAT, "HB first set Gearmode calloc storage info err");
212         return SOFTBUS_MALLOC_ERR;
213     }
214     ListInit(&info->node);
215     if (memcpy_s(&info->mode, sizeof(GearMode), mode, sizeof(GearMode)) != EOK) {
216         LNN_LOGE(LNN_HEART_BEAT, "HB first set Gearmode memcpy_s err");
217         SoftBusFree(info);
218         return SOFTBUS_MEM_ERR;
219     }
220     info->callerId = (char *)SoftBusCalloc(strlen(callerId) + 1);
221     if (info->callerId == NULL) {
222         LNN_LOGE(LNN_HEART_BEAT, "HB first set Gearmode malloc callerId err");
223         SoftBusFree(info);
224         return SOFTBUS_MALLOC_ERR;
225     }
226     if (strcpy_s((char *)info->callerId, strlen(callerId) + 1, callerId) != EOK) {
227         LNN_LOGE(LNN_HEART_BEAT, "HB first set Gearmode strcpy_s callerId err");
228         SoftBusFree((char *)info->callerId);
229         SoftBusFree(info);
230         return SOFTBUS_ERR;
231     }
232     if (strcmp(callerId, HB_DEFAULT_CALLER_ID) == 0) {
233         info->lifetimeStamp = HB_GEARMODE_LIFETIME_PERMANENT;
234     } else {
235         info->lifetimeStamp = nowTime + mode->duration * HB_TIME_FACTOR;
236     }
237     ListAdd(list, &info->node);
238     return SOFTBUS_OK;
239 }
240 
LnnSetGearModeBySpecificType(const char * callerId,const GearMode * mode,LnnHeartbeatType type)241 int32_t LnnSetGearModeBySpecificType(const char *callerId, const GearMode *mode, LnnHeartbeatType type)
242 {
243     int64_t nowTime;
244     SoftBusSysTime times;
245     GearModeStorageInfo *info = NULL;
246     LnnHeartbeatParamManager *paramMgr = NULL;
247 
248     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
249         LNN_LOGE(LNN_HEART_BEAT, "HB set Gearmode lock mutex fail");
250         return SOFTBUS_LOCK_ERR;
251     }
252     paramMgr = GetParamMgrByTypeLocked(type);
253     if (paramMgr == NULL) {
254         LNN_LOGE(LNN_HEART_BEAT, "HB set Gearmode get NULL paramMgr");
255         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
256         return SOFTBUS_ERR;
257     }
258     if (paramMgr->gearModeCnt > HB_GEARMODE_MAX_SET_CNT) {
259         LNN_LOGW(LNN_HEART_BEAT, "HB set Gearmode cnt exceed MAX_CNT=%{public}d", HB_GEARMODE_MAX_SET_CNT);
260         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
261         return SOFTBUS_ERR;
262     }
263     SoftBusGetTime(&times);
264     nowTime = times.sec * HB_TIME_FACTOR + times.usec / HB_TIME_FACTOR;
265     LIST_FOR_EACH_ENTRY(info, &paramMgr->gearModeList, GearModeStorageInfo, node) {
266         if (strcmp(info->callerId, callerId) != 0) {
267             continue;
268         }
269         if (memcpy_s(&info->mode, sizeof(GearMode), mode, sizeof(GearMode)) != EOK) {
270             LNN_LOGE(LNN_HEART_BEAT, "HB set Gearmode memcpy_s err");
271             (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
272             return SOFTBUS_MEM_ERR;
273         }
274         info->lifetimeStamp = nowTime + mode->duration * HB_TIME_FACTOR;
275         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
276         return SOFTBUS_OK;
277     }
278     if (FirstSetGearModeByCallerId(callerId, nowTime, &paramMgr->gearModeList, mode) != SOFTBUS_OK) {
279         LNN_LOGE(LNN_HEART_BEAT, "HB set Gearmode by callerId err");
280         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
281         return SOFTBUS_ERR;
282     }
283     paramMgr->gearModeCnt++;
284     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
285     return SOFTBUS_OK;
286 }
287 
GetStrategyTypeByPolicy(int32_t policy)288 LnnHeartbeatStrategyType GetStrategyTypeByPolicy(int32_t policy)
289 {
290     if (policy == ONCE_STRATEGY) {
291         return STRATEGY_HB_SEND_SINGLE;
292     }
293     return STRATEGY_HB_SEND_ADJUSTABLE_PERIOD;
294 }
295 
VisitClearNoneSplitHbType(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)296 static bool VisitClearNoneSplitHbType(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
297 {
298     (void)data;
299 
300     if (eachType != HEARTBEAT_TYPE_BLE_V0 && eachType != HEARTBEAT_TYPE_BLE_V1) {
301         /* only the ble heartbeat needs to be split and sent */
302         *typeSet &= ~eachType;
303     }
304     return true;
305 }
306 
SendEachOnce(LnnHeartbeatFsm * hbFsm,LnnProcessSendOnceMsgPara * msgPara,LnnHeartbeatSendEndData * endData,uint32_t * delayTime,uint32_t sendLen)307 static void SendEachOnce(LnnHeartbeatFsm *hbFsm, LnnProcessSendOnceMsgPara *msgPara, LnnHeartbeatSendEndData *endData,
308     uint32_t *delayTime, uint32_t sendLen)
309 {
310     if (LnnPostSendBeginMsgToHbFsm(hbFsm, endData->hbType, endData->wakeupFlag, msgPara, *delayTime) != SOFTBUS_OK) {
311         LNN_LOGE(LNN_HEART_BEAT, "HB send once first begin fail, hbType=%{public}d", endData->hbType);
312         return;
313     }
314     *delayTime += sendLen;
315     if (LnnPostSendEndMsgToHbFsm(hbFsm, endData, *delayTime) != SOFTBUS_OK) {
316         LNN_LOGE(LNN_HEART_BEAT, "HB send once last end fail, hbType=%{public}d", endData->hbType);
317     }
318 }
319 
RelayHeartbeatV0SplitOld(LnnHeartbeatFsm * hbFsm,LnnProcessSendOnceMsgPara * msgPara,bool wakeupFlag,LnnHeartbeatType registedHbType,bool isRelayV0)320 static int32_t RelayHeartbeatV0SplitOld(LnnHeartbeatFsm *hbFsm, LnnProcessSendOnceMsgPara *msgPara,
321     bool wakeupFlag, LnnHeartbeatType registedHbType, bool isRelayV0)
322 {
323     msgPara->isSyncData = false;
324     msgPara->hasScanRsp = true;
325     msgPara->isNeedRestart = false;
326     msgPara->isFirstBegin = false;
327     if (LnnPostSendBeginMsgToHbFsm(hbFsm, registedHbType, wakeupFlag, msgPara, 0) != SOFTBUS_OK) {
328         LNN_LOGE(LNN_HEART_BEAT, "HB send once first begin fail, hbType=%{public}d", registedHbType);
329         return SOFTBUS_ERR;
330     }
331     uint32_t sendCnt = isRelayV0 ? 1 : HB_SEND_SEPARATELY_CNT;
332     LnnHeartbeatType splitHbType = registedHbType;
333     (void)LnnVisitHbTypeSet(VisitClearNoneSplitHbType, &splitHbType, NULL);
334     LnnHeartbeatSendEndData endData = {
335         .hbType = splitHbType,
336         .wakeupFlag = wakeupFlag,
337         .isRelay = msgPara->isRelay,
338         .isLastEnd = false,
339     };
340     for (uint32_t i = 1; i < sendCnt; ++i) {
341         if (splitHbType < HEARTBEAT_TYPE_MIN) {
342             break;
343         }
344         if (i == sendCnt - 1) {
345             if (LnnPostSendEndMsgToHbFsm(hbFsm, &endData, i * HB_SEND_EACH_SEPARATELY_LEN) != SOFTBUS_OK) {
346                 LNN_LOGE(LNN_HEART_BEAT, "HB send once end fail, hbType=%{public}d", splitHbType);
347                 return SOFTBUS_ERR;
348             }
349             msgPara->isSyncData = true;
350             msgPara->isNeedRestart = true;
351             if (LnnPostSendBeginMsgToHbFsm(hbFsm, splitHbType, wakeupFlag, msgPara, i * HB_SEND_EACH_SEPARATELY_LEN) !=
352                 SOFTBUS_OK) {
353                 msgPara->isSyncData = false;
354                 LNN_LOGE(LNN_HEART_BEAT, "HB send once begin fail, hbType=%{public}d", splitHbType);
355                 return SOFTBUS_ERR;
356             }
357         }
358     }
359     endData.hbType = registedHbType;
360     endData.isLastEnd = true;
361     if (LnnPostSendEndMsgToHbFsm(hbFsm, &endData, isRelayV0 ? HB_SEND_EACH_SEPARATELY_LEN
362         : HB_SEND_ONCE_LEN) != SOFTBUS_OK) {
363         msgPara->isSyncData = false;
364         LNN_LOGE(LNN_HEART_BEAT, "HB send once last end fail, hbType=%{public}d", registedHbType);
365         return SOFTBUS_ERR;
366     }
367     msgPara->isSyncData = false;
368     return SOFTBUS_OK;
369 }
370 
RelayHeartbeatV0Split(LnnHeartbeatFsm * hbFsm,LnnProcessSendOnceMsgPara * msgPara,bool wakeupFlag,LnnHeartbeatType registedHbType)371 static int32_t RelayHeartbeatV0Split(
372     LnnHeartbeatFsm *hbFsm, LnnProcessSendOnceMsgPara *msgPara, bool wakeupFlag, LnnHeartbeatType registedHbType)
373 {
374     msgPara->isSyncData = false;
375     msgPara->hasScanRsp = true;
376     msgPara->isNeedRestart = true;
377     msgPara->isFirstBegin = false;
378     uint32_t delayTime = GenerateRandomNumForHb(HB_ADV_RANDOM_TIME_50, HB_ADV_RANDOM_TIME_500);
379     if (LnnPostSendBeginMsgToHbFsm(hbFsm, registedHbType, wakeupFlag, msgPara, delayTime) != SOFTBUS_OK) {
380         LNN_LOGE(LNN_HEART_BEAT, "HB send once first begin fail, hbType=%{public}d", registedHbType);
381         return SOFTBUS_ERR;
382     }
383     LnnHeartbeatType splitHbType = registedHbType;
384     (void)LnnVisitHbTypeSet(VisitClearNoneSplitHbType, &splitHbType, NULL);
385     LnnHeartbeatSendEndData endData = {
386         .hbType = splitHbType,
387         .wakeupFlag = wakeupFlag,
388         .isRelay = msgPara->isRelay,
389         .isLastEnd = true,
390     };
391     delayTime += HB_SEND_RELAY_LEN + HB_TIME_FACTOR_TWO_HUNDRED_MS;
392     if (LnnPostSendEndMsgToHbFsm(hbFsm, &endData, delayTime) != SOFTBUS_OK) {
393         LNN_LOGE(LNN_HEART_BEAT, "HB send once last end fail, hbType=%{public}d", registedHbType);
394         return SOFTBUS_ERR;
395     }
396     delayTime += GenerateRandomNumForHb(HB_ADV_RANDOM_TIME_300, HB_ADV_RANDOM_TIME_600);
397     msgPara->hasScanRsp = false;
398     msgPara->isNeedRestart = false;
399     if (LnnPostSendBeginMsgToHbFsm(hbFsm, registedHbType, wakeupFlag, msgPara, delayTime) != SOFTBUS_OK) {
400         LNN_LOGE(LNN_HEART_BEAT, "HB send once first begin fail, hbType=%{public}d", registedHbType);
401         return SOFTBUS_ERR;
402     }
403     delayTime += HB_SEND_RELAY_LEN + HB_TIME_FACTOR_TWO_HUNDRED_MS;
404     msgPara->hasScanRsp = true;
405     if (LnnPostSendBeginMsgToHbFsm(hbFsm, registedHbType, wakeupFlag, msgPara, delayTime) != SOFTBUS_OK) {
406         LNN_LOGE(LNN_HEART_BEAT, "HB send once first begin fail, hbType=%{public}d", registedHbType);
407         return SOFTBUS_ERR;
408     }
409     delayTime += HB_SEND_RELAY_LEN_ONCE;
410     delayTime += GenerateRandomNumForHb(HB_ADV_RANDOM_TIME_500, HB_ADV_RANDOM_TIME_1000);
411     msgPara->hasScanRsp = false;
412     endData.hbType = registedHbType;
413     SendEachOnce(hbFsm, msgPara, &endData, &delayTime, HB_SEND_RELAY_LEN_ONCE);
414     return SOFTBUS_OK;
415 }
416 
RelayHeartbeatV1Split(LnnHeartbeatFsm * hbFsm,LnnProcessSendOnceMsgPara * msgPara,bool wakeupFlag,LnnHeartbeatType registedHbType)417 static int32_t RelayHeartbeatV1Split(
418     LnnHeartbeatFsm *hbFsm, LnnProcessSendOnceMsgPara *msgPara, bool wakeupFlag, LnnHeartbeatType registedHbType)
419 {
420     msgPara->isFirstBegin = true;
421     msgPara->isNeedRestart = true;
422     msgPara->hasScanRsp = true;
423     if (LnnPostSendBeginMsgToHbFsm(hbFsm, registedHbType, wakeupFlag, msgPara, 0) != SOFTBUS_OK) {
424         LNN_LOGE(LNN_HEART_BEAT, "HB send once first begin fail, hbType=%{public}d", registedHbType);
425         return SOFTBUS_ERR;
426     }
427     uint32_t sendCnt = HB_SEND_SEPARATELY_CNT;
428     LnnHeartbeatType splitHbType = registedHbType;
429     (void)LnnVisitHbTypeSet(VisitClearNoneSplitHbType, &splitHbType, NULL);
430     LnnHeartbeatSendEndData endData = {
431         .hbType = splitHbType,
432         .wakeupFlag = wakeupFlag,
433         .isRelay = msgPara->isRelay,
434         .isLastEnd = false,
435     };
436     for (uint32_t i = 1; i < sendCnt; ++i) {
437         if (splitHbType < HEARTBEAT_TYPE_MIN) {
438             break;
439         }
440         if (i == sendCnt - 1) {
441             if (LnnPostSendEndMsgToHbFsm(hbFsm, &endData, i * HB_SEND_EACH_SEPARATELY_LEN) != SOFTBUS_OK) {
442                 LNN_LOGE(LNN_HEART_BEAT, "HB send once end fail, hbType=%{public}d", splitHbType);
443                 return SOFTBUS_ERR;
444             }
445             msgPara->isSyncData = true;
446             msgPara->isNeedRestart = false;
447             if (LnnPostSendBeginMsgToHbFsm(hbFsm, splitHbType, wakeupFlag, msgPara, i * HB_SEND_EACH_SEPARATELY_LEN) !=
448                 SOFTBUS_OK) {
449                 msgPara->isSyncData = false;
450                 LNN_LOGE(LNN_HEART_BEAT, "HB send once begin fail, hbType=%{public}d", splitHbType);
451                 return SOFTBUS_ERR;
452             }
453         }
454     }
455     endData.hbType = registedHbType;
456     endData.isLastEnd = true;
457     if (LnnPostSendEndMsgToHbFsm(hbFsm, &endData, HB_SEND_ONCE_LEN) != SOFTBUS_OK) {
458         msgPara->isSyncData = false;
459         LNN_LOGE(LNN_HEART_BEAT, "HB send once last end fail, hbType=%{public}d", registedHbType);
460         return SOFTBUS_ERR;
461     }
462     msgPara->isSyncData = false;
463     return SOFTBUS_OK;
464 }
465 
OtherHeartbeatSplit(LnnHeartbeatFsm * hbFsm,LnnProcessSendOnceMsgPara * msgPara,bool wakeupFlag,LnnHeartbeatType registedHbType)466 static int32_t OtherHeartbeatSplit(
467     LnnHeartbeatFsm *hbFsm, LnnProcessSendOnceMsgPara *msgPara, bool wakeupFlag, LnnHeartbeatType registedHbType)
468 {
469     uint32_t totalDelay = 0;
470     msgPara->isNeedRestart = true;
471     msgPara->hasScanRsp = true;
472     msgPara->isSyncData = false;
473     msgPara->isFirstBegin = true;
474     msgPara->isFast = (!LnnIsMultiDeviceOnline());
475     if (LnnPostSendBeginMsgToHbFsm(hbFsm, registedHbType, wakeupFlag, msgPara, totalDelay) != SOFTBUS_OK) {
476         LNN_LOGE(LNN_HEART_BEAT, "HB send once first begin fail, hbType=%{public}d", registedHbType);
477         return SOFTBUS_ERR;
478     }
479     LnnHeartbeatType splitHbType = registedHbType;
480     (void)LnnVisitHbTypeSet(VisitClearNoneSplitHbType, &splitHbType, NULL);
481     LnnHeartbeatSendEndData endData = {
482         .hbType = splitHbType,
483         .wakeupFlag = wakeupFlag,
484         .isRelay = msgPara->isRelay,
485         .isLastEnd = true,
486     };
487     totalDelay += HB_SEND_EACH_SEPARATELY_LEN + HB_SEND_RELAY_LEN;
488     if (LnnPostSendEndMsgToHbFsm(hbFsm, &endData, totalDelay) != SOFTBUS_OK) {
489         LNN_LOGE(LNN_HEART_BEAT, "HB send once end fail, hbType=%{public}d", splitHbType);
490         return SOFTBUS_ERR;
491     }
492     totalDelay += GenerateRandomNumForHb(HB_ADV_RANDOM_TIME_200, HB_ADV_RANDOM_TIME_500);
493     msgPara->isNeedRestart = false;
494     msgPara->hasScanRsp = false;
495     msgPara->isFirstBegin = false;
496     SendEachOnce(hbFsm, msgPara, &endData, &totalDelay, HB_SEND_EACH_SEPARATELY_LEN);
497     totalDelay += GenerateRandomNumForHb(HB_ADV_RANDOM_TIME_300, HB_ADV_RANDOM_TIME_600);
498     msgPara->isFast = false;
499     msgPara->hasScanRsp = true;
500     SendEachOnce(hbFsm, msgPara, &endData, &totalDelay, HB_SEND_EACH_SEPARATELY_LEN);
501     msgPara->hasScanRsp = false;
502     totalDelay += GenerateRandomNumForHb(HB_ADV_RANDOM_TIME_200, HB_ADV_RANDOM_TIME_500);
503     SendEachOnce(hbFsm, msgPara, &endData, &totalDelay, HB_SEND_RELAY_LEN);
504     msgPara->hasScanRsp = true;
505     msgPara->isSyncData = true;
506     totalDelay += GenerateRandomNumForHb(HB_ADV_RANDOM_TIME_200, HB_ADV_RANDOM_TIME_500);
507     SendEachOnce(hbFsm, msgPara, &endData, &totalDelay, HB_SEND_EACH_SEPARATELY_LEN);
508     msgPara->isNeedRestart = true;
509     msgPara->isSyncData = false;
510     return SOFTBUS_OK;
511 }
512 
SendEachSeparately(LnnHeartbeatFsm * hbFsm,LnnProcessSendOnceMsgPara * msgPara,const GearMode * mode,LnnHeartbeatType registedHbType,bool isRelayV0)513 static int32_t SendEachSeparately(LnnHeartbeatFsm *hbFsm, LnnProcessSendOnceMsgPara *msgPara, const GearMode *mode,
514     LnnHeartbeatType registedHbType, bool isRelayV0)
515 {
516     LNN_LOGI(LNN_HEART_BEAT, "hbType=%{public}d, isRelay=%{public}d", registedHbType, msgPara->isRelay);
517     bool wakeupFlag = mode != NULL ? mode->wakeupFlag : false;
518 
519     if (isRelayV0) {
520         if (LnnIsMultiDeviceOnline()) {
521             return RelayHeartbeatV0Split(hbFsm, msgPara, wakeupFlag, registedHbType);
522         } else {
523             return RelayHeartbeatV0SplitOld(hbFsm, msgPara, wakeupFlag, registedHbType, isRelayV0);
524         }
525     }
526     if (registedHbType == HEARTBEAT_TYPE_BLE_V1) {
527         return RelayHeartbeatV1Split(hbFsm, msgPara, wakeupFlag, registedHbType);
528     }
529     if (strlen(msgPara->callerId) != 0 && strcmp(msgPara->callerId, HB_SUPER_DEVICE_CALLER_ID) == 0) {
530         return RelayHeartbeatV1Split(hbFsm, msgPara, wakeupFlag, registedHbType);
531     }
532     return OtherHeartbeatSplit(hbFsm, msgPara, wakeupFlag, registedHbType);
533 }
534 
VisitClearUnRegistedHbType(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)535 static bool VisitClearUnRegistedHbType(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
536 {
537     (void)data;
538 
539     if (!LnnIsHeartbeatEnable(eachType)) {
540         LNN_LOGD(LNN_HEART_BEAT, "HB heartbeat is disabled, hbType=%{public}d", eachType);
541         *typeSet &= ~eachType;
542     }
543     return true;
544 }
545 
ProcessSendOnceStrategy(LnnHeartbeatFsm * hbFsm,LnnProcessSendOnceMsgPara * msgPara,const GearMode * mode)546 static int32_t ProcessSendOnceStrategy(LnnHeartbeatFsm *hbFsm, LnnProcessSendOnceMsgPara *msgPara, const GearMode *mode)
547 {
548     bool isRemoved = true;
549     LnnHeartbeatType registedHbType = msgPara->hbType;
550     bool wakeupFlag = mode != NULL ? mode->wakeupFlag : false;
551     (void)LnnVisitHbTypeSet(VisitClearUnRegistedHbType, &registedHbType, NULL);
552     if (registedHbType < HEARTBEAT_TYPE_MIN) {
553         LNN_LOGW(LNN_HEART_BEAT, "HB send once get hbType is not available. hbType=%{public}d", msgPara->hbType);
554         return SOFTBUS_OK;
555     }
556     LnnRemoveSendEndMsg(hbFsm, registedHbType, wakeupFlag, msgPara->isRelay, &isRemoved);
557     if (!isRemoved) {
558         LNN_LOGW(LNN_HEART_BEAT,
559             "HB send once is beginning, hbType=%{public}d, wakeupFlag=%{public}d, isRelay=%{public}d", msgPara->hbType,
560             wakeupFlag, msgPara->isRelay);
561         return SOFTBUS_OK;
562     }
563     LnnFsmRemoveMessage(&hbFsm->fsm, EVENT_HB_SEND_ONE_BEGIN);
564     bool isRelayV0 = msgPara->isRelay && ((registedHbType & HEARTBEAT_TYPE_BLE_V0) == HEARTBEAT_TYPE_BLE_V0);
565     if (SendEachSeparately(hbFsm, msgPara, mode, registedHbType, isRelayV0) != SOFTBUS_OK) {
566         LNN_LOGE(LNN_HEART_BEAT, "HB send each separately fail, hbType=%{public}d", registedHbType);
567         return SOFTBUS_ERR;
568     }
569     if (isRelayV0) {
570         LNN_LOGD(LNN_HEART_BEAT, "HB send once but dont check status, hbType=%{public}d", registedHbType);
571         return SOFTBUS_OK;
572     }
573     registedHbType &= (~(HEARTBEAT_TYPE_BLE_V3));
574     LnnCheckDevStatusMsgPara checkMsg = { .hbType = registedHbType, .hasNetworkId = false, .isWakeUp = wakeupFlag };
575     LnnRemoveCheckDevStatusMsg(hbFsm, &checkMsg);
576     if (LnnPostCheckDevStatusMsgToHbFsm(hbFsm, &checkMsg, HB_CHECK_DELAY_LEN) != SOFTBUS_OK) {
577         LNN_LOGE(LNN_HEART_BEAT, "HB send once post check msg fail, hbType=%{public}d", registedHbType);
578         return SOFTBUS_ERR;
579     }
580     return SOFTBUS_OK;
581 }
582 
SingleSendStrategy(LnnHeartbeatFsm * hbFsm,void * obj)583 static int32_t SingleSendStrategy(LnnHeartbeatFsm *hbFsm, void *obj)
584 {
585     LnnProcessSendOnceMsgPara *msgPara = (LnnProcessSendOnceMsgPara *)obj;
586     if (msgPara->strategyType != STRATEGY_HB_SEND_SINGLE) {
587         LNN_LOGE(LNN_HEART_BEAT, "HB single send get invaild strategy");
588         return SOFTBUS_INVALID_PARAM;
589     }
590     if (ProcessSendOnceStrategy(hbFsm, msgPara, NULL) != SOFTBUS_OK) {
591         LNN_LOGE(LNN_HEART_BEAT, "HB single send process send once fail");
592         return SOFTBUS_ERR;
593     }
594     return SOFTBUS_OK;
595 }
596 
FixedPeriodSendStrategy(LnnHeartbeatFsm * hbFsm,void * obj)597 static int32_t FixedPeriodSendStrategy(LnnHeartbeatFsm *hbFsm, void *obj)
598 {
599     LnnProcessSendOnceMsgPara *msgPara = (LnnProcessSendOnceMsgPara *)obj;
600 
601     if (msgPara->strategyType != STRATEGY_HB_SEND_FIXED_PERIOD) {
602         LNN_LOGE(LNN_HEART_BEAT, "HB fixed period send get invaild strategy");
603         return SOFTBUS_INVALID_PARAM;
604     }
605     if (ProcessSendOnceStrategy(hbFsm, msgPara, NULL) != SOFTBUS_OK) {
606         LNN_LOGE(LNN_HEART_BEAT, "HB fixed period send once fail");
607         return SOFTBUS_ERR;
608     }
609     if (LnnPostNextSendOnceMsgToHbFsm(hbFsm, msgPara, (uint64_t)LOW_FREQ_CYCLE * HB_TIME_FACTOR) != SOFTBUS_OK) {
610         LNN_LOGE(LNN_HEART_BEAT, "HB fixed period send loop msg fail");
611         return SOFTBUS_ERR;
612     }
613     return SOFTBUS_OK;
614 }
615 
AdjustablePeriodSendStrategy(LnnHeartbeatFsm * hbFsm,void * obj)616 static int32_t AdjustablePeriodSendStrategy(LnnHeartbeatFsm *hbFsm, void *obj)
617 {
618     int32_t ret;
619     GearMode mode;
620     (void)memset_s(&mode, sizeof(GearMode), 0, sizeof(GearMode));
621     LnnProcessSendOnceMsgPara *msgPara = (LnnProcessSendOnceMsgPara *)obj;
622 
623     if ((msgPara->hbType & HEARTBEAT_TYPE_BLE_V0) == 0 || msgPara->strategyType != STRATEGY_HB_SEND_ADJUSTABLE_PERIOD) {
624         LNN_LOGE(LNN_HEART_BEAT, "HB adjustable send get invaild strategy");
625         return SOFTBUS_INVALID_PARAM;
626     }
627     LnnRemoveProcessSendOnceMsg(hbFsm, msgPara->hbType, msgPara->strategyType);
628     ret = LnnGetGearModeBySpecificType(&mode, msgPara->callerId, HEARTBEAT_TYPE_BLE_V0);
629     if (ret == SOFTBUS_NETWORK_HEARTBEAT_EMPTY_LIST) {
630         LNN_LOGD(LNN_HEART_BEAT, "HB adjustable period strategy is end");
631         return SOFTBUS_OK;
632     }
633     if (ret != SOFTBUS_OK) {
634         LNN_LOGE(LNN_HEART_BEAT, "HB adjustable send get Gearmode err");
635         return SOFTBUS_ERR;
636     }
637     if (ProcessSendOnceStrategy(hbFsm, msgPara, &mode) != SOFTBUS_OK) {
638         LNN_LOGE(LNN_HEART_BEAT, "HB adjustable send once fail");
639         return SOFTBUS_ERR;
640     }
641     uint64_t delayMillis = (uint64_t)mode.cycle * HB_TIME_FACTOR;
642     if (LnnPostNextSendOnceMsgToHbFsm(hbFsm, (const LnnProcessSendOnceMsgPara *)obj, delayMillis) != SOFTBUS_OK) {
643         LNN_LOGE(LNN_HEART_BEAT, "HB adjustable send loop msg fail");
644         return SOFTBUS_ERR;
645     }
646     return SOFTBUS_OK;
647 }
648 
RegistParamMgrBySpecificType(LnnHeartbeatType type)649 static int32_t RegistParamMgrBySpecificType(LnnHeartbeatType type)
650 {
651     LnnHeartbeatParamManager *paramMgr = NULL;
652 
653     GearMode mode = {
654         .cycle = LOW_FREQ_CYCLE,
655         .duration = LONG_DURATION,
656         .wakeupFlag = false,
657     };
658     paramMgr = (LnnHeartbeatParamManager *)SoftBusCalloc(sizeof(LnnHeartbeatParamManager));
659     if (paramMgr == NULL) {
660         LNN_LOGE(LNN_HEART_BEAT, "HB regist param mgr malloc paramMgr fail");
661         return SOFTBUS_MALLOC_ERR;
662     }
663     paramMgr->type = type;
664     paramMgr->param = NULL;
665     paramMgr->isEnable = false;
666     paramMgr->gearModeCnt = 0;
667     ListInit(&paramMgr->gearModeList);
668 
669     if (type != HEARTBEAT_TYPE_BLE_V0 && type != HEARTBEAT_TYPE_BLE_V3) {
670         if (FirstSetGearModeByCallerId(HB_DEFAULT_CALLER_ID, 0, &paramMgr->gearModeList, &mode) != SOFTBUS_OK) {
671             LNN_LOGE(LNN_HEART_BEAT, "HB regist param mgr set default Gearmode fail");
672             SoftBusFree(paramMgr);
673             return SOFTBUS_ERR;
674         }
675         paramMgr->gearModeCnt++;
676     }
677     g_hbParamMgr[LnnConvertHbTypeToId(type)] = paramMgr;
678     return SOFTBUS_OK;
679 }
680 
VisitRegistParamMgr(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)681 static bool VisitRegistParamMgr(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
682 {
683     (void)typeSet;
684     (void)data;
685     const LnnHeartbeatParamManager *paramMgr = NULL;
686 
687     paramMgr = GetParamMgrByTypeLocked(eachType);
688     if (paramMgr != NULL) {
689         return true;
690     }
691     if (RegistParamMgrBySpecificType(eachType) != SOFTBUS_OK) {
692         LNN_LOGE(LNN_HEART_BEAT, "HB regist paramMgr err, type=%{public}d", eachType);
693         return false;
694     }
695     return true;
696 }
697 
LnnRegistParamMgrByType(LnnHeartbeatType type)698 int32_t LnnRegistParamMgrByType(LnnHeartbeatType type)
699 {
700     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
701         LNN_LOGE(LNN_HEART_BEAT, "HB regist paramMgr lock mutex fail");
702         return SOFTBUS_LOCK_ERR;
703     }
704     (void)LnnVisitHbTypeSet(VisitRegistParamMgr, &type, NULL);
705     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
706     return SOFTBUS_OK;
707 }
708 
UnRegistParamMgr(LnnHeartbeatParamManager * paramMgr)709 static void UnRegistParamMgr(LnnHeartbeatParamManager *paramMgr)
710 {
711     GearModeStorageInfo *item = NULL;
712     GearModeStorageInfo *nextItem = NULL;
713 
714     if (paramMgr->param != NULL) {
715         SoftBusFree(paramMgr->param);
716         paramMgr->param = NULL;
717     }
718     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &paramMgr->gearModeList, GearModeStorageInfo, node) {
719         ListDelete(&item->node);
720         if (item->callerId != NULL) {
721             SoftBusFree((char *)item->callerId);
722         }
723         SoftBusFree(item);
724     }
725     ListDelInit(&paramMgr->gearModeList);
726     SoftBusFree(paramMgr);
727     paramMgr = NULL;
728 }
729 
VisitUnRegistParamMgr(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)730 static bool VisitUnRegistParamMgr(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
731 {
732     (void)typeSet;
733     (void)data;
734     LnnHeartbeatParamManager *paramMgr = NULL;
735 
736     paramMgr = GetParamMgrByTypeLocked(eachType);
737     if (paramMgr == NULL) {
738         return true;
739     }
740     UnRegistParamMgr(paramMgr);
741     return true;
742 }
743 
LnnUnRegistParamMgrByType(LnnHeartbeatType type)744 void LnnUnRegistParamMgrByType(LnnHeartbeatType type)
745 {
746     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
747         LNN_LOGE(LNN_HEART_BEAT, "HB unRegist paramMgr lock mutex fail");
748         return;
749     }
750     (void)LnnVisitHbTypeSet(VisitUnRegistParamMgr, &type, NULL);
751     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
752 }
753 
LnnSetMediumParamBySpecificType(const LnnHeartbeatMediumParam * param)754 int32_t LnnSetMediumParamBySpecificType(const LnnHeartbeatMediumParam *param)
755 {
756     LnnHeartbeatParamManager *paramMgr = NULL;
757 
758     if (param == NULL) {
759         LNN_LOGE(LNN_HEART_BEAT, "HB set medium param get invalid param");
760         return SOFTBUS_INVALID_PARAM;
761     }
762     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
763         LNN_LOGE(LNN_HEART_BEAT, "HB set medium param lock mutex fail");
764         return SOFTBUS_LOCK_ERR;
765     }
766     paramMgr = GetParamMgrByTypeLocked(param->type);
767     if (paramMgr == NULL) {
768         LNN_LOGE(LNN_HEART_BEAT, "HB set medium param get NULL paramMgr");
769         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
770         return SOFTBUS_ERR;
771     }
772     if (paramMgr->param == NULL) {
773         paramMgr->param = (LnnHeartbeatMediumParam *)SoftBusCalloc(sizeof(LnnHeartbeatMediumParam));
774     }
775     if (paramMgr->param == NULL) {
776         LNN_LOGE(LNN_HEART_BEAT, "HB set medium param calloc err");
777         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
778         return SOFTBUS_MALLOC_ERR;
779     }
780     if (memcpy_s(paramMgr->param, sizeof(LnnHeartbeatMediumParam), param, sizeof(LnnHeartbeatMediumParam)) != EOK) {
781         LNN_LOGE(LNN_HEART_BEAT, "HB set medium param memcpy_s err");
782         SoftBusFree(paramMgr->param);
783         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
784         return SOFTBUS_MEM_ERR;
785     }
786 
787     int32_t ret = LnnPostSetMediumParamMsgToHbFsm(g_hbFsm, paramMgr->param);
788     if (ret != SOFTBUS_OK) {
789         LNN_LOGE(LNN_HEART_BEAT, "HB set medium param via mgr err");
790         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
791         return ret;
792     }
793     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
794     return SOFTBUS_OK;
795 }
796 
LnnGetMediumParamBySpecificType(LnnHeartbeatMediumParam * param,LnnHeartbeatType type)797 int32_t LnnGetMediumParamBySpecificType(LnnHeartbeatMediumParam *param, LnnHeartbeatType type)
798 {
799     const LnnHeartbeatParamManager *paramMgr = NULL;
800 
801     if (param == NULL) {
802         LNN_LOGE(LNN_HEART_BEAT, "HB get medium param get invalid param");
803         return SOFTBUS_INVALID_PARAM;
804     }
805     if (memset_s(param, sizeof(LnnHeartbeatMediumParam), 0, sizeof(LnnHeartbeatMediumParam) != EOK)) {
806         LNN_LOGE(LNN_HEART_BEAT, "HB get medium param memset_s err");
807         return SOFTBUS_MEM_ERR;
808     }
809     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
810         LNN_LOGE(LNN_HEART_BEAT, "HB get medium param lock mutex fail!");
811         return SOFTBUS_LOCK_ERR;
812     }
813     paramMgr = GetParamMgrByTypeLocked(type);
814     if (paramMgr == NULL || paramMgr->param == NULL) {
815         LNN_LOGE(LNN_HEART_BEAT, "HB get medium param get NULL paramMgr");
816         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
817         return SOFTBUS_ERR;
818     }
819     if (memcpy_s(param, sizeof(LnnHeartbeatMediumParam), paramMgr->param, sizeof(LnnHeartbeatMediumParam)) != EOK) {
820         LNN_LOGE(LNN_HEART_BEAT, "HB get medium param memcpy_s err");
821         (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
822         return SOFTBUS_MEM_ERR;
823     }
824     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
825     return SOFTBUS_OK;
826 }
827 
LnnGetHbStrategyManager(LnnHeartbeatStrategyManager * mgr,LnnHeartbeatType hbType,LnnHeartbeatStrategyType strategyType)828 int32_t LnnGetHbStrategyManager(
829     LnnHeartbeatStrategyManager *mgr, LnnHeartbeatType hbType, LnnHeartbeatStrategyType strategyType)
830 {
831     if (mgr == NULL) {
832         LNN_LOGE(LNN_HEART_BEAT, "HB get strategy mgr invalid param");
833         return SOFTBUS_INVALID_PARAM;
834     }
835     if (!LnnCheckSupportedHbType(&hbType, &g_hbStrategyMgr[strategyType].supportType)) {
836         LNN_LOGE(LNN_HEART_BEAT, "HB get strategy mgr not support, type=%{public}d, hbType=%{public}d", strategyType,
837             hbType);
838         return SOFTBUS_ERR;
839     }
840     mgr->supportType = g_hbStrategyMgr[strategyType].supportType;
841     mgr->onProcess = g_hbStrategyMgr[strategyType].onProcess;
842     return SOFTBUS_OK;
843 }
844 
LnnStartNewHbStrategyFsm(void)845 int32_t LnnStartNewHbStrategyFsm(void)
846 {
847     LnnHeartbeatFsm *hbFsm = NULL;
848 
849     hbFsm = LnnCreateHeartbeatFsm();
850     if (hbFsm == NULL) {
851         LNN_LOGE(LNN_HEART_BEAT, "HB start strategy fsm create fsm fail");
852         return SOFTBUS_ERR;
853     }
854     /* If udp heartbeat deployed, use HEARTBEAT_TYPE_UDP | HEARTBEAT_TYPE_BLE_V1 */
855     hbFsm->hbType = HEARTBEAT_TYPE_BLE_V1;
856     hbFsm->strategyType = STRATEGY_HB_SEND_FIXED_PERIOD;
857     if (LnnStartHeartbeatFsm(hbFsm) != SOFTBUS_OK) {
858         LNN_LOGE(LNN_HEART_BEAT, "HB start strategy fsm start fsm fail");
859         return SOFTBUS_ERR;
860     }
861     g_hbFsm = hbFsm;
862     hbFsm = NULL;
863     return SOFTBUS_OK;
864 }
865 
LnnStartOfflineTimingStrategy(const char * networkId,ConnectionAddrType addrType)866 int32_t LnnStartOfflineTimingStrategy(const char *networkId, ConnectionAddrType addrType)
867 {
868     GearMode mode;
869     (void)memset_s(&mode, sizeof(GearMode), 0, sizeof(GearMode));
870     LnnCheckDevStatusMsgPara msgPara = { 0 };
871 
872     if (networkId == NULL) {
873         return SOFTBUS_INVALID_PARAM;
874     }
875     char *anonyNetworkId = NULL;
876     if (LnnIsSupportBurstFeature(networkId)) {
877         Anonymize(networkId, &anonyNetworkId);
878         LNN_LOGD(LNN_HEART_BEAT, "%{public}s support burst, dont't need post offline info", anonyNetworkId);
879         AnonymizeFree(anonyNetworkId);
880         return SOFTBUS_OK;
881     }
882     if (strcpy_s((char *)msgPara.networkId, NETWORK_ID_BUF_LEN, networkId) != EOK) {
883         LNN_LOGE(LNN_HEART_BEAT, "HB start offline timing strcpy_s networkId fail");
884         return SOFTBUS_ERR;
885     }
886     msgPara.addrType = addrType;
887     msgPara.hasNetworkId = true;
888     msgPara.hbType = LnnConvertConnAddrTypeToHbType(addrType);
889     if (LnnGetGearModeBySpecificType(&mode, NULL, msgPara.hbType) != SOFTBUS_OK) {
890         return SOFTBUS_ERR;
891     }
892     uint64_t delayMillis = (uint64_t)mode.cycle * HB_TIME_FACTOR + HB_NOTIFY_DEV_LOST_DELAY_LEN;
893     return LnnPostCheckDevStatusMsgToHbFsm(g_hbFsm, &msgPara, delayMillis);
894 }
895 
LnnStopOfflineTimingStrategy(const char * networkId,ConnectionAddrType addrType)896 int32_t LnnStopOfflineTimingStrategy(const char *networkId, ConnectionAddrType addrType)
897 {
898     if (networkId == NULL) {
899         return SOFTBUS_INVALID_PARAM;
900     }
901     LnnCheckDevStatusMsgPara msgPara = {
902         .hbType = LnnConvertConnAddrTypeToHbType(addrType),
903         .addrType = addrType,
904     };
905     if (strcpy_s((char *)msgPara.networkId, NETWORK_ID_BUF_LEN, networkId) != EOK) {
906         LNN_LOGE(LNN_HEART_BEAT, "HB stop offline timing strcpy_s networkId fail");
907         return SOFTBUS_ERR;
908     }
909     msgPara.hasNetworkId = true;
910     LnnRemoveCheckDevStatusMsg(g_hbFsm, &msgPara);
911     return SOFTBUS_OK;
912 }
913 
LnnStartScreenChangeOfflineTiming(const char * networkId,ConnectionAddrType addrType)914 int32_t LnnStartScreenChangeOfflineTiming(const char *networkId, ConnectionAddrType addrType)
915 {
916     LNN_LOGI(LNN_HEART_BEAT, "start screen changed offline timing");
917     if (networkId == NULL || addrType >= CONNECTION_ADDR_MAX) {
918         LNN_LOGE(LNN_HEART_BEAT, "invalid param");
919         return SOFTBUS_INVALID_PARAM;
920     }
921     LnnCheckDevStatusMsgPara msgPara = { 0 };
922     if (strcpy_s((char *)msgPara.networkId, NETWORK_ID_BUF_LEN, networkId) != EOK) {
923         LNN_LOGE(LNN_HEART_BEAT, "HB start offline timing strcpy_s networkId fail");
924         return SOFTBUS_ERR;
925     }
926     msgPara.hasNetworkId = true;
927     msgPara.hbType = LnnConvertConnAddrTypeToHbType(addrType);
928 
929     if (LnnPostScreenOffCheckDevMsgToHbFsm(g_hbFsm, &msgPara, HB_OFFLINE_PERIOD * HB_OFFLINE_TIME) != SOFTBUS_OK) {
930         LNN_LOGE(LNN_HEART_BEAT, "post screen off check dev msg failed");
931         return SOFTBUS_ERR;
932     }
933     return SOFTBUS_OK;
934 }
935 
LnnStopScreenChangeOfflineTiming(const char * networkId,ConnectionAddrType addrType)936 int32_t LnnStopScreenChangeOfflineTiming(const char *networkId, ConnectionAddrType addrType)
937 {
938     if (networkId == NULL) {
939         return SOFTBUS_INVALID_PARAM;
940     }
941     LnnCheckDevStatusMsgPara msgPara = {
942         .hbType = LnnConvertConnAddrTypeToHbType(addrType),
943         .addrType = addrType,
944     };
945     if (strcpy_s((char *)msgPara.networkId, NETWORK_ID_BUF_LEN, networkId) != EOK) {
946         LNN_LOGE(LNN_HEART_BEAT, "HB stop offline timing strcpy_s networkId fail");
947         return SOFTBUS_ERR;
948     }
949     msgPara.hasNetworkId = true;
950     LnnRemoveScreenOffCheckStatusMsg(g_hbFsm, &msgPara);
951     return SOFTBUS_OK;
952 }
953 
LnnStartHbByTypeAndStrategy(LnnHeartbeatType hbType,LnnHeartbeatStrategyType strategyType,bool isRelay)954 int32_t LnnStartHbByTypeAndStrategy(LnnHeartbeatType hbType, LnnHeartbeatStrategyType strategyType, bool isRelay)
955 {
956     LnnProcessSendOnceMsgPara msgPara = {
957         .hbType = hbType,
958         .strategyType = strategyType,
959         .isRelay = isRelay,
960         .isSyncData = false,
961     };
962     if (LnnPostNextSendOnceMsgToHbFsm(g_hbFsm, &msgPara, 0) != SOFTBUS_OK) {
963         LNN_LOGE(LNN_HEART_BEAT, "HB start heartbeat fail, type=%{public}d", hbType);
964         return SOFTBUS_ERR;
965     }
966     return SOFTBUS_OK;
967 }
968 
LnnStartHeartbeat(uint64_t delayMillis)969 int32_t LnnStartHeartbeat(uint64_t delayMillis)
970 {
971     LNN_LOGI(LNN_HEART_BEAT, "heartbeat(HB) process start delay=%{public}" PRIu64 "msec", delayMillis);
972     return LnnPostStartMsgToHbFsm(g_hbFsm, delayMillis);
973 }
974 
LnnStopV0HeartbeatAndNotTransState()975 int32_t LnnStopV0HeartbeatAndNotTransState()
976 {
977     LNN_LOGI(LNN_HEART_BEAT, "HB only stop heartbeat V0");
978     if (LnnPostStopMsgToHbFsm(g_hbFsm, HEARTBEAT_TYPE_BLE_V0) != SOFTBUS_OK) {
979         LNN_LOGE(LNN_HEART_BEAT, "HB stop heartbeat by type post msg fail");
980         return SOFTBUS_ERR;
981     }
982     return SOFTBUS_OK;
983 }
984 
LnnStopHeartbeatByType(LnnHeartbeatType type)985 int32_t LnnStopHeartbeatByType(LnnHeartbeatType type)
986 {
987     if (LnnPostStopMsgToHbFsm(g_hbFsm, type) != SOFTBUS_OK) {
988         LNN_LOGE(LNN_HEART_BEAT, "HB stop heartbeat by type post msg fail");
989         return SOFTBUS_ERR;
990     }
991     LnnHbClearRecvList();
992     if (type ==
993         (HEARTBEAT_TYPE_UDP | HEARTBEAT_TYPE_BLE_V0 | HEARTBEAT_TYPE_BLE_V1 | HEARTBEAT_TYPE_BLE_V3 |
994             HEARTBEAT_TYPE_TCP_FLUSH)) {
995         return LnnPostTransStateMsgToHbFsm(g_hbFsm, EVENT_HB_IN_NONE_STATE);
996     }
997     return SOFTBUS_OK;
998 }
999 
LnnStopHeartBeatAdvByTypeNow(LnnHeartbeatType type)1000 int32_t LnnStopHeartBeatAdvByTypeNow(LnnHeartbeatType type)
1001 {
1002     if (type <= HEARTBEAT_TYPE_MIN || type >= HEARTBEAT_TYPE_MAX) {
1003         LNN_LOGE(LNN_HEART_BEAT, "HB send once get is not available, hbType=%{public}d", type);
1004         return SOFTBUS_ERR;
1005     }
1006     LnnHeartbeatSendEndData endData = {
1007         .hbType = type,
1008         .wakeupFlag = false,
1009         .isRelay = false,
1010         .isLastEnd = true,
1011     };
1012     if (LnnPostSendEndMsgToHbFsm(g_hbFsm, &endData, 0) != SOFTBUS_OK) {
1013         LNN_LOGE(LNN_HEART_BEAT, "HB send once end fail, hbType=%{public}d", type);
1014         return SOFTBUS_ERR;
1015     }
1016     return SOFTBUS_OK;
1017 }
1018 
VisitEnableHbType(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)1019 static bool VisitEnableHbType(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
1020 {
1021     bool *isEnable = (bool *)data;
1022     LnnHeartbeatParamManager *paramMgr = NULL;
1023 
1024     paramMgr = GetParamMgrByTypeLocked(eachType);
1025     if (paramMgr == NULL) {
1026         LNN_LOGW(LNN_HEART_BEAT, "HB enable get param mgr is NULL, hbType=%{public}d", eachType);
1027         return true;
1028     }
1029     paramMgr->isEnable = *isEnable;
1030     return true;
1031 }
1032 
LnnEnableHeartbeatByType(LnnHeartbeatType type,bool isEnable)1033 int32_t LnnEnableHeartbeatByType(LnnHeartbeatType type, bool isEnable)
1034 {
1035     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
1036         LNN_LOGE(LNN_HEART_BEAT, "HB enable hbType lock mutex fail");
1037         return SOFTBUS_LOCK_ERR;
1038     }
1039     (void)LnnVisitHbTypeSet(VisitEnableHbType, &type, &isEnable);
1040     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
1041     return SOFTBUS_OK;
1042 }
1043 
LnnIsHeartbeatEnable(LnnHeartbeatType type)1044 bool LnnIsHeartbeatEnable(LnnHeartbeatType type)
1045 {
1046     bool ret = false;
1047     LnnHeartbeatParamManager *paramMgr = NULL;
1048 
1049     if (SoftBusMutexLock(&g_hbStrategyMutex) != 0) {
1050         LNN_LOGE(LNN_HEART_BEAT, "HB get param regist status lock mutex fail");
1051         return false;
1052     }
1053     paramMgr = GetParamMgrByTypeLocked(type);
1054     ret = (paramMgr != NULL && paramMgr->isEnable) ? true : false;
1055     (void)SoftBusMutexUnlock(&g_hbStrategyMutex);
1056     return ret;
1057 }
1058 
LnnSetHbAsMasterNodeState(bool isMasterNode)1059 int32_t LnnSetHbAsMasterNodeState(bool isMasterNode)
1060 {
1061     return LnnPostTransStateMsgToHbFsm(g_hbFsm, isMasterNode ? EVENT_HB_AS_MASTER_NODE : EVENT_HB_AS_NORMAL_NODE);
1062 }
1063 
LnnUpdateSendInfoStrategy(LnnHeartbeatUpdateInfoType type)1064 int32_t LnnUpdateSendInfoStrategy(LnnHeartbeatUpdateInfoType type)
1065 {
1066     return LnnPostUpdateSendInfoMsgToHbFsm(g_hbFsm, type);
1067 }
1068 
LnnHbStrategyInit(void)1069 int32_t LnnHbStrategyInit(void)
1070 {
1071     if (SoftBusMutexInit(&g_hbStrategyMutex, NULL) != 0) {
1072         LNN_LOGE(LNN_HEART_BEAT, "HB strategy module init mutex fail!");
1073         return SOFTBUS_ERR;
1074     }
1075     if (LnnRegistParamMgrByType(HEARTBEAT_TYPE_BLE_V0 | HEARTBEAT_TYPE_BLE_V1 | HEARTBEAT_TYPE_BLE_V3) != SOFTBUS_OK) {
1076         LNN_LOGE(LNN_HEART_BEAT, "HB regist ble strategy fail");
1077         return SOFTBUS_ERR;
1078     }
1079     if (LnnRegistParamMgrByType(HEARTBEAT_TYPE_TCP_FLUSH) != SOFTBUS_OK) {
1080         LNN_LOGE(LNN_HEART_BEAT, "HB regist udp/tcp strategy fail");
1081         return SOFTBUS_ERR;
1082     }
1083     return SOFTBUS_OK;
1084 }
1085 
LnnHbStrategyDeinit(void)1086 void LnnHbStrategyDeinit(void)
1087 {
1088     if (g_hbFsm != NULL) {
1089         (void)LnnStopHeartbeatFsm(g_hbFsm);
1090     }
1091     LnnUnRegistParamMgrByType(HEARTBEAT_TYPE_BLE_V0 | HEARTBEAT_TYPE_BLE_V1 | HEARTBEAT_TYPE_BLE_V3);
1092     LnnUnRegistParamMgrByType(HEARTBEAT_TYPE_TCP_FLUSH);
1093     (void)SoftBusMutexDestroy(&g_hbStrategyMutex);
1094 }
1095