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(×);
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(¶mMgr->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, ¶mMgr->gearModeList, ¶mMgr->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(×);
264 nowTime = times.sec * HB_TIME_FACTOR + times.usec / HB_TIME_FACTOR;
265 LIST_FOR_EACH_ENTRY(info, ¶mMgr->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, ¶mMgr->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, ®istedHbType, 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(¶mMgr->gearModeList);
668
669 if (type != HEARTBEAT_TYPE_BLE_V0 && type != HEARTBEAT_TYPE_BLE_V3) {
670 if (FirstSetGearModeByCallerId(HB_DEFAULT_CALLER_ID, 0, ¶mMgr->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, ¶mMgr->gearModeList, GearModeStorageInfo, node) {
719 ListDelete(&item->node);
720 if (item->callerId != NULL) {
721 SoftBusFree((char *)item->callerId);
722 }
723 SoftBusFree(item);
724 }
725 ListDelInit(¶mMgr->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