1 /*
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "lnn_net_builder.h"
17
18 #include <securec.h>
19 #include <stdlib.h>
20 #include <inttypes.h>
21
22 #include "anonymizer.h"
23 #include "auth_common.h"
24 #include "auth_deviceprofile.h"
25 #include "auth_interface.h"
26 #include "auth_manager.h"
27 #include "auth_request.h"
28 #include "auth_request.h"
29 #include "auth_hichain_adapter.h"
30 #include "bus_center_event.h"
31 #include "bus_center_manager.h"
32 #include "common_list.h"
33 #include "g_enhance_lnn_func_pack.h"
34 #include "lnn_async_callback_utils.h"
35 #include "lnn_battery_info.h"
36 #include "lnn_connection_addr_utils.h"
37 #include "lnn_connection_fsm.h"
38 #include "lnn_deviceinfo_to_profile.h"
39 #include "lnn_devicename_info.h"
40 #include "lnn_discovery_manager.h"
41 #include "lnn_distributed_net_ledger.h"
42
43 #include "lnn_heartbeat_utils.h"
44
45 #include "lnn_local_net_ledger.h"
46 #include "lnn_log.h"
47 #include "lnn_map.h"
48 #include "lnn_network_id.h"
49 #include "lnn_network_info.h"
50 #include "lnn_network_manager.h"
51 #include "lnn_node_info.h"
52 #include "lnn_node_weight.h"
53 #include "lnn_ohos_account.h"
54 #include "lnn_p2p_info.h"
55 #include "lnn_physical_subnet_manager.h"
56 #include "lnn_sync_info_manager.h"
57 #include "lnn_sync_item_info.h"
58 #include "lnn_topo_manager.h"
59 #include "softbus_adapter_bt_common.h"
60 #include "softbus_adapter_crypto.h"
61 #include "softbus_adapter_json.h"
62 #include "softbus_adapter_mem.h"
63 #include "softbus_error_code.h"
64 #include "softbus_feature_config.h"
65 #include "legacy/softbus_hisysevt_bus_center.h"
66 #include "softbus_json_utils.h"
67 #include "softbus_adapter_json.h"
68 #include "softbus_utils.h"
69 #include "softbus_wifi_api_adapter.h"
70 #include "lnn_net_builder.h"
71 #include "lnn_net_builder_init.h"
72
73
74 #define DEFAULT_PKG_NAME "com.huawei.nearby"
75 #define DEFAULT_MAX_LNN_CONNECTION_COUNT 10
76
77 typedef int32_t (*NetBuilderMessageProcess)(const void *para);
78
FindConnectionFsmByRequestId(uint32_t requestId)79 LnnConnectionFsm *FindConnectionFsmByRequestId(uint32_t requestId)
80 {
81 LnnConnectionFsm *item = NULL;
82
83 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
84 if (item->connInfo.requestId == requestId) {
85 return item;
86 }
87 }
88 return NULL;
89 }
90
FindNodeInfoByRquestId(uint32_t requestId)91 NodeInfo *FindNodeInfoByRquestId(uint32_t requestId)
92 {
93 LnnConnectionFsm *connFsm = FindConnectionFsmByRequestId(requestId);
94 if (connFsm == NULL || connFsm->isDead) {
95 LNN_LOGE(LNN_BUILDER, "can not find connection fsm. requestId=%{public}u", requestId);
96 return NULL;
97 }
98 LNN_LOGI(LNN_BUILDER, "find connFsm success");
99 if (connFsm->connInfo.nodeInfo == NULL) {
100 return NULL;
101 }
102 return connFsm->connInfo.nodeInfo;
103 }
104
FindConnectionFsmByAuthHandle(const AuthHandle * authHandle)105 LnnConnectionFsm *FindConnectionFsmByAuthHandle(const AuthHandle *authHandle)
106 {
107 LnnConnectionFsm *item = NULL;
108
109 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
110 if (item->connInfo.authHandle.authId == authHandle->authId &&
111 item->connInfo.authHandle.type == authHandle->type) {
112 return item;
113 }
114 }
115 return NULL;
116 }
117
FindConnectionFsmByAddr(const ConnectionAddr * addr,bool isShort)118 LnnConnectionFsm *FindConnectionFsmByAddr(const ConnectionAddr *addr, bool isShort)
119 {
120 LnnConnectionFsm *item = NULL;
121
122 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
123 if (LnnIsSameConnectionAddr(addr, &item->connInfo.addr, isShort)) {
124 return item;
125 }
126 }
127 return NULL;
128 }
129
FindConnectionFsmByNetworkId(const char * networkId)130 static LnnConnectionFsm *FindConnectionFsmByNetworkId(const char *networkId)
131 {
132 LnnConnectionFsm *item = NULL;
133
134 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
135 if (strcmp(networkId, item->connInfo.peerNetworkId) == 0) {
136 return item;
137 }
138 }
139 return NULL;
140 }
141
FindRequestIdByAddr(ConnectionAddr * connetionAddr,uint32_t * requestId)142 int32_t FindRequestIdByAddr(ConnectionAddr *connetionAddr, uint32_t *requestId)
143 {
144 if (requestId == NULL) {
145 LNN_LOGE(LNN_BUILDER, "requestId is null");
146 return SOFTBUS_INVALID_PARAM;
147 }
148 LnnConnectionFsm *connFsm = FindConnectionFsmByAddr(connetionAddr, false);
149 if (connFsm == NULL || connFsm->isDead) {
150 LNN_LOGE(LNN_BUILDER, "can not find connection fsm by addr");
151 return SOFTBUS_NETWORK_NOT_FOUND;
152 }
153 LNN_LOGD(LNN_BUILDER, "find connFsm success");
154 *requestId = connFsm->connInfo.requestId;
155 return SOFTBUS_OK;
156 }
157
StartNewConnectionFsm(const ConnectionAddr * addr,const char * pkgName,bool isNeedConnect)158 LnnConnectionFsm *StartNewConnectionFsm(const ConnectionAddr *addr, const char *pkgName, bool isNeedConnect)
159 {
160 LnnConnectionFsm *connFsm = NULL;
161
162 if (LnnGetNetBuilder()->connCount >= LnnGetNetBuilder()->maxConnCount) {
163 LNN_LOGE(LNN_BUILDER, "current connection num exceeds max limit, connCount=%{public}d",
164 LnnGetNetBuilder()->connCount);
165 return NULL;
166 }
167 connFsm = LnnCreateConnectionFsm(addr, pkgName, isNeedConnect);
168 if (connFsm == NULL) {
169 LNN_LOGE(LNN_BUILDER, "create connection fsm failed");
170 return NULL;
171 }
172 if (LnnStartConnectionFsm(connFsm) != SOFTBUS_OK) {
173 LNN_LOGE(LNN_BUILDER, "start connection failed. fsmId=%{public}u", connFsm->id);
174 LnnDestroyConnectionFsm(connFsm);
175 return NULL;
176 }
177 SetBeginJoinLnnTime(connFsm);
178 ListAdd(&LnnGetNetBuilder()->fsmList, &connFsm->node);
179 ++LnnGetNetBuilder()->connCount;
180 return connFsm;
181 }
182
CleanConnectionFsm(LnnConnectionFsm * connFsm)183 void CleanConnectionFsm(LnnConnectionFsm *connFsm)
184 {
185 if (connFsm == NULL) {
186 LNN_LOGE(LNN_BUILDER, "connection fsm is null");
187 return;
188 }
189 LNN_LOGI(LNN_BUILDER, "connection is cleaned. fsmId=%{public}u", connFsm->id);
190 LnnDestroyConnectionFsm(connFsm);
191 }
192
StopConnectionFsm(LnnConnectionFsm * connFsm)193 void StopConnectionFsm(LnnConnectionFsm *connFsm)
194 {
195 if (LnnStopConnectionFsm(connFsm, CleanConnectionFsm) != SOFTBUS_OK) {
196 LNN_LOGE(LNN_BUILDER, "stop connection failed. fsmId=%{public}u", connFsm->id);
197 }
198 ListDelete(&connFsm->node);
199 --LnnGetNetBuilder()->connCount;
200 }
201
CreatePassiveConnectionFsm(const DeviceVerifyPassMsgPara * msgPara)202 static int32_t CreatePassiveConnectionFsm(const DeviceVerifyPassMsgPara *msgPara)
203 {
204 LnnConnectionFsm *connFsm = NULL;
205 connFsm = StartNewConnectionFsm(&msgPara->addr, DEFAULT_PKG_NAME, true);
206 if (connFsm == NULL) {
207 LNN_LOGE(LNN_BUILDER, "start new connection fsm fail, authId=%{public}" PRId64, msgPara->authHandle.authId);
208 return SOFTBUS_NETWORK_FSM_START_FAIL;
209 }
210 connFsm->connInfo.authHandle = msgPara->authHandle;
211 connFsm->connInfo.nodeInfo = msgPara->nodeInfo;
212 connFsm->connInfo.flag |= LNN_CONN_INFO_FLAG_JOIN_PASSIVE;
213 LNN_LOGI(LNN_BUILDER, "fsmId=%{public}u start a passive connection fsm, type=%{public}d, authId=%{public}" PRId64,
214 connFsm->id, msgPara->authHandle.type, msgPara->authHandle.authId);
215 int32_t ret = LnnSendAuthResultMsgToConnFsm(connFsm, SOFTBUS_OK);
216 if (ret != SOFTBUS_OK) {
217 connFsm->connInfo.nodeInfo = NULL;
218 StopConnectionFsm(connFsm);
219 LNN_LOGE(LNN_BUILDER, "fsmId=%{public}u post auth result to connection fsm fail, authId=%{public}" PRId64,
220 connFsm->id, msgPara->authHandle.authId);
221 return ret;
222 }
223 return SOFTBUS_OK;
224 }
225
IsInvalidConnectionFsm(const LnnConnectionFsm * connFsm,const LeaveInvalidConnMsgPara * msgPara)226 static bool IsInvalidConnectionFsm(const LnnConnectionFsm *connFsm, const LeaveInvalidConnMsgPara *msgPara)
227 {
228 if (strcmp(msgPara->oldNetworkId, connFsm->connInfo.peerNetworkId) != 0) {
229 return false;
230 }
231 if (connFsm->isDead) {
232 LNN_LOGI(LNN_BUILDER, "connection is dead. fsmId=%{public}u", connFsm->id);
233 return false;
234 }
235 if (msgPara->addrType != CONNECTION_ADDR_MAX && msgPara->addrType != connFsm->connInfo.addr.type) {
236 LNN_LOGI(LNN_BUILDER,
237 "connection type not match. fsmId=%{public}u, msgAddrType=%{public}d, connAddrType=%{public}d", connFsm->id,
238 msgPara->addrType, connFsm->connInfo.addr.type);
239 return false;
240 }
241 if ((connFsm->connInfo.flag & LNN_CONN_INFO_FLAG_ONLINE) == 0) {
242 LNN_LOGI(LNN_BUILDER, "connection is not online. fsmId=%{public}u", connFsm->id);
243 return false;
244 }
245 if ((connFsm->connInfo.flag & LNN_CONN_INFO_FLAG_INITIATE_ONLINE) != 0) {
246 LNN_LOGI(LNN_BUILDER, "connection is already in leaving. fsmId=%{public}u", connFsm->id);
247 return false;
248 }
249 return true;
250 }
251
ProcessJoinLNNRequest(const void * para)252 static int32_t ProcessJoinLNNRequest(const void *para)
253 {
254 return TrySendJoinLNNRequest((const JoinLnnMsgPara *)para, true, false);
255 }
256
ProcessDevDiscoveryRequest(const void * para)257 static int32_t ProcessDevDiscoveryRequest(const void *para)
258 {
259 return TrySendJoinLNNRequest((const JoinLnnMsgPara *)para, false, false);
260 }
261
ProcessCleanConnectionFsm(const void * para)262 static int32_t ProcessCleanConnectionFsm(const void *para)
263 {
264 uint16_t connFsmId;
265 LnnConnectionFsm *connFsm = NULL;
266 int32_t rc = SOFTBUS_NETWORK_FSM_CLEAN_FAILED;
267
268 if (para == NULL) {
269 LNN_LOGW(LNN_BUILDER, "connFsmId is null");
270 return SOFTBUS_INVALID_PARAM;
271 }
272 connFsmId = *(uint16_t *)para;
273 do {
274 connFsm = FindConnectionFsmByConnFsmId(connFsmId);
275 if (connFsm == NULL) {
276 LNN_LOGE(LNN_BUILDER, "can not find connection fsm");
277 break;
278 }
279 StopConnectionFsm(connFsm);
280 TryInitiateNewNetworkOnline(connFsm);
281 TryDisconnectAllConnection(connFsm);
282 TryNotifyAllTypeOffline(connFsm);
283 TryRemovePendingJoinRequest();
284 rc = SOFTBUS_OK;
285 } while (false);
286 SoftBusFree((void *)para);
287 return rc;
288 }
289
ProcessVerifyResult(const void * para)290 static int32_t ProcessVerifyResult(const void *para)
291 {
292 int32_t rc;
293 LnnConnectionFsm *connFsm = NULL;
294 const VerifyResultMsgPara *msgPara = (const VerifyResultMsgPara *)para;
295
296 if (msgPara == NULL) {
297 LNN_LOGW(LNN_BUILDER, "para is null");
298 return SOFTBUS_INVALID_PARAM;
299 }
300
301 do {
302 connFsm = FindConnectionFsmByRequestId(msgPara->requestId);
303 if (connFsm == NULL || connFsm->isDead) {
304 LNN_LOGE(LNN_BUILDER, "can not find connection fsm by request. requestId=%{public}u", msgPara->requestId);
305 rc = SOFTBUS_NETWORK_NOT_FOUND;
306 break;
307 }
308 LNN_LOGI(LNN_BUILDER, "[id=%{public}u] connection fsm auth done, type=%{public}d, authId=%{public}"
309 PRId64 ", retCode=%{public}d", connFsm->id, msgPara->authHandle.type,
310 msgPara->authHandle.authId, msgPara->retCode);
311 if (msgPara->retCode == SOFTBUS_OK) {
312 if (msgPara->nodeInfo == NULL) {
313 LNN_LOGE(LNN_BUILDER, "msgPara node Info is null, stop fsm [id=%{public}u]", connFsm->id);
314 StopConnectionFsm(connFsm);
315 rc = SOFTBUS_INVALID_PARAM;
316 break;
317 }
318 connFsm->connInfo.authHandle = msgPara->authHandle;
319 connFsm->connInfo.nodeInfo = msgPara->nodeInfo;
320 }
321 rc = LnnSendAuthResultMsgToConnFsm(connFsm, msgPara->retCode);
322 if (rc != SOFTBUS_OK) {
323 LNN_LOGE(LNN_BUILDER, "send auth result to connection failed. [id=%{public}u]", connFsm->id);
324 connFsm->connInfo.nodeInfo = NULL;
325 break;
326 }
327 } while (false);
328
329 if (rc != SOFTBUS_OK && msgPara->nodeInfo != NULL) {
330 SoftBusFree((void *)msgPara->nodeInfo);
331 }
332 SoftBusFree((void *)msgPara);
333 return rc;
334 }
335
JudgingBleState(uint32_t remote)336 static int32_t JudgingBleState(uint32_t remote)
337 {
338 uint32_t local;
339 int32_t ret = LnnGetLocalNumU32Info(NUM_KEY_NET_CAP, &local);
340 if (ret != SOFTBUS_OK) {
341 LNN_LOGE(LNN_BUILDER, "get local num info failed");
342 return SOFTBUS_NETWORK_LEDGER_INIT_FAILED;
343 }
344 if (((local & (1 << BIT_BLE)) == 0) || ((remote & (1 << BIT_BLE)) == 0)) {
345 LNN_LOGE(LNN_BUILDER, "can't support BLE, local=%{public}u, remote=%{public}u", local, remote);
346 return SOFTBUS_BLUETOOTH_OFF;
347 }
348 return SOFTBUS_OK;
349 }
350
ProcessEnhancedP2pDupBle(const DeviceVerifyPassMsgPara * msgPara)351 static int32_t ProcessEnhancedP2pDupBle(const DeviceVerifyPassMsgPara *msgPara)
352 {
353 if (JudgingBleState(msgPara->nodeInfo->netCapacity) != SOFTBUS_OK) {
354 LNN_LOGE(LNN_BUILDER, "can't support BLE");
355 return SOFTBUS_BLUETOOTH_OFF;
356 }
357 int32_t ret = 0;
358 switch (msgPara->authHandle.type) {
359 case AUTH_LINK_TYPE_ENHANCED_P2P:
360 ret = ProcessBleOnline(msgPara->nodeInfo, &(msgPara->addr), BIT_SUPPORT_ENHANCEDP2P_DUP_BLE);
361 break;
362 case AUTH_LINK_TYPE_SESSION:
363 ret = ProcessBleOnline(msgPara->nodeInfo, &(msgPara->addr), BIT_SUPPORT_SESSION_DUP_BLE);
364 AuthRemoveAuthManagerByAuthHandle(msgPara->authHandle);
365 break;
366 default:
367 LNN_LOGE(LNN_BUILDER, "auth type is %{public}d, not support", msgPara->authHandle.type);
368 ret = SOFTBUS_FUNC_NOT_SUPPORT;
369 }
370 return ret;
371 }
372
GetSessionKeyByAuthHandle(const DeviceVerifyPassMsgPara * msgPara,AuthHandle authHandle)373 static void GetSessionKeyByAuthHandle(const DeviceVerifyPassMsgPara *msgPara, AuthHandle authHandle)
374 {
375 SessionKey sessionKey;
376 (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
377 UpdateDpAclParams aclParams = {
378 .accountId = msgPara->nodeInfo->accountId,
379 .deviceId = msgPara->nodeInfo->deviceInfo.deviceUdid,
380 .peerUserId = msgPara->nodeInfo->userId
381 };
382 UpdateDpSameAccount(&aclParams, sessionKey, false, msgPara->nodeInfo->aclState);
383 }
384
CheckParamValid(const DeviceVerifyPassMsgPara * msgPara)385 static int32_t CheckParamValid(const DeviceVerifyPassMsgPara *msgPara)
386 {
387 if (msgPara == NULL) {
388 LNN_LOGW(LNN_BUILDER, "para is null");
389 return SOFTBUS_INVALID_PARAM;
390 }
391 if (msgPara->nodeInfo == NULL) {
392 LNN_LOGE(LNN_BUILDER, "msgPara nodeInfo is null");
393 SoftBusFree((void *)msgPara);
394 return SOFTBUS_INVALID_PARAM;
395 }
396 return SOFTBUS_OK;
397 }
398
GetPeerDeviceUdid(char * peerNetworkId,char * peerUdid,uint32_t udidLen)399 static int32_t GetPeerDeviceUdid(char *peerNetworkId, char *peerUdid, uint32_t udidLen)
400 {
401 NodeInfo info;
402 (void)memset_s(&info, sizeof(NodeInfo), 0, sizeof(NodeInfo));
403 if (LnnGetRemoteNodeInfoById(peerNetworkId, CATEGORY_NETWORK_ID, &info) != SOFTBUS_OK) {
404 LNN_LOGE(LNN_BUILDER, "get remote node info fail");
405 return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
406 }
407 if (strcpy_s(peerUdid, udidLen, info.deviceInfo.deviceUdid) != EOK) {
408 LNN_LOGE(LNN_BUILDER, "strcpy udid fail");
409 return SOFTBUS_STRCPY_ERR;
410 }
411 return SOFTBUS_OK;
412 }
413
TryTriggerSparkGroupBuild(const DeviceVerifyPassMsgPara * msgPara)414 static void TryTriggerSparkGroupBuild(const DeviceVerifyPassMsgPara *msgPara)
415 {
416 if (IsSameAccountId(msgPara->nodeInfo->accountId) &&
417 LnnHasDiscoveryType(msgPara->nodeInfo, DISCOVERY_TYPE_BLE)) {
418 TriggerSparkGroupJoinAgainPacked(msgPara->nodeInfo->deviceInfo.deviceUdid, SPARK_GROUP_DELAY_TIME_MS);
419 }
420 }
421
ProcessDeviceVerifyPass(const void * para)422 static int32_t ProcessDeviceVerifyPass(const void *para)
423 {
424 int32_t rc;
425 LnnConnectionFsm *connFsm = NULL;
426 const DeviceVerifyPassMsgPara *msgPara = (const DeviceVerifyPassMsgPara *)para;
427
428 if (CheckParamValid(msgPara) != SOFTBUS_OK) {
429 return SOFTBUS_INVALID_PARAM;
430 }
431 if (msgPara->authHandle.type == AUTH_LINK_TYPE_ENHANCED_P2P || msgPara->authHandle.type == AUTH_LINK_TYPE_SESSION) {
432 LNN_LOGI(LNN_BUILDER, "auth type is %{public}d, start dup ble.", msgPara->authHandle.type);
433 rc = ProcessEnhancedP2pDupBle(msgPara);
434 if (msgPara->nodeInfo != NULL) {
435 SoftBusFree((void *)msgPara->nodeInfo);
436 }
437 SoftBusFree((void *)msgPara);
438 return rc;
439 }
440
441 do {
442 connFsm = FindConnectionFsmByAuthHandle(&msgPara->authHandle);
443 if (connFsm == NULL || connFsm->isDead) {
444 rc = CreatePassiveConnectionFsm(msgPara);
445 break;
446 }
447 if (LnnIsNeedCleanConnectionFsm(msgPara->nodeInfo, msgPara->addr.type)) {
448 rc = CreatePassiveConnectionFsm(msgPara);
449 break;
450 }
451 char peerUdid[UDID_BUF_LEN] = { 0 };
452 if (GetPeerDeviceUdid(connFsm->connInfo.peerNetworkId, peerUdid, UDID_BUF_LEN) == SOFTBUS_OK &&
453 strcmp(peerUdid, msgPara->nodeInfo->deviceInfo.deviceUdid) != 0) {
454 LnnSendLeaveRequestToConnFsm(connFsm);
455 rc = CreatePassiveConnectionFsm(msgPara);
456 break;
457 }
458 msgPara->nodeInfo->discoveryType = 1 << (uint32_t)LnnConvAddrTypeToDiscType(msgPara->addr.type);
459 if (LnnUpdateNodeInfo(msgPara->nodeInfo, msgPara->addr.type) != SOFTBUS_OK) {
460 LNN_LOGE(LNN_BUILDER, "LnnUpdateNodeInfo failed");
461 }
462 TryTriggerSparkGroupBuild(msgPara);
463 GetSessionKeyByAuthHandle(msgPara, msgPara->authHandle);
464 LNN_LOGI(LNN_BUILDER, "fsmId=%{public}u connection fsm exist, ignore VerifyPass authId=%{public}" PRId64,
465 connFsm->id, msgPara->authHandle.authId);
466 rc = SOFTBUS_ALREADY_EXISTED;
467 } while (false);
468 if (rc != SOFTBUS_OK && msgPara->nodeInfo != NULL) {
469 SoftBusFree((void *)msgPara->nodeInfo);
470 }
471 SoftBusFree((void *)msgPara);
472 return rc;
473 }
474
ProcessDeviceDisconnect(const void * para)475 static int32_t ProcessDeviceDisconnect(const void *para)
476 {
477 int32_t rc;
478 LnnConnectionFsm *connFsm = NULL;
479 const AuthHandle *authHandle = (const AuthHandle *)para;
480
481 if (authHandle == NULL) {
482 LNN_LOGW(LNN_BUILDER, "auth authHandle is null");
483 return SOFTBUS_INVALID_PARAM;
484 }
485
486 do {
487 connFsm = FindConnectionFsmByAuthHandle(authHandle);
488 if (connFsm == NULL || connFsm->isDead) {
489 LNN_LOGE(LNN_BUILDER, "can not find connection fsm. authId=%{public}" PRId64, authHandle->authId);
490 rc = SOFTBUS_NETWORK_NOT_FOUND;
491 break;
492 }
493 LNN_LOGI(LNN_BUILDER, "fsmId=%{public}u device disconnect, authId=%{public}" PRId64,
494 connFsm->id, authHandle->authId);
495 rc = LnnSendDisconnectMsgToConnFsm(connFsm);
496 if (rc != SOFTBUS_OK) {
497 LNN_LOGE(LNN_BUILDER, "send disconnect to connection failed. fsmId=%{public}u", connFsm->id);
498 break;
499 }
500 } while (false);
501 SoftBusFree((void *)authHandle);
502 return rc;
503 }
504
505
ProcessDeviceNotTrusted(const void * para)506 static int32_t ProcessDeviceNotTrusted(const void *para)
507 {
508 int32_t rc;
509 const char *udid = NULL;
510 LnnConnectionFsm *item = NULL;
511 const char *peerUdid = (const char *)para;
512
513 if (peerUdid == NULL) {
514 LNN_LOGW(LNN_BUILDER, "peer udid is null");
515 return SOFTBUS_INVALID_PARAM;
516 }
517
518 do {
519 char networkId[NETWORK_ID_BUF_LEN] = { 0 };
520 if (LnnGetNetworkIdByUdid(peerUdid, networkId, sizeof(networkId)) == SOFTBUS_OK) {
521 LnnRequestLeaveSpecific(networkId, CONNECTION_ADDR_MAX);
522 break;
523 }
524 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
525 udid = LnnGetDeviceUdid(item->connInfo.nodeInfo);
526 if (udid == NULL || strcmp(peerUdid, udid) != 0) {
527 continue;
528 }
529 rc = LnnSendNotTrustedToConnFsm(item);
530 LNN_LOGI(LNN_BUILDER, "send not trusted msg to connection fsm. fsmId=%{public}u, result=%{public}d",
531 item->id, rc);
532 }
533 } while (false);
534 SoftBusFree((void *)peerUdid);
535 return SOFTBUS_OK;
536 }
537
ProcessLeaveLNNRequest(const void * para)538 static int32_t ProcessLeaveLNNRequest(const void *para)
539 {
540 const char *networkId = (const char *)para;
541 LnnConnectionFsm *item = NULL;
542 int rc = SOFTBUS_NETWORK_NOT_FOUND;
543
544 if (networkId == NULL) {
545 LNN_LOGW(LNN_BUILDER, "leave networkId is null");
546 return SOFTBUS_INVALID_PARAM;
547 }
548
549 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
550 if (strcmp(networkId, item->connInfo.peerNetworkId) != 0 || item->isDead) {
551 continue;
552 }
553 rc = LnnSendLeaveRequestToConnFsm(item);
554 if (rc != SOFTBUS_OK) {
555 LNN_LOGE(LNN_BUILDER, "send leave LNN msg to connection failed. fsmId=%{public}u", item->id);
556 } else {
557 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_REQUEST;
558 LNN_LOGI(LNN_BUILDER, "send leave LNN msg to connection success. fsmId=%{public}u", item->id);
559 }
560 }
561 if (rc != SOFTBUS_OK) {
562 LnnNotifyLeaveResult(networkId, SOFTBUS_NETWORK_REQ_LEAVE_LNN_FAIL);
563 }
564 SoftBusFree((void *)networkId);
565 return rc;
566 }
567
ProcessSyncOfflineFinish(const void * para)568 static int32_t ProcessSyncOfflineFinish(const void *para)
569 {
570 const char *networkId = (const char *)para;
571 LnnConnectionFsm *item = NULL;
572 int rc = SOFTBUS_OK;
573
574 if (networkId == NULL) {
575 LNN_LOGW(LNN_BUILDER, "sync offline finish networkId is null");
576 return SOFTBUS_INVALID_PARAM;
577 }
578 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
579 if (strcmp(networkId, item->connInfo.peerNetworkId) != 0 || item->isDead) {
580 continue;
581 }
582 rc = LnnSendSyncOfflineFinishToConnFsm(item);
583 LNN_LOGI(LNN_BUILDER, "send sync offline msg to connection fsmId=%{public}u, result=%{public}d", item->id, rc);
584 }
585 SoftBusFree((void *)networkId);
586 return rc;
587 }
588
ProcessLeaveInvalidConn(const void * para)589 static int32_t ProcessLeaveInvalidConn(const void *para)
590 {
591 LnnConnectionFsm *item = NULL;
592 int32_t rc = SOFTBUS_OK;
593 int32_t count = 0;
594 const LeaveInvalidConnMsgPara *msgPara = (const LeaveInvalidConnMsgPara *)para;
595
596 if (msgPara == NULL) {
597 LNN_LOGW(LNN_BUILDER, "leave invalid connection msg para is null");
598 return SOFTBUS_INVALID_PARAM;
599 }
600 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
601 if (!IsInvalidConnectionFsm(item, msgPara)) {
602 continue;
603 }
604 // The new connFsm should timeout when following errors occur
605 ++count;
606 item->connInfo.cleanInfo = (LnnInvalidCleanInfo *)SoftBusMalloc(sizeof(LnnInvalidCleanInfo));
607 if (item->connInfo.cleanInfo == NULL) {
608 LNN_LOGI(LNN_BUILDER, "malloc invalid clean info failed. fsmId=%{public}u", item->id);
609 continue;
610 }
611 item->connInfo.cleanInfo->addrType = msgPara->addrType;
612 if (strncpy_s(item->connInfo.cleanInfo->networkId, NETWORK_ID_BUF_LEN,
613 msgPara->newNetworkId, strlen(msgPara->newNetworkId)) != EOK) {
614 LNN_LOGE(LNN_BUILDER, "copy new networkId failed. fsmId=%{public}u", item->id);
615 rc = SOFTBUS_STRCPY_ERR;
616 SoftBusFree(item->connInfo.cleanInfo);
617 item->connInfo.cleanInfo = NULL;
618 continue;
619 }
620 rc = LnnSendLeaveRequestToConnFsm(item);
621 if (rc == SOFTBUS_OK) {
622 item->connInfo.flag |= LNN_CONN_INFO_FLAG_INITIATE_ONLINE;
623 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_AUTO;
624 } else {
625 SoftBusFree(item->connInfo.cleanInfo);
626 item->connInfo.cleanInfo = NULL;
627 }
628 LNN_LOGI(
629 LNN_BUILDER, "send leave LNN msg to invalid connection. fsmId=%{public}u, result=%{public}d", item->id, rc);
630 }
631 if (count == 0) {
632 InitiateNewNetworkOnline(msgPara->addrType, msgPara->newNetworkId);
633 }
634 SoftBusFree((void *)msgPara);
635 return rc;
636 }
637
ProcessNodeStateChanged(const void * para)638 static int32_t ProcessNodeStateChanged(const void *para)
639 {
640 const ConnectionAddr *addr = (const ConnectionAddr *)para;
641 LnnConnectionFsm *connFsm = NULL;
642 int32_t rc = SOFTBUS_NETWORK_NOT_FOUND;
643 bool isOnline = false;
644
645 if (addr == NULL) {
646 LNN_LOGW(LNN_BUILDER, "node state changed msg is null");
647 return SOFTBUS_INVALID_PARAM;
648 }
649 do {
650 connFsm = FindConnectionFsmByAddr(addr, false);
651 if (connFsm == NULL) {
652 LNN_LOGE(LNN_BUILDER, "can't find connection fsm when node online state changed");
653 break;
654 }
655 isOnline = IsNodeOnline(connFsm->connInfo.peerNetworkId);
656 TryElectAsMasterState(connFsm->connInfo.peerNetworkId, isOnline);
657 if (!IsSupportMasterNodeElect(connFsm->connInfo.version)) {
658 LNN_LOGI(LNN_BUILDER, "peer not support master node elect. fsmId=%{public}u", connFsm->id);
659 rc = SOFTBUS_OK;
660 break;
661 }
662 rc = isOnline ? TryElectMasterNodeOnline(connFsm) : TryElectMasterNodeOffline(connFsm);
663 } while (false);
664 SoftBusFree((void *)addr);
665 if (isOnline) {
666 TryRemovePendingJoinRequest();
667 }
668 return rc;
669 }
670
ProcessMasterElect(const void * para)671 static int32_t ProcessMasterElect(const void *para)
672 {
673 const ElectMsgPara *msgPara = (const ElectMsgPara *)para;
674 LnnConnectionFsm *connFsm = NULL;
675 char localMasterUdid[UDID_BUF_LEN] = { 0 };
676 int32_t localMasterWeight;
677 int32_t compareRet;
678 int32_t rc = SOFTBUS_NETWORK_NOT_FOUND;
679
680 if (msgPara == NULL) {
681 LNN_LOGW(LNN_BUILDER, "elect msg para is null");
682 return SOFTBUS_INVALID_PARAM;
683 }
684 do {
685 connFsm = FindConnectionFsmByNetworkId(msgPara->networkId);
686 if (connFsm == NULL || connFsm->isDead) {
687 LNN_LOGE(LNN_BUILDER, "can't find connection fsm when receive elect node");
688 break;
689 }
690 if (!IsNodeOnline(connFsm->connInfo.peerNetworkId)) {
691 LNN_LOGE(LNN_BUILDER, "peer node is already offline. fsmId=%{public}u", connFsm->id);
692 break;
693 }
694 if (LnnGetLocalStrInfo(STRING_KEY_MASTER_NODE_UDID, localMasterUdid, UDID_BUF_LEN) != SOFTBUS_OK ||
695 LnnGetLocalNumInfo(NUM_KEY_MASTER_NODE_WEIGHT, &localMasterWeight) != SOFTBUS_OK) {
696 LNN_LOGE(LNN_BUILDER, "get local master node info from ledger failed. fsmId=%{public}u", connFsm->id);
697 break;
698 }
699 compareRet = LnnCompareNodeWeight(localMasterWeight, localMasterUdid,
700 msgPara->masterWeight, msgPara->masterUdid);
701 LNN_LOGI(LNN_BUILDER, "weight compare result: fsmId=%{public}u, result=%{public}d", connFsm->id, compareRet);
702 if (compareRet != 0) {
703 if (compareRet < 0) {
704 UpdateLocalMasterNode(false, msgPara->masterUdid, msgPara->masterWeight);
705 SendElectMessageToAll(connFsm->connInfo.peerNetworkId);
706 } else {
707 rc = SyncElectMessage(connFsm->connInfo.peerNetworkId);
708 LNN_LOGI(LNN_BUILDER, "sync elect info to connFsmId=%{public}u, result=%{public}d", connFsm->id, rc);
709 }
710 }
711 rc = SOFTBUS_OK;
712 } while (false);
713 SoftBusFree((void *)msgPara);
714 return rc;
715 }
716
ProcessLeaveByAddrType(const void * para)717 static int32_t ProcessLeaveByAddrType(const void *para)
718 {
719 bool *addrType = NULL;
720 LnnConnectionFsm *item = NULL;
721 int32_t rc;
722 bool notify = true;
723
724 if (para == NULL) {
725 LNN_LOGW(LNN_BUILDER, "leave by addr type msg para is null");
726 return SOFTBUS_INVALID_PARAM;
727 }
728
729 addrType = (bool *)para;
730 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
731 if (!addrType[item->connInfo.addr.type]) {
732 continue;
733 }
734 // if there are any same addr type, let last one send notify
735 notify = false;
736 if (item->isDead) {
737 continue;
738 }
739 rc = LnnSendLeaveRequestToConnFsm(item);
740 LNN_LOGI(LNN_BUILDER, "leave conn by addr. fsmId=%{public}u, type=%{public}d, rc=%{public}d", item->id,
741 item->connInfo.addr.type, rc);
742 if (rc == SOFTBUS_OK) {
743 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_AUTO;
744 }
745 }
746 LNN_LOGD(LNN_BUILDER, "notify=%{public}d, eth=%{public}d, wifi=%{public}d, usb=%{public}d", notify,
747 addrType[CONNECTION_ADDR_ETH], addrType[CONNECTION_ADDR_WLAN], addrType[CONNECTION_ADDR_NCM]);
748 if (notify && (addrType[CONNECTION_ADDR_ETH] || addrType[CONNECTION_ADDR_WLAN] || addrType[CONNECTION_ADDR_NCM])) {
749 (void)LnnNotifyAllTypeOffline(CONNECTION_ADDR_MAX);
750 }
751 RemovePendingRequestByAddrType(addrType, CONNECTION_ADDR_MAX);
752 SoftBusFree((void *)para);
753 return SOFTBUS_OK;
754 }
755
ProcessLeaveSpecific(const void * para)756 static int32_t ProcessLeaveSpecific(const void *para)
757 {
758 const SpecificLeaveMsgPara *msgPara = (const SpecificLeaveMsgPara *)para;
759 LnnConnectionFsm *item = NULL;
760
761 if (msgPara == NULL) {
762 LNN_LOGW(LNN_BUILDER, "leave specific msg is null");
763 return SOFTBUS_INVALID_PARAM;
764 }
765
766 int32_t rc;
767 bool deviceLeave = false;
768 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
769 if (strcmp(item->connInfo.peerNetworkId, msgPara->networkId) != 0 ||
770 (item->connInfo.addr.type != msgPara->addrType &&
771 msgPara->addrType != CONNECTION_ADDR_MAX)) {
772 continue;
773 }
774 deviceLeave = true;
775 rc = LnnSendLeaveRequestToConnFsm(item);
776 if (rc == SOFTBUS_OK) {
777 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_AUTO;
778 }
779 LNN_LOGI(LNN_BUILDER, "send leave LNN msg to connection. fsmId=%{public}u, result=%{public}d", item->id, rc);
780 }
781
782 if (deviceLeave) {
783 SoftBusFree((void *)msgPara);
784 return SOFTBUS_OK;
785 }
786
787 do {
788 NodeInfo nodeInfo;
789 (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
790 if (LnnGetRemoteNodeInfoById(msgPara->networkId, CATEGORY_NETWORK_ID, &nodeInfo)) {
791 break;
792 }
793
794 if (nodeInfo.deviceInfo.deviceTypeId != TYPE_PC_ID ||
795 strcmp(nodeInfo.networkId, nodeInfo.deviceInfo.deviceUdid) != 0) {
796 break;
797 }
798
799 (void)LnnClearDiscoveryType(&nodeInfo, LnnConvAddrTypeToDiscType(msgPara->addrType));
800 if (nodeInfo.discoveryType != 0) {
801 LNN_LOGI(LNN_BUILDER, "pc without softbus has another discovery type");
802 break;
803 }
804
805 LNN_LOGI(LNN_BUILDER, "pc without softbus offline");
806 DeleteFromProfile(nodeInfo.deviceInfo.deviceUdid);
807 LnnRemoveNode(nodeInfo.deviceInfo.deviceUdid);
808 } while (false);
809 SoftBusFree((void *)msgPara);
810 return SOFTBUS_OK;
811 }
812
ProcessLeaveByAuthId(const void * para)813 static int32_t ProcessLeaveByAuthId(const void *para)
814 {
815 int32_t rc = SOFTBUS_OK;
816 const int64_t *authId = (const int64_t *)para;
817 if (authId == NULL) {
818 LNN_LOGE(LNN_BUILDER, "authId is null");
819 return SOFTBUS_INVALID_PARAM;
820 }
821 LnnConnectionFsm *item = NULL;
822 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
823 if (item->connInfo.authHandle.authId != *authId || item->isDead) {
824 continue;
825 }
826 LNN_LOGI(LNN_BUILDER, "[id=%{public}u]leave reqeust, authId: %{public}" PRId64, item->id, *authId);
827 rc = LnnSendLeaveRequestToConnFsm(item);
828 if (rc != SOFTBUS_OK) {
829 LNN_LOGE(LNN_BUILDER, "send leaveReqeust to connection fsm[id=%{public}u] failed", item->id);
830 }
831 }
832 SoftBusFree((void *) authId);
833 return rc;
834 }
835
ProcessSetReSyncDeviceName(const void * para)836 static int32_t ProcessSetReSyncDeviceName(const void *para)
837 {
838 (void)para;
839 LnnConnectionFsm *item = NULL;
840 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
841 if (!item->isDead && (item->connInfo.flag & LNN_CONN_INFO_FLAG_ONLINE) != 0) {
842 if (item->connInfo.nodeInfo != NULL) {
843 LNN_LOGI(LNN_BUILDER, "[id=%{public}u] need resync device name, authId: %{public}" PRId64, item->id,
844 item->connInfo.authHandle.authId);
845 item->connInfo.nodeInfo->isNeedReSyncDeviceName = true;
846 }
847 }
848 }
849 if (para != NULL) {
850 SoftBusFree((void *)para);
851 para = NULL;
852 }
853 return SOFTBUS_OK;
854 }
855
856 static NetBuilderMessageProcess g_messageProcessor[MSG_TYPE_BUILD_MAX] = {
857 ProcessJoinLNNRequest,
858 ProcessDevDiscoveryRequest,
859 ProcessCleanConnectionFsm,
860 ProcessVerifyResult,
861 ProcessDeviceVerifyPass,
862 ProcessDeviceDisconnect,
863 ProcessDeviceNotTrusted,
864 ProcessLeaveLNNRequest,
865 ProcessSyncOfflineFinish,
866 ProcessNodeStateChanged,
867 ProcessMasterElect,
868 ProcessLeaveInvalidConn,
869 ProcessLeaveByAddrType,
870 ProcessLeaveSpecific,
871 ProcessLeaveByAuthId,
872 ProcessSetReSyncDeviceName,
873 };
874
NetBuilderMessageHandler(SoftBusMessage * msg)875 void NetBuilderMessageHandler(SoftBusMessage *msg)
876 {
877 int32_t ret;
878
879 if (msg == NULL) {
880 LNN_LOGE(LNN_BUILDER, "msg is null in net builder handler");
881 return;
882 }
883 LNN_LOGI(LNN_BUILDER, "net builder process msg=%{public}d", msg->what);
884 if (msg->what >= MSG_TYPE_BUILD_MAX) {
885 LNN_LOGE(LNN_BUILDER, "invalid msg type");
886 return;
887 }
888 ret = g_messageProcessor[msg->what](msg->obj);
889 LNN_LOGD(LNN_BUILDER, "net builder process msg done, msg=%{public}d, ret=%{public}d", msg->what, ret);
890 }