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