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