1 /*
2  * Copyright (c) 2022 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_medium_mgr.h"
17 
18 #include <securec.h>
19 #include <string.h>
20 
21 #include "anonymizer.h"
22 #include "auth_manager.h"
23 #include "auth_device_common_key.h"
24 #include "auth_deviceprofile.h"
25 #include "auth_interface.h"
26 #include "bus_center_info_key.h"
27 #include "bus_center_manager.h"
28 #include "common_list.h"
29 #include "lnn_async_callback_utils.h"
30 #include "lnn_ble_heartbeat.h"
31 #include "lnn_ble_lpdevice.h"
32 #include "lnn_cipherkey_manager.h"
33 #include "lnn_connection_addr_utils.h"
34 #include "lnn_device_info.h"
35 #include "lnn_device_info_recovery.h"
36 #include "lnn_distributed_net_ledger.h"
37 #include "lnn_event.h"
38 #include "lnn_feature_capability.h"
39 #include "lnn_heartbeat_fsm.h"
40 #include "lnn_heartbeat_strategy.h"
41 #include "lnn_heartbeat_utils.h"
42 #include "lnn_lane_vap_info.h"
43 #include "lnn_log.h"
44 #include "lnn_net_builder.h"
45 #include "lnn_node_info.h"
46 #include "lnn_parameter_utils.h"
47 
48 #include "softbus_adapter_mem.h"
49 #include "softbus_adapter_bt_common.h"
50 #include "softbus_adapter_timer.h"
51 #include "softbus_def.h"
52 #include "softbus_errcode.h"
53 #include "softbus_utils.h"
54 
55 #define INVALID_BR_MAC_ADDR "00:00:00:00:00:00"
56 
57 #define HB_RECV_INFO_SAVE_LEN (60 * 60 * HB_TIME_FACTOR)
58 #define HB_REAUTH_TIME        (10 * HB_TIME_FACTOR)
59 #define HB_DFX_DELAY_TIME     (7 * HB_TIME_FACTOR)
60 #define PC_RESTRICT_TIME    3
61 typedef struct {
62     ListNode node;
63     DeviceInfo *device;
64     int32_t weight;
65     int32_t masterWeight;
66     uint64_t lastRecvTime;
67     uint64_t lastJoinLnnTime;
68 } LnnHeartbeatRecvInfo;
69 
70 typedef struct {
71     ConnectOnlineReason connectReason;
72     bool isConnect;
73 } LnnConnectCondition;
74 
75 static void HbMediumMgrRelayProcess(const char *udidHash, ConnectionAddrType type, LnnHeartbeatType hbType);
76 static int32_t HbMediumMgrRecvProcess(DeviceInfo *device, const LnnHeartbeatWeight *mediumWeight,
77     LnnHeartbeatType hbType, bool isOnlineDirectly, HbRespData *hbResp);
78 static int32_t HbMediumMgrRecvHigherWeight(
79     const char *udidHash, int32_t weight, ConnectionAddrType type, bool isReElect, bool isPeerScreenOn);
80 static void HbMediumMgrRecvLpInfo(const char *networkId, uint64_t nowTime);
81 
82 static LnnHeartbeatMediumMgr *g_hbMeidumMgr[HB_MAX_TYPE_COUNT] = { 0 };
83 
84 static LnnHeartbeatMediumMgrCb g_hbMediumMgrCb = {
85     .onRelay = HbMediumMgrRelayProcess,
86     .onReceive = HbMediumMgrRecvProcess,
87     .onRecvHigherWeight = HbMediumMgrRecvHigherWeight,
88     .onRecvLpInfo = HbMediumMgrRecvLpInfo,
89 };
90 
91 static SoftBusList *g_hbRecvList = NULL;
92 
HbFirstSaveRecvTime(LnnHeartbeatRecvInfo * storedInfo,DeviceInfo * device,int32_t weight,int32_t masterWeight,uint64_t recvTime)93 static int32_t HbFirstSaveRecvTime(
94     LnnHeartbeatRecvInfo *storedInfo, DeviceInfo *device, int32_t weight, int32_t masterWeight, uint64_t recvTime)
95 {
96     LnnHeartbeatRecvInfo *recvInfo = NULL;
97 
98     recvInfo = (LnnHeartbeatRecvInfo *)SoftBusMalloc(sizeof(LnnHeartbeatRecvInfo));
99     if (recvInfo == NULL) {
100         LNN_LOGE(LNN_HEART_BEAT, "medium mgr malloc recvInfo err");
101         return SOFTBUS_MALLOC_ERR;
102     }
103     recvInfo->device = (DeviceInfo *)SoftBusCalloc(sizeof(DeviceInfo));
104     if (recvInfo->device == NULL) {
105         LNN_LOGE(LNN_HEART_BEAT, "medium mgr deviceInfo calloc err");
106         SoftBusFree(recvInfo);
107         return SOFTBUS_MALLOC_ERR;
108     }
109     if (memcpy_s(recvInfo->device, sizeof(DeviceInfo), device, sizeof(DeviceInfo)) != EOK) {
110         LNN_LOGE(LNN_HEART_BEAT, "memcpy_s deviceInfo err");
111         SoftBusFree(recvInfo->device);
112         SoftBusFree(recvInfo);
113         return SOFTBUS_MEM_ERR;
114     }
115     recvInfo->weight = weight;
116     recvInfo->lastRecvTime = recvTime;
117     recvInfo->masterWeight = masterWeight;
118     ListInit(&recvInfo->node);
119     ListAdd(&g_hbRecvList->list, &recvInfo->node);
120     g_hbRecvList->cnt++;
121     storedInfo = recvInfo;
122     return SOFTBUS_OK;
123 }
124 
HbSaveRecvTimeToRemoveRepeat(LnnHeartbeatRecvInfo * storedInfo,DeviceInfo * device,int32_t weight,int32_t masterWeight,uint64_t recvTime)125 static int32_t HbSaveRecvTimeToRemoveRepeat(
126     LnnHeartbeatRecvInfo *storedInfo, DeviceInfo *device, int32_t weight, int32_t masterWeight, uint64_t recvTime)
127 {
128     if (storedInfo != NULL) {
129         storedInfo->lastRecvTime = recvTime;
130         storedInfo->weight = weight != 0 ? weight : storedInfo->weight;
131         storedInfo->masterWeight = masterWeight;
132         storedInfo->device->isOnline = device->isOnline;
133         return SOFTBUS_OK;
134     }
135     int32_t ret = HbFirstSaveRecvTime(storedInfo, device, weight, masterWeight, recvTime);
136     if (ret != SOFTBUS_OK) {
137         char *anonyUdid = NULL;
138         Anonymize(device->devId, &anonyUdid);
139         LNN_LOGE(LNN_HEART_BEAT, "save recv time fail, udidHash=%{public}s", anonyUdid);
140         AnonymizeFree(anonyUdid);
141     }
142     return ret;
143 }
144 
HbGetRepeatThresholdByType(LnnHeartbeatType hbType)145 static uint64_t HbGetRepeatThresholdByType(LnnHeartbeatType hbType)
146 {
147     if (LnnIsMultiDeviceOnline()) {
148         return HB_REPEAD_RECV_THRESHOLD_MULTI_DEVICE;
149     }
150     switch (hbType) {
151         case HEARTBEAT_TYPE_BLE_V0:
152             return HB_REPEAD_RECV_THRESHOLD;
153         case HEARTBEAT_TYPE_BLE_V1:
154             return HB_REPEAD_JOIN_LNN_THRESHOLD;
155         default:
156             return 0;
157     }
158 }
159 
UpdateOnlineInfoNoConnection(const char * networkId,HbRespData * hbResp)160 static void UpdateOnlineInfoNoConnection(const char *networkId, HbRespData *hbResp)
161 {
162     if (hbResp == NULL || hbResp->stateVersion == STATE_VERSION_INVALID) {
163         LNN_LOGD(LNN_HEART_BEAT, "isn't ble directly online, ignore");
164         return;
165     }
166     NodeInfo nodeInfo;
167     (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
168     if (LnnGetRemoteNodeInfoById(networkId, CATEGORY_NETWORK_ID, &nodeInfo) != SOFTBUS_OK) {
169         LNN_LOGD(LNN_HEART_BEAT, "get nodeInfo fail");
170         return;
171     }
172     if (nodeInfo.deviceInfo.deviceTypeId == TYPE_PC_ID) {
173         LNN_LOGI(LNN_HEART_BEAT, "winpc no need update netCapacity");
174         return;
175     }
176     uint32_t oldNetCapa = nodeInfo.netCapacity;
177     if ((hbResp->capabiltiy & ENABLE_WIFI_CAP) != 0) {
178         (void)LnnSetNetCapability(&nodeInfo.netCapacity, BIT_WIFI);
179     } else {
180         (void)LnnClearNetCapability(&nodeInfo.netCapacity, BIT_WIFI);
181         (void)LnnClearNetCapability(&nodeInfo.netCapacity, BIT_WIFI_5G);
182         (void)LnnClearNetCapability(&nodeInfo.netCapacity, BIT_WIFI_24G);
183     }
184     if ((hbResp->capabiltiy & P2P_GO) != 0 || (hbResp->capabiltiy & P2P_GC) != 0) {
185         (void)LnnSetNetCapability(&nodeInfo.netCapacity, BIT_WIFI_P2P);
186     } else {
187         (void)LnnClearNetCapability(&nodeInfo.netCapacity, BIT_WIFI_P2P);
188     }
189     if ((hbResp->capabiltiy & DISABLE_BR_CAP) != 0) {
190         (void)LnnClearNetCapability(&nodeInfo.netCapacity, BIT_BR);
191     } else {
192         (void)LnnSetNetCapability(&nodeInfo.netCapacity, BIT_BR);
193     }
194     (void)LnnSetNetCapability(&nodeInfo.netCapacity, BIT_BLE);
195     if (oldNetCapa == nodeInfo.netCapacity) {
196         LNN_LOGD(LNN_HEART_BEAT, "capa not change, don't update devInfo");
197         return;
198     }
199     if (LnnSetDLConnCapability(networkId, nodeInfo.netCapacity) != SOFTBUS_OK) {
200         LNN_LOGE(LNN_HEART_BEAT, "update net capability fail");
201         return;
202     }
203     char *anonyNetworkId = NULL;
204     Anonymize(networkId, &anonyNetworkId);
205     LNN_LOGI(LNN_HEART_BEAT, "networkId=%{public}s capability change:%{public}u->%{public}u", anonyNetworkId,
206         oldNetCapa, nodeInfo.netCapacity);
207     AnonymizeFree(anonyNetworkId);
208 }
209 
HbGetOnlineNodeByRecvInfo(const char * recvUdidHash,const ConnectionAddrType recvAddrType,NodeInfo * nodeInfo,HbRespData * hbResp)210 static int32_t HbGetOnlineNodeByRecvInfo(
211     const char *recvUdidHash, const ConnectionAddrType recvAddrType, NodeInfo *nodeInfo, HbRespData *hbResp)
212 {
213     int32_t i, infoNum;
214     NodeBasicInfo *info = NULL;
215     char udidHash[HB_SHORT_UDID_HASH_HEX_LEN + 1] = { 0 };
216 
217     if (LnnGetAllOnlineNodeInfo(&info, &infoNum) != SOFTBUS_OK) {
218         LNN_LOGE(LNN_HEART_BEAT, "get all online node info fail");
219         return SOFTBUS_ERR;
220     }
221     if (info == NULL || infoNum == 0) {
222         LNN_LOGD(LNN_HEART_BEAT, "none online node");
223         return SOFTBUS_ERR;
224     }
225     DiscoveryType discType = LnnConvAddrTypeToDiscType(recvAddrType);
226     for (i = 0; i < infoNum; ++i) {
227         if (LnnIsLSANode(&info[i])) {
228             continue;
229         }
230         if (LnnGetRemoteNodeInfoById(info[i].networkId, CATEGORY_NETWORK_ID, nodeInfo) != SOFTBUS_OK) {
231             LNN_LOGD(LNN_HEART_BEAT, "get nodeInfo fail");
232             continue;
233         }
234         if (!LnnHasDiscoveryType(nodeInfo, discType)) {
235             char *anonyNetworkId = NULL;
236             Anonymize(info[i].networkId, &anonyNetworkId);
237             LNN_LOGD(LNN_HEART_BEAT, "node online not have discType. networkId=%{public}s, discType=%{public}d",
238                 anonyNetworkId, discType);
239             AnonymizeFree(anonyNetworkId);
240             continue;
241         }
242         if (LnnGenerateHexStringHash((const unsigned char *)nodeInfo->deviceInfo.deviceUdid, udidHash,
243             HB_SHORT_UDID_HASH_HEX_LEN) != SOFTBUS_OK) {
244             continue;
245         }
246         if (strncmp(udidHash, recvUdidHash, HB_SHORT_UDID_HASH_HEX_LEN) == 0) {
247             char *anonyNetworkId = NULL;
248             char *anonyUdid = NULL;
249             Anonymize(udidHash, &anonyUdid);
250             Anonymize(info[i].networkId, &anonyNetworkId);
251             LNN_LOGD(
252                 LNN_HEART_BEAT, "node is online. udidHash=%{public}s, networkId=%{public}s", anonyUdid, anonyNetworkId);
253             AnonymizeFree(anonyNetworkId);
254             AnonymizeFree(anonyUdid);
255             UpdateOnlineInfoNoConnection(info[i].networkId, hbResp);
256             SoftBusFree(info);
257             return SOFTBUS_OK;
258         }
259     }
260     SoftBusFree(info);
261     return SOFTBUS_ERR;
262 }
263 
HbUpdateOfflineTimingByRecvInfo(const char * networkId,ConnectionAddrType type,LnnHeartbeatType hbType,uint64_t updateTime)264 static int32_t HbUpdateOfflineTimingByRecvInfo(
265     const char *networkId, ConnectionAddrType type, LnnHeartbeatType hbType, uint64_t updateTime)
266 {
267     uint64_t oldTimeStamp;
268     char *anonyNetworkId = NULL;
269     if (LnnGetDLHeartbeatTimestamp(networkId, &oldTimeStamp) != SOFTBUS_OK) {
270         Anonymize(networkId, &anonyNetworkId);
271         LNN_LOGE(LNN_HEART_BEAT, "get timestamp err, networkId=%{public}s", anonyNetworkId);
272         AnonymizeFree(anonyNetworkId);
273         return SOFTBUS_ERR;
274     }
275     if (LnnSetDLHeartbeatTimestamp(networkId, updateTime) != SOFTBUS_OK) {
276         Anonymize(networkId, &anonyNetworkId);
277         LNN_LOGE(LNN_HEART_BEAT, "update timestamp err, networkId=%{public}s", anonyNetworkId);
278         AnonymizeFree(anonyNetworkId);
279         return SOFTBUS_ERR;
280     }
281     Anonymize(networkId, &anonyNetworkId);
282     LNN_LOGI(LNN_HEART_BEAT,
283         "recv to update timestamp, networkId=%{public}s, timestamp:%{public}" PRIu64 "->%{public}" PRIu64,
284         anonyNetworkId, oldTimeStamp, updateTime);
285     if (hbType != HEARTBEAT_TYPE_BLE_V1 && hbType != HEARTBEAT_TYPE_BLE_V0) {
286         LNN_LOGD(LNN_HEART_BEAT, "only BLE_V1 and BLE_V0 support offline timing");
287         AnonymizeFree(anonyNetworkId);
288         return SOFTBUS_ERR;
289     }
290     if (LnnStopOfflineTimingStrategy(networkId, type) != SOFTBUS_OK) {
291         LNN_LOGE(LNN_HEART_BEAT, "remove offline check err, networkId=%{public}s", anonyNetworkId);
292         AnonymizeFree(anonyNetworkId);
293         return SOFTBUS_ERR;
294     }
295     if (LnnStartOfflineTimingStrategy(networkId, type) != SOFTBUS_OK) {
296         LNN_LOGE(LNN_HEART_BEAT, "set new offline check err, networkId=%{public}s", anonyNetworkId);
297         AnonymizeFree(anonyNetworkId);
298         return SOFTBUS_ERR;
299     }
300     AnonymizeFree(anonyNetworkId);
301     return SOFTBUS_OK;
302 }
303 
HbGetStoredRecvInfo(const char * udidHash,ConnectionAddrType type,uint64_t recvTime)304 static LnnHeartbeatRecvInfo *HbGetStoredRecvInfo(const char *udidHash, ConnectionAddrType type, uint64_t recvTime)
305 {
306     LnnHeartbeatRecvInfo *item = NULL;
307     LnnHeartbeatRecvInfo *next = NULL;
308 
309     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_hbRecvList->list, LnnHeartbeatRecvInfo, node) {
310         if ((recvTime - item->lastRecvTime) > HB_RECV_INFO_SAVE_LEN) {
311             ListDelete(&item->node);
312             SoftBusFree(item->device);
313             SoftBusFree(item);
314             g_hbRecvList->cnt--;
315             continue;
316         }
317         if (memcmp(item->device->devId, udidHash, DISC_MAX_DEVICE_ID_LEN) == 0 &&
318             LnnConvAddrTypeToDiscType(item->device->addr[0].type) == LnnConvAddrTypeToDiscType(type)) {
319             return item;
320         }
321     }
322     return NULL;
323 }
324 
HbIsRepeatedRecvInfo(LnnHeartbeatType hbType,const LnnHeartbeatRecvInfo * storedInfo,DeviceInfo * device,uint64_t nowTime)325 static bool HbIsRepeatedRecvInfo(
326     LnnHeartbeatType hbType, const LnnHeartbeatRecvInfo *storedInfo, DeviceInfo *device, uint64_t nowTime)
327 {
328     if (storedInfo == NULL) {
329         return false;
330     }
331     if (nowTime - storedInfo->lastRecvTime >= HbGetRepeatThresholdByType(hbType)) {
332         return false;
333     }
334     if (!storedInfo->device->isOnline && device->isOnline) {
335         return false;
336     }
337     return true;
338 }
339 
HbIsRepeatedJoinLnnRequest(LnnHeartbeatRecvInfo * storedInfo,uint64_t nowTime)340 static bool HbIsRepeatedJoinLnnRequest(LnnHeartbeatRecvInfo *storedInfo, uint64_t nowTime)
341 {
342     if (storedInfo == NULL) {
343         return false;
344     }
345     if (nowTime - storedInfo->lastJoinLnnTime < HB_REPEAD_JOIN_LNN_THRESHOLD) {
346         char *anonyUdid = NULL;
347         Anonymize(storedInfo->device->devId, &anonyUdid);
348         LNN_LOGD(LNN_HEART_BEAT, "recv but ignore repeated join lnn request, udidHash=%{public}s", anonyUdid);
349         AnonymizeFree(anonyUdid);
350         return true;
351     }
352     storedInfo->lastJoinLnnTime = nowTime;
353     return false;
354 }
355 
HbIsNeedReAuth(const NodeInfo * nodeInfo,const char * newAccountHash)356 static bool HbIsNeedReAuth(const NodeInfo *nodeInfo, const char *newAccountHash)
357 {
358     char *anonyNetworkId = NULL;
359     Anonymize(nodeInfo->networkId, &anonyNetworkId);
360     LNN_LOGI(LNN_HEART_BEAT,
361         "peer networkId=%{public}s, accountHash:%{public}02X%{public}02X->%{public}02X%{public}02X", anonyNetworkId,
362         nodeInfo->accountHash[0], nodeInfo->accountHash[1], newAccountHash[0], newAccountHash[1]);
363     AnonymizeFree(anonyNetworkId);
364     return memcmp(nodeInfo->accountHash, newAccountHash, HB_SHORT_ACCOUNT_HASH_LEN) != 0;
365 }
366 
HbDumpRecvDeviceInfo(const DeviceInfo * device,int32_t weight,int32_t masterWeight,LnnHeartbeatType hbType,uint64_t nowTime)367 static void HbDumpRecvDeviceInfo(
368     const DeviceInfo *device, int32_t weight, int32_t masterWeight, LnnHeartbeatType hbType, uint64_t nowTime)
369 {
370     char *anonyUdid = NULL;
371     const char *devTypeStr = LnnConvertIdToDeviceType((uint16_t)device->devType);
372     Anonymize(device->devId, &anonyUdid);
373     LNN_LOGI(LNN_HEART_BEAT,
374         "heartbeat(HB) OnTock, udidHash=%{public}s, accountHash=%{public}02X%{public}02X, hbType=%{public}d, "
375         "devTypeStr=%{public}s, peerWeight=%{public}d, masterWeight=%{public}d, devTypeHex=%{public}02X, "
376         "ConnectionAddrType=%{public}d, nowTime=%{public}" PRIu64,
377         anonyUdid, device->accountHash[0], device->accountHash[1], hbType, devTypeStr != NULL ? devTypeStr : "", weight,
378         masterWeight, device->devType, device->addr[0].type, nowTime);
379     AnonymizeFree(anonyUdid);
380 }
381 
IsLocalSupportBleDirectOnline()382 static bool IsLocalSupportBleDirectOnline()
383 {
384     uint64_t localFeatureCap = 0;
385     if (LnnGetLocalNumU64Info(NUM_KEY_FEATURE_CAPA, &localFeatureCap) != SOFTBUS_OK) {
386         LNN_LOGW(LNN_HEART_BEAT, "build ble broadcast, get local feature cap failed");
387         return false;
388     }
389     if ((localFeatureCap & (1 << BIT_BLE_DIRECT_ONLINE)) == 0) {
390         return false;
391     }
392     return true;
393 }
394 
IsLocalSupportThreeState()395 static bool IsLocalSupportThreeState()
396 {
397     uint64_t localFeatureCap = 0;
398     if (LnnGetLocalNumU64Info(NUM_KEY_FEATURE_CAPA, &localFeatureCap) != SOFTBUS_OK) {
399         LNN_LOGW(LNN_HEART_BEAT, "build ble broadcast, get local feature cap failed");
400         return false;
401     }
402     if ((localFeatureCap & (1 << BIT_SUPPORT_THREE_STATE)) == 0) {
403         return false;
404     }
405     return true;
406 }
407 
SetDeviceNetCapability(uint32_t * deviceInfoNetCapacity,HbRespData * hbResp)408 static void SetDeviceNetCapability(uint32_t *deviceInfoNetCapacity, HbRespData *hbResp)
409 {
410     uint32_t oldNetCapa = *deviceInfoNetCapacity;
411     if ((hbResp->capabiltiy & ENABLE_WIFI_CAP) != 0) {
412         (void)LnnSetNetCapability(deviceInfoNetCapacity, BIT_WIFI);
413     } else {
414         (void)LnnClearNetCapability(deviceInfoNetCapacity, BIT_WIFI);
415         (void)LnnClearNetCapability(deviceInfoNetCapacity, BIT_WIFI_5G);
416         (void)LnnClearNetCapability(deviceInfoNetCapacity, BIT_WIFI_24G);
417     }
418     if ((hbResp->capabiltiy & DISABLE_BR_CAP) != 0) {
419         (void)LnnClearNetCapability(deviceInfoNetCapacity, BIT_BR);
420     } else {
421         (void)LnnSetNetCapability(deviceInfoNetCapacity, BIT_BR);
422     }
423     if ((hbResp->capabiltiy & P2P_GO) != 0 || (hbResp->capabiltiy & P2P_GC)) {
424         (void)LnnSetNetCapability(deviceInfoNetCapacity, BIT_WIFI_P2P);
425     } else {
426         (void)LnnClearNetCapability(deviceInfoNetCapacity, BIT_WIFI_P2P);
427     }
428     (void)LnnSetNetCapability(deviceInfoNetCapacity, BIT_BLE);
429     LNN_LOGI(LNN_HEART_BEAT, "capability change:%{public}u->%{public}u", oldNetCapa, *deviceInfoNetCapacity);
430 }
431 
SetDeviceScreenStatus(NodeInfo * nodeInfo,bool isScreenOn)432 static int32_t SetDeviceScreenStatus(NodeInfo *nodeInfo, bool isScreenOn)
433 {
434     if (nodeInfo == NULL) {
435         LNN_LOGE(LNN_HEART_BEAT, "nodeInfo is null");
436         return SOFTBUS_INVALID_PARAM;
437     }
438     nodeInfo->isScreenOn = isScreenOn;
439     char *anonyDeviceUdid = NULL;
440     Anonymize(nodeInfo->deviceInfo.deviceUdid, &anonyDeviceUdid);
441     LNN_LOGI(LNN_HEART_BEAT, "udid=%{public}s, prepare to set screen status to %{public}s from hbResp",
442         AnonymizeWrapper(anonyDeviceUdid), isScreenOn ? "on" : "off");
443     AnonymizeFree(anonyDeviceUdid);
444     return SOFTBUS_OK;
445 }
446 
IsStateVersionChanged(const HbRespData * hbResp,const NodeInfo * deviceInfo,int32_t * stateVersion,ConnectOnlineReason * connectReason)447 static bool IsStateVersionChanged(
448     const HbRespData *hbResp, const NodeInfo *deviceInfo, int32_t *stateVersion, ConnectOnlineReason *connectReason)
449 {
450     if (LnnGetLocalNumInfo(NUM_KEY_STATE_VERSION, stateVersion) == SOFTBUS_OK &&
451         *stateVersion != deviceInfo->localStateVersion) {
452         *connectReason = LOCAL_STATE_VERSION_CHANGED;
453         LNN_LOGI(LNN_HEART_BEAT, "don't support ble direct online because local stateVersion=%{public}d->%{public}d",
454             deviceInfo->localStateVersion, *stateVersion);
455         return true;
456     }
457     if ((int32_t)hbResp->stateVersion != deviceInfo->stateVersion) {
458         *connectReason = PEER_STATE_VERSION_CHANGED;
459         LNN_LOGI(LNN_HEART_BEAT, "don't support ble direct online because peer stateVersion=%{public}d->%{public}d",
460             deviceInfo->stateVersion, (int32_t)hbResp->stateVersion);
461         return true;
462     }
463     return false;
464 }
465 
IsInvalidBrmac(const char * macAddr)466 static bool IsInvalidBrmac(const char *macAddr)
467 {
468     if (strlen(macAddr) == 0) {
469         LNN_LOGE(LNN_HEART_BEAT, "macAddr is null");
470         return true;
471     }
472     if (strcmp(macAddr, INVALID_BR_MAC_ADDR) == 0) {
473         LNN_LOGE(LNN_HEART_BEAT, "macAddr is invalid");
474         return true;
475     }
476     return false;
477 }
478 
IsUuidChange(const char * oldUuid,const HbRespData * hbResp,uint32_t len)479 static bool IsUuidChange(const char *oldUuid, const HbRespData *hbResp, uint32_t len)
480 {
481     char zeroUuid[UUID_BUF_LEN] = { 0 };
482     uint8_t uuidHash[SHA_256_HASH_LEN] = { 0 };
483 
484     if (oldUuid == NULL || hbResp == NULL) {
485         LNN_LOGD(LNN_HEART_BEAT, "invalid param");
486         return false;
487     }
488     if (memcmp(zeroUuid, hbResp->shortUuid, len) == 0) {
489         LNN_LOGD(LNN_HEART_BEAT, "ignore zero uuid");
490         return false;
491     }
492     if (SoftBusGenerateStrHash((const unsigned char *)oldUuid, strlen(oldUuid), (unsigned char *)uuidHash) !=
493         SOFTBUS_OK) {
494         LNN_LOGE(LNN_HEART_BEAT, "gen uuid hash err");
495         return false;
496     }
497     if (memcmp(uuidHash, hbResp->shortUuid, len) != 0) {
498         LNN_LOGE(LNN_HEART_BEAT,
499             "don't support ble direct online because uuid change %{public}02x%{public}02x->%{public}02x%{public}02x",
500             uuidHash[0], uuidHash[1], (hbResp->shortUuid)[0], (hbResp->shortUuid)[1]);
501         return true;
502     }
503     return false;
504 }
505 
IsNeedConnectOnLine(DeviceInfo * device,HbRespData * hbResp,ConnectOnlineReason * connectReason)506 static bool IsNeedConnectOnLine(DeviceInfo *device, HbRespData *hbResp, ConnectOnlineReason *connectReason)
507 {
508     if (hbResp == NULL || hbResp->stateVersion == STATE_VERSION_INVALID) {
509         LNN_LOGI(LNN_HEART_BEAT, "don't support ble direct online because resp data");
510         return true;
511     }
512     int32_t ret, stateVersion;
513     NodeInfo deviceInfo;
514     (void)memset_s(&deviceInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
515     if (!IsLocalSupportBleDirectOnline()) {
516         LNN_LOGI(LNN_HEART_BEAT, "ble don't support ble direct online");
517         return true;
518     }
519     if (LnnRetrieveDeviceInfo(device->devId, &deviceInfo) != SOFTBUS_OK ||
520         IsInvalidBrmac(deviceInfo.connectInfo.macAddr)) {
521         *connectReason = BLE_FIRST_CONNECT;
522         LNN_LOGI(LNN_HEART_BEAT, "don't support ble direct online because retrieve fail, "
523             "stateVersion=%{public}d->%{public}d", deviceInfo.stateVersion, (int32_t)hbResp->stateVersion);
524         return true;
525     }
526     if (IsStateVersionChanged(hbResp, &deviceInfo, &stateVersion, connectReason)) {
527         LNN_LOGI(LNN_HEART_BEAT, "don't support ble direct online because state version change");
528         return true;
529     }
530     AuthDeviceKeyInfo keyInfo = { 0 };
531     if ((!IsCloudSyncEnabled() || !IsFeatureSupport(deviceInfo.feature, BIT_CLOUD_SYNC_DEVICE_INFO)) &&
532         AuthFindDeviceKey(device->devId, AUTH_LINK_TYPE_BLE, &keyInfo) != SOFTBUS_OK &&
533         AuthFindLatestNormalizeKey(device->devId, &keyInfo, true) != SOFTBUS_OK) {
534         *connectReason = DEVICEKEY_NOT_EXISTED;
535         LNN_LOGE(LNN_HEART_BEAT, "don't support ble direct online because key not exist");
536         return true;
537     }
538     (void)memset_s(&keyInfo, sizeof(AuthDeviceKeyInfo), 0, sizeof(AuthDeviceKeyInfo));
539     SetDeviceNetCapability(&deviceInfo.netCapacity, hbResp);
540     (void)SetDeviceScreenStatus(&deviceInfo, hbResp->isScreenOn);
541     if ((ret = LnnUpdateRemoteDeviceInfo(&deviceInfo)) != SOFTBUS_OK) {
542         *connectReason = UPDATE_REMOTE_DEVICE_INFO_FAILED;
543         LNN_LOGE(LNN_HEART_BEAT, "don't support ble direct online because update device info fail ret=%{public}d", ret);
544         return true;
545     }
546     if ((deviceInfo.deviceInfo.osType == OH_OS_TYPE) && (!IsCipherManagerFindKey(deviceInfo.deviceInfo.deviceUdid))) {
547         *connectReason = FIND_REMOTE_CIPHERKEY_FAILED;
548         LNN_LOGE(LNN_HEART_BEAT, "don't support ble direct online because broadcast key");
549         return true;
550     }
551     if (IsUuidChange(deviceInfo.uuid, hbResp, HB_SHORT_UUID_LEN)) {
552         return true;
553     }
554     LNN_LOGI(LNN_HEART_BEAT, "support ble direct online");
555     return false;
556 }
557 
HbIsRepeatedReAuthRequest(LnnHeartbeatRecvInfo * storedInfo,uint64_t nowTime)558 static bool HbIsRepeatedReAuthRequest(LnnHeartbeatRecvInfo *storedInfo, uint64_t nowTime)
559 {
560     if (storedInfo == NULL) {
561         return false;
562     }
563     if (nowTime - storedInfo->lastJoinLnnTime < HB_REAUTH_TIME) {
564         return true;
565     }
566     storedInfo->lastJoinLnnTime = nowTime;
567     return false;
568 }
569 
HbIsValidJoinLnnRequest(DeviceInfo * device,HbRespData * hbResp)570 static bool HbIsValidJoinLnnRequest(DeviceInfo *device, HbRespData *hbResp)
571 {
572     NodeInfo nodeInfo;
573     (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
574     if (!IsLocalSupportThreeState()) {
575         LNN_LOGI(LNN_HEART_BEAT, "local don't support three state");
576         return true;
577     }
578     if (LnnRetrieveDeviceInfo(device->devId, &nodeInfo) != SOFTBUS_OK) {
579         LNN_LOGI(LNN_HEART_BEAT, "retrieve device info failed");
580         return true;
581     }
582     if ((nodeInfo.feature & (1 << BIT_SUPPORT_THREE_STATE)) == 0 && SoftBusGetBrState() == BR_DISABLE) {
583         char *anonyUdid = NULL;
584         Anonymize(device->devId, &anonyUdid);
585         LNN_LOGI(LNN_HEART_BEAT, "peer udidHash=%{public}s don't support three state and local br off", anonyUdid);
586         AnonymizeFree(anonyUdid);
587         return false;
588     }
589     return true;
590 }
591 
GetNowTime()592 static uint64_t GetNowTime()
593 {
594     SoftBusSysTime times = { 0 };
595     SoftBusGetTime(&times);
596     return (uint64_t)times.sec * HB_TIME_FACTOR + (uint64_t)times.usec / HB_TIME_FACTOR;
597 }
598 
CopyBleReportExtra(const LnnBleReportExtra * bleExtra,LnnEventExtra * extra)599 static void CopyBleReportExtra(const LnnBleReportExtra *bleExtra, LnnEventExtra *extra)
600 {
601     if (bleExtra == NULL || extra == NULL) {
602         LNN_LOGE(LNN_HEART_BEAT, "invalid param");
603         return;
604     }
605 
606     extra->onlineNum = bleExtra->extra.onlineNum;
607     extra->errcode = bleExtra->extra.errcode;
608     extra->lnnType = bleExtra->extra.lnnType;
609     extra->result = bleExtra->extra.result;
610     extra->localUdidHash = bleExtra->extra.localUdidHash;
611     extra->peerUdidHash = bleExtra->extra.peerUdidHash;
612     extra->osType = bleExtra->extra.osType;
613     extra->localDeviceType = bleExtra->extra.localDeviceType;
614     extra->peerDeviceType = bleExtra->extra.peerDeviceType;
615     extra->connOnlineReason = bleExtra->extra.connOnlineReason;
616     if (bleExtra->extra.peerNetworkId[0] != '\0') {
617         extra->onlineType = bleExtra->extra.onlineType;
618         extra->peerNetworkId = bleExtra->extra.peerNetworkId;
619         extra->peerUdid = bleExtra->extra.peerUdid;
620         extra->peerBleMac = bleExtra->extra.peerBleMac;
621     }
622 }
623 
HbProcessDfxMessage(void * para)624 static void HbProcessDfxMessage(void *para)
625 {
626     if (para == NULL) {
627         LNN_LOGE(LNN_HEART_BEAT, "invalid para");
628         return;
629     }
630     LnnBleReportExtra bleExtra;
631     (void)memset_s(&bleExtra, sizeof(LnnBleReportExtra), 0, sizeof(LnnBleReportExtra));
632     if (GetNodeFromLnnBleReportExtraMap((char *)para, &bleExtra) != SOFTBUS_OK) {
633         LNN_LOGE(LNN_HEART_BEAT, "get ble report node from lnnBleReportExtraMap fail");
634         SoftBusFree(para);
635         return;
636     }
637     if (bleExtra.status == BLE_REPORT_EVENT_SUCCESS || bleExtra.status == BLE_REPORT_EVENT_INIT) {
638         DeleteNodeFromLnnBleReportExtraMap((char *)para);
639         SoftBusFree(para);
640         return;
641     }
642     LnnEventExtra extra = { 0 };
643     LnnEventExtraInit(&extra);
644     CopyBleReportExtra(&bleExtra, &extra);
645     LNN_EVENT(EVENT_SCENE_JOIN_LNN, EVENT_STAGE_JOIN_LNN_END, extra);
646     LNN_LOGI(LNN_HEART_BEAT, "the device online failed within 7 seconds.");
647     DeleteNodeFromLnnBleReportExtraMap((char *)para);
648     SoftBusFree(para);
649 }
650 
HbAddAsyncProcessCallbackDelay(DeviceInfo * device,bool * IsRestrict)651 static int32_t HbAddAsyncProcessCallbackDelay(DeviceInfo *device, bool *IsRestrict)
652 {
653     if (device == NULL) {
654         LNN_LOGE(LNN_HEART_BEAT, "invalid param");
655         return SOFTBUS_INVALID_PARAM;
656     }
657     int32_t ret = SOFTBUS_OK;
658     LnnBleReportExtra bleExtra;
659     (void)memset_s(&bleExtra, sizeof(LnnBleReportExtra), 0, sizeof(LnnBleReportExtra));
660     if (device->addr[0].type == CONNECTION_ADDR_BLE) {
661         char *udidHash = (char *)SoftBusCalloc(SHORT_UDID_HASH_HEX_LEN + 1);
662         if (udidHash == NULL) {
663             LNN_LOGE(LNN_HEART_BEAT, "udidHash calloc fail");
664             return SOFTBUS_MALLOC_ERR;
665         }
666         ret = ConvertBytesToHexString(
667             udidHash, SHORT_UDID_HASH_HEX_LEN + 1, device->addr[0].info.ble.udidHash, SHORT_UDID_HASH_LEN);
668         if (ret != SOFTBUS_OK) {
669             LNN_LOGE(LNN_HEART_BEAT, "convert bytes to string fail");
670             SoftBusFree(udidHash);
671             return ret;
672         }
673         uint32_t count = 0;
674         if (GetNodeFromPcRestrictMap(udidHash, &count) == SOFTBUS_OK && count == PC_RESTRICT_TIME) {
675             LNN_LOGI(LNN_HEART_BEAT, "restrict pc");
676             *IsRestrict = true;
677         }
678         if (!IsExistLnnDfxNodeByUdidHash(udidHash, &bleExtra)) {
679             ret = LnnAsyncCallbackDelayHelper(
680                 GetLooper(LOOP_TYPE_DEFAULT), HbProcessDfxMessage, (void *)udidHash, HB_DFX_DELAY_TIME);
681             if (ret != SOFTBUS_OK) {
682                 LNN_LOGE(LNN_HEART_BEAT, "HbProcessDfxMessage failed, due to set async callback fail");
683                 SoftBusFree(udidHash);
684                 return ret;
685             }
686             bleExtra.status = BLE_REPORT_EVENT_INIT;
687             AddNodeToLnnBleReportExtraMap(udidHash, &bleExtra);
688             // udidHash will free When the callback function HbProcessDfxMessage is started.
689             return SOFTBUS_OK;
690         }
691         SoftBusFree(udidHash);
692     }
693     return SOFTBUS_OK;
694 }
695 
ProcessUdidAnonymize(char * devId)696 static void ProcessUdidAnonymize(char *devId)
697 {
698     char *anonyUdid = NULL;
699     Anonymize(devId, &anonyUdid);
700     LNN_LOGD(LNN_HEART_BEAT, "recv but ignore repeated join lnn request, udidHash=%{public}s",
701         AnonymizeWrapper(anonyUdid));
702     AnonymizeFree(anonyUdid);
703 }
704 
SoftBusNetNodeResult(DeviceInfo * device,HbRespData * hbResp,LnnConnectCondition * connectCondition,LnnHeartbeatRecvInfo * storedInfo,uint64_t nowTime)705 static int32_t SoftBusNetNodeResult(DeviceInfo *device, HbRespData *hbResp,
706     LnnConnectCondition *connectCondition, LnnHeartbeatRecvInfo *storedInfo, uint64_t nowTime)
707 {
708     char *anonyUdid = NULL;
709     Anonymize(device->devId, &anonyUdid);
710     LNN_LOGI(LNN_HEART_BEAT,
711         "heartbeat(HB) find device, udidHash=%{public}s, ConnectionAddrType=%{public}02X, isConnect=%{public}d, "
712         "connectReason=%{public}u",
713         anonyUdid, device->addr[0].type, connectCondition->isConnect, connectCondition->connectReason);
714     AnonymizeFree(anonyUdid);
715 
716     LnnDfxDeviceInfoReport info;
717     (void)memset_s(&info, sizeof(LnnDfxDeviceInfoReport), 0, sizeof(LnnDfxDeviceInfoReport));
718     if (hbResp != NULL) {
719         info.osType = ((hbResp->capabiltiy & BLE_TRIGGER_HML) != 0) ? OH_OS_TYPE : HO_OS_TYPE;
720     } else {
721         info.osType = HO_OS_TYPE;
722     }
723     info.type = device->devType;
724     info.bleConnectReason = connectCondition->connectReason;
725     bool IsRestrict = false;
726     if (HbAddAsyncProcessCallbackDelay(device, &IsRestrict) != SOFTBUS_OK) {
727         LNN_LOGE(LNN_HEART_BEAT, "HbAddAsyncProcessCallbackDelay fail");
728     }
729     if (IsRestrict) {
730         return SOFTBUS_NETWORK_PC_RESTRICT;
731     }
732     if (HbIsRepeatedJoinLnnRequest(storedInfo, nowTime)) {
733         ProcessUdidAnonymize(device->devId);
734         return SOFTBUS_NETWORK_HEARTBEAT_REPEATED;
735     }
736     if (LnnNotifyDiscoveryDevice(device->addr, &info, connectCondition->isConnect) != SOFTBUS_OK) {
737         LNN_LOGE(LNN_HEART_BEAT, "mgr recv process notify device found fail");
738         return SOFTBUS_ERR;
739     }
740     if (connectCondition->isConnect) {
741         return SOFTBUS_NETWORK_NODE_OFFLINE;
742     } else {
743         return SOFTBUS_NETWORK_NODE_DIRECT_ONLINE;
744     }
745 }
746 
DfxRecordHeartBeatAuthStart(const AuthConnInfo * connInfo,const char * packageName,uint32_t requestId)747 static void DfxRecordHeartBeatAuthStart(const AuthConnInfo *connInfo, const char *packageName, uint32_t requestId)
748 {
749     LnnEventExtra extra = { 0 };
750     LnnEventExtraInit(&extra);
751     extra.authRequestId = (int32_t)requestId;
752 
753     if (connInfo != NULL) {
754         extra.authLinkType = connInfo->type;
755     }
756     char pkgName[PKG_NAME_SIZE_MAX] = { 0 };
757     if (packageName != NULL && IsValidString(packageName, PKG_NAME_SIZE_MAX - 1) &&
758         strncpy_s(pkgName, PKG_NAME_SIZE_MAX, packageName, PKG_NAME_SIZE_MAX - 1) == EOK) {
759         extra.callerPkg = pkgName;
760     }
761     LNN_EVENT(EVENT_SCENE_JOIN_LNN, EVENT_STAGE_AUTH, extra);
762 }
763 
HbOnlineNodeAuth(DeviceInfo * device,LnnHeartbeatRecvInfo * storedInfo,uint64_t nowTime)764 static int32_t HbOnlineNodeAuth(DeviceInfo *device, LnnHeartbeatRecvInfo *storedInfo, uint64_t nowTime)
765 {
766     if (!device->isOnline) {
767         LNN_LOGW(LNN_HEART_BEAT, "ignore lnn request, not support connect");
768         return SOFTBUS_OK;
769     }
770     if (HbIsRepeatedReAuthRequest(storedInfo, nowTime)) {
771         LNN_LOGE(LNN_HEART_BEAT, "reauth request repeated");
772         return SOFTBUS_NETWORK_HEARTBEAT_REPEATED;
773     }
774     AuthConnInfo authConn;
775     uint32_t requestId = AuthGenRequestId();
776     (void)LnnConvertAddrToAuthConnInfo(device->addr, &authConn);
777     DfxRecordHeartBeatAuthStart(&authConn, LNN_DEFAULT_PKG_NAME, requestId);
778     if (AuthStartVerify(&authConn, requestId, LnnGetReAuthVerifyCallback(), AUTH_MODULE_LNN, false) != SOFTBUS_OK) {
779         LNN_LOGI(LNN_HEART_BEAT, "AuthStartVerify error");
780         return SOFTBUS_ERR;
781     }
782     return SOFTBUS_OK;
783 }
784 
HbSuspendReAuth(DeviceInfo * device)785 static int32_t HbSuspendReAuth(DeviceInfo *device)
786 {
787     if (device->addr[0].type == CONNECTION_ADDR_BLE) {
788         char udidHash[SHORT_UDID_HASH_HEX_LEN + 1] = { 0 };
789         if (ConvertBytesToUpperCaseHexString(udidHash, SHORT_UDID_HASH_HEX_LEN + 1, device->addr[0].info.ble.udidHash,
790                 SHORT_UDID_HASH_LEN) != SOFTBUS_OK) {
791             LNN_LOGE(LNN_HEART_BEAT, "convert bytes to string fail");
792             return SOFTBUS_ERR;
793         }
794         if (IsNeedAuthLimit(udidHash)) {
795             char *anonyUdidHash = NULL;
796             Anonymize(udidHash, &anonyUdidHash);
797             LNN_LOGI(LNN_HEART_BEAT, "current device need delay authentication, type=%{public}d, udidHash=%{public}s",
798                 device->addr[0].type, anonyUdidHash);
799             AnonymizeFree(anonyUdidHash);
800             return SOFTBUS_NETWORK_BLE_CONNECT_SUSPEND;
801         }
802     }
803     return SOFTBUS_OK;
804 }
805 
CheckReceiveDeviceInfo(DeviceInfo * device,LnnHeartbeatType hbType,const LnnHeartbeatRecvInfo * storedInfo,uint64_t nowTime)806 static int32_t CheckReceiveDeviceInfo(
807     DeviceInfo *device, LnnHeartbeatType hbType, const LnnHeartbeatRecvInfo *storedInfo, uint64_t nowTime)
808 {
809     if (HbIsRepeatedRecvInfo(hbType, storedInfo, device, nowTime)) {
810         LNN_LOGD(LNN_HEART_BEAT, "repeat receive info");
811         return SOFTBUS_NETWORK_HEARTBEAT_REPEATED;
812     }
813     if (HbSuspendReAuth(device) == SOFTBUS_NETWORK_BLE_CONNECT_SUSPEND) {
814         return SOFTBUS_NETWORK_BLE_CONNECT_SUSPEND;
815     }
816     return SOFTBUS_OK;
817 }
818 
CheckJoinLnnRequest(DeviceInfo * device,HbRespData * hbResp)819 static int32_t CheckJoinLnnRequest(DeviceInfo *device, HbRespData *hbResp)
820 {
821     if (!HbIsValidJoinLnnRequest(device, hbResp)) {
822         return SOFTBUS_NETWORK_JOIN_REQUEST_ERR;
823     }
824     return SOFTBUS_OK;
825 }
826 
ProcRespVapChange(DeviceInfo * device,HbRespData * hbResp)827 static void ProcRespVapChange(DeviceInfo *device, HbRespData *hbResp)
828 {
829     if (device == NULL || hbResp == NULL) {
830         LNN_LOGD(LNN_HEART_BEAT, "param is nullptr");
831         return;
832     }
833     int32_t infoNum = 0;
834     NodeBasicInfo *info = NULL;
835     char udidHash[HB_SHORT_UDID_HASH_HEX_LEN + 1] = {0};
836     int32_t ret = LnnGetAllOnlineNodeInfo(&info, &infoNum);
837     if (ret != SOFTBUS_OK) {
838         LNN_LOGE(LNN_HEART_BEAT, "get all online node info fail");
839         return;
840     }
841     if (info == NULL) {
842         LNN_LOGD(LNN_HEART_BEAT, "online info is null");
843         return;
844     }
845     if (infoNum == 0) {
846         LNN_LOGW(LNN_HEART_BEAT, "none online node");
847         SoftBusFree(info);
848         return;
849     }
850     NodeInfo nodeInfo;
851     (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
852     for (int32_t i = 0; i < infoNum; ++i) {
853         if (LnnGetRemoteNodeInfoById(info[i].networkId, CATEGORY_NETWORK_ID, &nodeInfo) != SOFTBUS_OK) {
854             LNN_LOGD(LNN_HEART_BEAT, "get nodeInfo fail");
855             continue;
856         }
857         if (LnnGenerateHexStringHash((const unsigned char *)nodeInfo.deviceInfo.deviceUdid, udidHash,
858             HB_SHORT_UDID_HASH_HEX_LEN) != SOFTBUS_OK) {
859             continue;
860         }
861         if (strncmp(udidHash, device->devId, HB_SHORT_UDID_HASH_HEX_LEN) == 0) {
862             LNN_LOGD(LNN_HEART_BEAT, "hbResp preChannelCode=%{public}d", hbResp->preferChannel);
863             (void)LnnAddRemoteChannelCode(nodeInfo.deviceInfo.deviceUdid, hbResp->preferChannel);
864             SoftBusFree(info);
865             return;
866         }
867     }
868     SoftBusFree(info);
869 }
870 
IsSupportCloudSync(DeviceInfo * device)871 static bool IsSupportCloudSync(DeviceInfo *device)
872 {
873     NodeInfo info;
874     (void)memset_s(&info, sizeof(NodeInfo), 0, sizeof(NodeInfo));
875     uint64_t localFeature = 0;
876     if (LnnRetrieveDeviceInfo(device->devId, &info) != SOFTBUS_OK) {
877         LNN_LOGE(LNN_HEART_BEAT, "don't support cloud sync beacause retrive info fail");
878         return false;
879     }
880     if (LnnGetLocalNumU64Info(NUM_KEY_FEATURE_CAPA, &localFeature) != SOFTBUS_OK) {
881         LNN_LOGE(LNN_HEART_BEAT, "don't support cloud sync beacause get local feature fail");
882         return false;
883     }
884     return IsFeatureSupport(localFeature, BIT_CLOUD_SYNC_DEVICE_INFO) &&
885         IsFeatureSupport(info.feature, BIT_CLOUD_SYNC_DEVICE_INFO);
886 }
887 
CheckJoinLnnConnectResult(DeviceInfo * device,HbRespData * hbResp,LnnHeartbeatRecvInfo * storedInfo,uint64_t nowTime)888 static int32_t CheckJoinLnnConnectResult(
889     DeviceInfo *device, HbRespData *hbResp, LnnHeartbeatRecvInfo *storedInfo, uint64_t nowTime)
890 {
891     LnnConnectCondition connectCondition;
892     int32_t res = CheckJoinLnnRequest(device, hbResp);
893     if (res != SOFTBUS_OK) {
894         return res;
895     }
896     connectCondition.connectReason = CONNECT_INITIAL_VALUE;
897     connectCondition.isConnect = IsNeedConnectOnLine(device, hbResp, &connectCondition.connectReason);
898     if (connectCondition.isConnect && !device->isOnline) {
899         if (IsSupportCloudSync(device)) {
900             return SOFTBUS_NETWORK_PEER_NODE_CONNECT;
901         }
902         return SOFTBUS_NETWORK_NOT_CONNECTABLE;
903     }
904     return SoftBusNetNodeResult(device, hbResp, &connectCondition, storedInfo, nowTime);
905 }
906 
HbNotifyReceiveDevice(DeviceInfo * device,const LnnHeartbeatWeight * mediumWeight,LnnHeartbeatType hbType,bool isOnlineDirectly,HbRespData * hbResp)907 static int32_t HbNotifyReceiveDevice(DeviceInfo *device, const LnnHeartbeatWeight *mediumWeight,
908     LnnHeartbeatType hbType, bool isOnlineDirectly, HbRespData *hbResp)
909 {
910     uint64_t nowTime = GetNowTime();
911     LNN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_hbRecvList->lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
912         LNN_HEART_BEAT, "try to lock failed");
913     LnnHeartbeatRecvInfo *storedInfo = HbGetStoredRecvInfo(device->devId, device->addr[0].type, nowTime);
914     int32_t res = CheckReceiveDeviceInfo(device, hbType, storedInfo, nowTime);
915     if (res != SOFTBUS_OK) {
916         (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
917         return res;
918     }
919     if (HbSaveRecvTimeToRemoveRepeat(
920         storedInfo, device, mediumWeight->weight, mediumWeight->localMasterWeight, nowTime) != SOFTBUS_OK) {
921         (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
922         return SOFTBUS_ERR;
923     }
924     if (isOnlineDirectly) {
925         (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
926         (void)HbUpdateOfflineTimingByRecvInfo(device->devId, device->addr[0].type, hbType, nowTime);
927         return SOFTBUS_NETWORK_HEARTBEAT_REPEATED;
928     }
929     HbDumpRecvDeviceInfo(device, mediumWeight->weight, mediumWeight->localMasterWeight, hbType, nowTime);
930     NodeInfo nodeInfo;
931     (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
932     if (HbGetOnlineNodeByRecvInfo(device->devId, device->addr[0].type, &nodeInfo, hbResp) == SOFTBUS_OK) {
933         if (!HbIsNeedReAuth(&nodeInfo, device->accountHash) &&
934             !IsUuidChange(nodeInfo.uuid, hbResp, HB_SHORT_UUID_LEN)) {
935             (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
936             return HbUpdateOfflineTimingByRecvInfo(nodeInfo.networkId, device->addr[0].type, hbType, nowTime);
937         }
938         int32_t ret = HbOnlineNodeAuth(device, storedInfo, nowTime);
939         (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
940         return ret;
941     }
942     res = CheckJoinLnnConnectResult(device, hbResp, storedInfo, nowTime);
943     (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
944     return res;
945 }
946 
HbMediumMgrRecvProcess(DeviceInfo * device,const LnnHeartbeatWeight * mediumWeight,LnnHeartbeatType hbType,bool isOnlineDirectly,HbRespData * hbResp)947 static int32_t HbMediumMgrRecvProcess(DeviceInfo *device, const LnnHeartbeatWeight *mediumWeight,
948     LnnHeartbeatType hbType, bool isOnlineDirectly, HbRespData *hbResp)
949 {
950     if (device == NULL || mediumWeight == NULL) {
951         LNN_LOGE(LNN_HEART_BEAT, "mgr recv process get invalid param");
952         return SOFTBUS_INVALID_PARAM;
953     }
954     if (!AuthIsPotentialTrusted(device)) {
955         char *anonyUdid = NULL;
956         Anonymize(device->devId, &anonyUdid);
957         LNN_LOGW(LNN_HEART_BEAT,
958             ">> heartbeat(HB) OnTock is not potential trusted, udid=%{public}s, accountHash=%{public}02X%{public}02X",
959             anonyUdid, device->accountHash[0], device->accountHash[1]);
960         AnonymizeFree(anonyUdid);
961         return SOFTBUS_NETWORK_HEARTBEAT_UNTRUSTED;
962     }
963     ProcRespVapChange(device, hbResp);
964     return HbNotifyReceiveDevice(device, mediumWeight, hbType, isOnlineDirectly, hbResp);
965 }
966 
HbMediumMgrRecvHigherWeight(const char * udidHash,int32_t weight,ConnectionAddrType type,bool isReElect,bool isPeerScreenOn)967 static int32_t HbMediumMgrRecvHigherWeight(
968     const char *udidHash, int32_t weight, ConnectionAddrType type, bool isReElect, bool isPeerScreenOn)
969 {
970     NodeInfo nodeInfo;
971     char masterUdid[UDID_BUF_LEN] = { 0 };
972     bool isFromMaster = false;
973 
974     if (udidHash == NULL) {
975         LNN_LOGE(LNN_HEART_BEAT, "mgr recv higher weight get invalid param");
976         return SOFTBUS_INVALID_PARAM;
977     }
978     (void)memset_s(&nodeInfo, sizeof(nodeInfo), 0, sizeof(nodeInfo));
979     if (HbGetOnlineNodeByRecvInfo(udidHash, type, &nodeInfo, NULL) != SOFTBUS_OK) {
980         char *anonyUdid = NULL;
981         Anonymize(udidHash, &anonyUdid);
982         LNN_LOGD(LNN_HEART_BEAT, "recv higher weight is not online yet. udidhash=%{public}s", anonyUdid);
983         AnonymizeFree(anonyUdid);
984         return SOFTBUS_OK;
985     }
986     if (LnnGetLocalStrInfo(STRING_KEY_MASTER_NODE_UDID, masterUdid, sizeof(masterUdid)) != SOFTBUS_OK) {
987         LNN_LOGE(LNN_HEART_BEAT, "get local master udid fail");
988         return SOFTBUS_ERR;
989     }
990     isFromMaster = strcmp(masterUdid, nodeInfo.deviceInfo.deviceUdid) == 0 ? true : false;
991     if (isReElect && !isFromMaster &&
992         LnnNotifyMasterElect(nodeInfo.networkId, nodeInfo.deviceInfo.deviceUdid, weight) != SOFTBUS_OK) {
993         LNN_LOGE(LNN_HEART_BEAT, "notify master elect fail");
994         return SOFTBUS_ERR;
995     }
996     if (isFromMaster && isPeerScreenOn) {
997         LnnSetHbAsMasterNodeState(false);
998     }
999     char *anonyUdid = NULL;
1000     Anonymize(udidHash, &anonyUdid);
1001     char *anonyMasterUdid = NULL;
1002     Anonymize(masterUdid, &anonyMasterUdid);
1003     LNN_LOGI(LNN_HEART_BEAT, "recv higher weight udidHash=%{public}s, weight=%{public}d, masterUdid=%{public}s",
1004         anonyUdid, weight, anonyMasterUdid);
1005     AnonymizeFree(anonyUdid);
1006     AnonymizeFree(anonyMasterUdid);
1007     return SOFTBUS_OK;
1008 }
1009 
HbMediumMgrRecvLpInfo(const char * networkId,uint64_t nowTime)1010 static void HbMediumMgrRecvLpInfo(const char *networkId, uint64_t nowTime)
1011 {
1012     if (HbUpdateOfflineTimingByRecvInfo(networkId, CONNECTION_ADDR_BLE, HEARTBEAT_TYPE_BLE_V4, nowTime) != SOFTBUS_OK) {
1013         LNN_LOGE(LNN_HEART_BEAT, "HB medium mgr update time stamp fail");
1014     }
1015 }
1016 
HbMediumMgrRelayProcess(const char * udidHash,ConnectionAddrType type,LnnHeartbeatType hbType)1017 static void HbMediumMgrRelayProcess(const char *udidHash, ConnectionAddrType type, LnnHeartbeatType hbType)
1018 {
1019     (void)type;
1020 
1021     if (udidHash == NULL) {
1022         LNN_LOGE(LNN_HEART_BEAT, "mgr relay get invalid param");
1023         return;
1024     }
1025     char *anonyUdid = NULL;
1026     Anonymize(udidHash, &anonyUdid);
1027     LNN_LOGD(LNN_HEART_BEAT, "mgr relay process, udidhash=%{public}s, hbType=%{public}d", anonyUdid, hbType);
1028     AnonymizeFree(anonyUdid);
1029     if (LnnStartHbByTypeAndStrategy(hbType | HEARTBEAT_TYPE_BLE_V3, STRATEGY_HB_SEND_SINGLE, true) != SOFTBUS_OK) {
1030         LNN_LOGE(LNN_HEART_BEAT, "mgr relay process fail");
1031         return;
1032     }
1033 }
1034 
HbInitRecvList(void)1035 static int32_t HbInitRecvList(void)
1036 {
1037     if (g_hbRecvList != NULL) {
1038         return SOFTBUS_OK;
1039     }
1040     g_hbRecvList = CreateSoftBusList();
1041     if (g_hbRecvList == NULL) {
1042         LNN_LOGE(LNN_INIT, "create recv list fail");
1043         return SOFTBUS_ERR;
1044     }
1045     g_hbRecvList->cnt = 0;
1046     return SOFTBUS_OK;
1047 }
1048 
HbDeinitRecvList(void)1049 static void HbDeinitRecvList(void)
1050 {
1051     LnnHeartbeatRecvInfo *item = NULL;
1052     LnnHeartbeatRecvInfo *nextItem = NULL;
1053 
1054     if (g_hbRecvList == NULL) {
1055         return;
1056     }
1057     if (SoftBusMutexLock(&g_hbRecvList->lock) != 0) {
1058         LNN_LOGE(LNN_INIT, "deinit recv list lock recv info list fail");
1059         return;
1060     }
1061     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_hbRecvList->list, LnnHeartbeatRecvInfo, node) {
1062         ListDelete(&item->node);
1063         SoftBusFree(item->device);
1064         SoftBusFree(item);
1065     }
1066     (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
1067     DestroySoftBusList(g_hbRecvList);
1068     g_hbRecvList = NULL;
1069 }
1070 
LnnHbClearRecvList(void)1071 void LnnHbClearRecvList(void)
1072 {
1073     LnnHeartbeatRecvInfo *item = NULL;
1074     LnnHeartbeatRecvInfo *nextItem = NULL;
1075 
1076     if (g_hbRecvList == NULL) {
1077         return;
1078     }
1079     if (SoftBusMutexLock(&g_hbRecvList->lock) != 0) {
1080         LNN_LOGE(LNN_HEART_BEAT, "deinit recv list lock recv info list fail");
1081         return;
1082     }
1083     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &g_hbRecvList->list, LnnHeartbeatRecvInfo, node) {
1084         ListDelete(&item->node);
1085         SoftBusFree(item->device);
1086         SoftBusFree(item);
1087     }
1088     g_hbRecvList->cnt = 0;
1089     (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
1090 }
1091 
LnnDumpHbMgrRecvList(void)1092 void LnnDumpHbMgrRecvList(void)
1093 {
1094 #define HB_DUMP_UPDATE_INFO_MAX_NUM 10
1095     int32_t dumpCount = 0;
1096     char *deviceType = NULL;
1097     LnnHeartbeatRecvInfo *item = NULL;
1098 
1099     if (SoftBusMutexLock(&g_hbRecvList->lock) != 0) {
1100         LNN_LOGE(LNN_HEART_BEAT, "dump recv list lock recv info list fail");
1101         return;
1102     }
1103     if (IsListEmpty(&g_hbRecvList->list)) {
1104         LNN_LOGD(LNN_HEART_BEAT, "DumpHbMgrRecvList count=0");
1105         (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
1106         return;
1107     }
1108     LIST_FOR_EACH_ENTRY(item, &g_hbRecvList->list, LnnHeartbeatRecvInfo, node) {
1109         char *anonyUdid = NULL;
1110         dumpCount++;
1111         if (dumpCount > HB_DUMP_UPDATE_INFO_MAX_NUM) {
1112             break;
1113         }
1114         deviceType = LnnConvertIdToDeviceType((uint16_t)item->device->devType);
1115         if (deviceType == NULL) {
1116             Anonymize(item->device->devId, &anonyUdid);
1117             LNN_LOGE(LNN_HEART_BEAT, "get deviceType fail, udidHash=%{public}s", anonyUdid);
1118             AnonymizeFree(anonyUdid);
1119             continue;
1120         }
1121         Anonymize(item->device->devId, &anonyUdid);
1122         LNN_LOGD(LNN_HEART_BEAT,
1123             "DumpRecvList count=%{public}d, i=%{public}d, udidHash=%{public}s, deviceType=%{public}s, "
1124             "ConnectionAddrType=%{public}02X, weight=%{public}d, masterWeight=%{public}d, "
1125             "lastRecvTime=%{public}" PRIu64,
1126             g_hbRecvList->cnt, dumpCount, anonyUdid, deviceType, item->device->addr[0].type, item->weight,
1127             item->masterWeight, item->lastRecvTime);
1128         AnonymizeFree(anonyUdid);
1129     }
1130     (void)SoftBusMutexUnlock(&g_hbRecvList->lock);
1131 }
1132 
LnnDumpHbOnlineNodeList(void)1133 void LnnDumpHbOnlineNodeList(void)
1134 {
1135 #define HB_DUMP_ONLINE_NODE_MAX_NUM 5
1136     int32_t i, infoNum;
1137     uint64_t oldTimeStamp;
1138     NodeBasicInfo *info = NULL;
1139 
1140     if (LnnGetAllOnlineNodeInfo(&info, &infoNum) != SOFTBUS_OK) {
1141         LNN_LOGE(LNN_HEART_BEAT, "get node info fail");
1142         return;
1143     }
1144     if (info == NULL || infoNum == 0) {
1145         LNN_LOGD(LNN_HEART_BEAT, "DumpHbOnlineNodeList count=0");
1146         return;
1147     }
1148     NodeInfo nodeInfo;
1149     (void)memset_s(&nodeInfo, sizeof(nodeInfo), 0, sizeof(nodeInfo));
1150     for (i = 0; i < infoNum; ++i) {
1151         if (i > HB_DUMP_ONLINE_NODE_MAX_NUM) {
1152             break;
1153         }
1154         if (LnnGetRemoteNodeInfoById(info[i].networkId, CATEGORY_NETWORK_ID, &nodeInfo) != SOFTBUS_OK) {
1155             continue;
1156         }
1157         if (LnnGetDLHeartbeatTimestamp(info[i].networkId, &oldTimeStamp) != SOFTBUS_OK) {
1158             LNN_LOGE(LNN_HEART_BEAT, "get timeStamp err, nodeInfo i=%{public}d", i);
1159             continue;
1160         }
1161         char *deviceTypeStr = LnnConvertIdToDeviceType(nodeInfo.deviceInfo.deviceTypeId);
1162         char *anonyDeviceName = NULL;
1163         Anonymize(nodeInfo.deviceInfo.deviceName, &anonyDeviceName);
1164         LNN_LOGD(LNN_HEART_BEAT,
1165             "DumpOnlineNodeList count=%{public}d, i=%{public}d, deviceName=%{public}s, deviceTypeId=%{public}d, "
1166             "deviceTypeStr=%{public}s, masterWeight=%{public}d, discoveryType=%{public}d, "
1167             "oldTimestamp=%{public}" PRIu64 "",
1168             infoNum, i + 1, anonyDeviceName, nodeInfo.deviceInfo.deviceTypeId,
1169             deviceTypeStr != NULL ? deviceTypeStr : "", nodeInfo.masterWeight, nodeInfo.discoveryType, oldTimeStamp);
1170         AnonymizeFree(anonyDeviceName);
1171     }
1172     SoftBusFree(info);
1173 }
1174 
LnnHbMediumMgrInit(void)1175 int32_t LnnHbMediumMgrInit(void)
1176 {
1177     if (LnnRegistBleHeartbeatMediumMgr() != SOFTBUS_OK) {
1178         LNN_LOGE(LNN_HEART_BEAT, "regist ble heartbeat manager fail");
1179         return SOFTBUS_ERR;
1180     }
1181     if (LnnRegisterBleLpDeviceMediumMgr() != SOFTBUS_OK) {
1182         LNN_LOGE(LNN_HEART_BEAT, "LP regist LpDevice manager fail");
1183         return SOFTBUS_ERR;
1184     }
1185     return HbInitRecvList();
1186 }
1187 
VisitHbMediumMgrSendBegin(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)1188 static bool VisitHbMediumMgrSendBegin(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
1189 {
1190     (void)typeSet;
1191     int32_t id, ret;
1192     LnnHeartbeatSendBeginData *custData = NULL;
1193 
1194     if (data == NULL) {
1195         LNN_LOGE(LNN_HEART_BEAT, "manager send once begin get invalid param");
1196         return false;
1197     }
1198     custData = (LnnHeartbeatSendBeginData *)data;
1199     custData->hbType = eachType;
1200     id = LnnConvertHbTypeToId(eachType);
1201     if (id == HB_INVALID_TYPE_ID) {
1202         LNN_LOGE(LNN_HEART_BEAT, "manager send once begin convert type fail");
1203         return false;
1204     }
1205     if (g_hbMeidumMgr[id] == NULL || (eachType & g_hbMeidumMgr[id]->supportType) == 0) {
1206         LNN_LOGW(LNN_HEART_BEAT, "not support heartbeat type=%{public}d", eachType);
1207         return true;
1208     }
1209     if (g_hbMeidumMgr[id]->onSendOneHbBegin == NULL) {
1210         LNN_LOGW(LNN_HEART_BEAT, "manager send once begin cb is NULL, type=%{public}d", eachType);
1211         return true;
1212     }
1213     ret = g_hbMeidumMgr[id]->onSendOneHbBegin(custData);
1214     if (ret != SOFTBUS_OK) {
1215         LNN_LOGE(LNN_HEART_BEAT, "send once begin fail, type=%{public}d, ret=%{public}d", eachType, ret);
1216         return false;
1217     }
1218     return true;
1219 }
1220 
LnnHbMediumMgrSendBegin(LnnHeartbeatSendBeginData * custData)1221 int32_t LnnHbMediumMgrSendBegin(LnnHeartbeatSendBeginData *custData)
1222 {
1223     if (custData == NULL) {
1224         return SOFTBUS_INVALID_PARAM;
1225     }
1226     if (!LnnVisitHbTypeSet(VisitHbMediumMgrSendBegin, &custData->hbType, custData)) {
1227         LNN_LOGE(LNN_HEART_BEAT, "manager hb send begin fail. hbType=%{public}d", custData->hbType);
1228         return SOFTBUS_ERR;
1229     }
1230     return SOFTBUS_OK;
1231 }
1232 
VisitHbMediumMgrSendEnd(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)1233 static bool VisitHbMediumMgrSendEnd(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
1234 {
1235     (void)typeSet;
1236     (void)data;
1237     int32_t id, ret;
1238     LnnHeartbeatSendEndData *custData = NULL;
1239 
1240     if (data == NULL) {
1241         LNN_LOGE(LNN_HEART_BEAT, "manager send once end get invalid param");
1242         return false;
1243     }
1244     if (eachType == HEARTBEAT_TYPE_BLE_V3) {
1245         LNN_LOGI(LNN_HEART_BEAT, "V3 don't stop");
1246         return true;
1247     }
1248     custData = (LnnHeartbeatSendEndData *)data;
1249     custData->hbType = eachType;
1250     id = LnnConvertHbTypeToId(eachType);
1251     if (id == HB_INVALID_TYPE_ID) {
1252         LNN_LOGE(LNN_HEART_BEAT, "manager stop one cycle convert type fail");
1253         return false;
1254     }
1255     if (g_hbMeidumMgr[id] == NULL || (eachType & g_hbMeidumMgr[id]->supportType) == 0) {
1256         LNN_LOGW(LNN_HEART_BEAT, "not support heartbeat type=%{public}d", eachType);
1257         return true;
1258     }
1259     if (g_hbMeidumMgr[id]->onSendOneHbEnd == NULL) {
1260         LNN_LOGW(LNN_HEART_BEAT, "manager send once end cb is NULL, type=%{public}d", eachType);
1261         return true;
1262     }
1263     ret = g_hbMeidumMgr[id]->onSendOneHbEnd(custData);
1264     if (ret != SOFTBUS_OK) {
1265         LNN_LOGE(LNN_HEART_BEAT, "stop one cycle hb fail, type=%{public}d, ret=%{public}d", eachType, ret);
1266         return false;
1267     }
1268     return true;
1269 }
1270 
LnnHbMediumMgrSendEnd(LnnHeartbeatSendEndData * custData)1271 int32_t LnnHbMediumMgrSendEnd(LnnHeartbeatSendEndData *custData)
1272 {
1273     if (!LnnVisitHbTypeSet(VisitHbMediumMgrSendEnd, &custData->hbType, custData)) {
1274         LNN_LOGE(LNN_HEART_BEAT, "manager hb send end fail. hbType=%{public}d", custData->hbType);
1275         return SOFTBUS_ERR;
1276     }
1277     return SOFTBUS_OK;
1278 }
1279 
VisitHbMediumMgrStop(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)1280 static bool VisitHbMediumMgrStop(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
1281 {
1282     (void)typeSet;
1283     (void)data;
1284     int32_t id, ret;
1285 
1286     id = LnnConvertHbTypeToId(eachType);
1287     if (id == HB_INVALID_TYPE_ID) {
1288         LNN_LOGE(LNN_HEART_BEAT, "stop heartbeat convert type fail");
1289         return false;
1290     }
1291     if (g_hbMeidumMgr[id] == NULL || (eachType & g_hbMeidumMgr[id]->supportType) == 0) {
1292         LNN_LOGW(LNN_HEART_BEAT, "not support heartbeat type=%{public}d", eachType);
1293         return true;
1294     }
1295     if (g_hbMeidumMgr[id]->onStopHbByType == NULL) {
1296         LNN_LOGW(LNN_HEART_BEAT, "manager stop cb is NULL, type=%{public}d", eachType);
1297         return true;
1298     }
1299     ret = g_hbMeidumMgr[id]->onStopHbByType();
1300     if (ret != SOFTBUS_OK) {
1301         LNN_LOGE(LNN_HEART_BEAT, "stop heartbeat fail, type=%{public}d, ret=%{public}d", eachType, ret);
1302         return false;
1303     }
1304     return true;
1305 }
1306 
LnnHbMediumMgrStop(LnnHeartbeatType * type)1307 int32_t LnnHbMediumMgrStop(LnnHeartbeatType *type)
1308 {
1309     if (!LnnVisitHbTypeSet(VisitHbMediumMgrStop, type, NULL)) {
1310         LNN_LOGE(LNN_HEART_BEAT, "manager stop fail. hbType=%{public}d", *type);
1311         return SOFTBUS_ERR;
1312     }
1313     return SOFTBUS_OK;
1314 }
1315 
LnnHbMediumMgrDeinit(void)1316 void LnnHbMediumMgrDeinit(void)
1317 {
1318     int32_t i;
1319 
1320     for (i = 0; i < HB_MAX_TYPE_COUNT; ++i) {
1321         /* HEARTBEAT_TYPE_BLE_V0 and HEARTBEAT_TYPE_BLE_V1 have the same medium manager. */
1322         if (i == LnnConvertHbTypeToId(HEARTBEAT_TYPE_BLE_V1)) {
1323             continue;
1324         }
1325         if (g_hbMeidumMgr[i] == NULL || g_hbMeidumMgr[i]->deinit == NULL) {
1326             continue;
1327         }
1328         g_hbMeidumMgr[i]->deinit();
1329         g_hbMeidumMgr[i] = NULL;
1330     }
1331     HbDeinitRecvList();
1332 }
1333 
LnnHbMediumMgrSetParam(void * param)1334 int32_t LnnHbMediumMgrSetParam(void *param)
1335 {
1336     int32_t id, ret;
1337 
1338     if (param == NULL) {
1339         LNN_LOGE(LNN_HEART_BEAT, "set medium param get invalid param");
1340         return SOFTBUS_INVALID_PARAM;
1341     }
1342     LnnHeartbeatMediumParam *mediumParam = (LnnHeartbeatMediumParam *)param;
1343     id = LnnConvertHbTypeToId(mediumParam->type);
1344     if (id == HB_INVALID_TYPE_ID) {
1345         LNN_LOGE(LNN_HEART_BEAT, "set medium param convert type fail");
1346         return SOFTBUS_ERR;
1347     }
1348     if (g_hbMeidumMgr[id] == NULL || g_hbMeidumMgr[id]->onSetMediumParam == NULL) {
1349         LNN_LOGW(LNN_HEART_BEAT, "not support heartbeat type=%{public}d", mediumParam->type);
1350         return SOFTBUS_NOT_IMPLEMENT;
1351     }
1352     ret = g_hbMeidumMgr[id]->onSetMediumParam((const LnnHeartbeatMediumParam *)mediumParam);
1353     if (ret != SOFTBUS_OK) {
1354         LNN_LOGE(LNN_HEART_BEAT, "set medium param fail, type=%{public}d, ret=%{public}d", mediumParam->type, ret);
1355         return ret;
1356     }
1357     return SOFTBUS_OK;
1358 }
1359 
LnnHbMediumMgrUpdateSendInfo(LnnHeartbeatUpdateInfoType type)1360 int32_t LnnHbMediumMgrUpdateSendInfo(LnnHeartbeatUpdateInfoType type)
1361 {
1362     int32_t i;
1363 
1364     for (i = 0; i < HB_MAX_TYPE_COUNT; ++i) {
1365         /* HEARTBEAT_TYPE_BLE_V0 and HEARTBEAT_TYPE_BLE_V1 have the same medium manager. */
1366         if (i == LnnConvertHbTypeToId(HEARTBEAT_TYPE_BLE_V1)) {
1367             continue;
1368         }
1369         if (g_hbMeidumMgr[i] == NULL || g_hbMeidumMgr[i]->onUpdateSendInfo == NULL) {
1370             continue;
1371         }
1372         if (g_hbMeidumMgr[i]->onUpdateSendInfo(type) != SOFTBUS_OK) {
1373             LNN_LOGE(LNN_HEART_BEAT, "manager update send info fail, i=%{public}d", i);
1374             return SOFTBUS_ERR;
1375         }
1376     }
1377     return SOFTBUS_OK;
1378 }
1379 
VisitRegistHeartbeatMediumMgr(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)1380 static bool VisitRegistHeartbeatMediumMgr(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
1381 {
1382     (void)typeSet;
1383     int32_t id;
1384     LnnHeartbeatMediumMgr *mgr = (LnnHeartbeatMediumMgr *)data;
1385 
1386     id = LnnConvertHbTypeToId(eachType);
1387     if (id == HB_INVALID_TYPE_ID) {
1388         LNN_LOGE(LNN_HEART_BEAT, "regist manager convert type fail");
1389         return false;
1390     }
1391     LNN_LOGD(LNN_HEART_BEAT, "Regeist medium manager id=%{public}d", id);
1392     g_hbMeidumMgr[id] = mgr;
1393     return true;
1394 }
1395 
LnnRegistHeartbeatMediumMgr(LnnHeartbeatMediumMgr * mgr)1396 int32_t LnnRegistHeartbeatMediumMgr(LnnHeartbeatMediumMgr *mgr)
1397 {
1398     // TODO: One-to-one correspondence between LnnHeartbeatMediumMgr and implementation.
1399     if (mgr == NULL) {
1400         LNN_LOGE(LNN_HEART_BEAT, "regist manager get invalid param");
1401         return SOFTBUS_INVALID_PARAM;
1402     }
1403     if (!LnnVisitHbTypeSet(VisitRegistHeartbeatMediumMgr, &mgr->supportType, (void *)mgr)) {
1404         LNN_LOGE(LNN_HEART_BEAT, "regist manager fail");
1405         return SOFTBUS_ERR;
1406     }
1407     if (mgr->init != NULL) {
1408         return mgr->init(&g_hbMediumMgrCb);
1409     }
1410     return SOFTBUS_OK;
1411 }
1412 
VisitUnRegistHeartbeatMediumMgr(LnnHeartbeatType * typeSet,LnnHeartbeatType eachType,void * data)1413 static bool VisitUnRegistHeartbeatMediumMgr(LnnHeartbeatType *typeSet, LnnHeartbeatType eachType, void *data)
1414 {
1415     (void)typeSet;
1416     (void)data;
1417     int32_t id;
1418 
1419     id = LnnConvertHbTypeToId(eachType);
1420     if (id == HB_INVALID_TYPE_ID) {
1421         LNN_LOGE(LNN_HEART_BEAT, "unregist manager convert type fail");
1422         return false;
1423     }
1424     g_hbMeidumMgr[id] = NULL;
1425     return true;
1426 }
1427 
LnnUnRegistHeartbeatMediumMgr(LnnHeartbeatMediumMgr * mgr)1428 int32_t LnnUnRegistHeartbeatMediumMgr(LnnHeartbeatMediumMgr *mgr)
1429 {
1430     if (mgr == NULL) {
1431         LNN_LOGE(LNN_HEART_BEAT, "unregist manager get invalid param");
1432         return SOFTBUS_INVALID_PARAM;
1433     }
1434     if (!LnnVisitHbTypeSet(VisitUnRegistHeartbeatMediumMgr, &mgr->supportType, (void *)mgr)) {
1435         LNN_LOGE(LNN_HEART_BEAT, "unregist manager fail");
1436         return SOFTBUS_ERR;
1437     }
1438     if (mgr->deinit != NULL) {
1439         mgr->deinit();
1440     }
1441     return SOFTBUS_OK;
1442 }
1443