1 /*
2 * Copyright (c) 2021-2024 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_error_code.h"
63 #include "softbus_feature_config.h"
64 #include "legacy/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_NETWORK_FSM_START_FAIL;
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 int32_t ret = LnnSendAuthResultMsgToConnFsm(connFsm, SOFTBUS_OK);
215 if (ret != SOFTBUS_OK) {
216 connFsm->connInfo.nodeInfo = NULL;
217 StopConnectionFsm(connFsm);
218 LNN_LOGE(LNN_BUILDER, "fsmId=%{public}u post auth result to connection fsm fail, authId=%{public}" PRId64,
219 connFsm->id, msgPara->authHandle.authId);
220 return ret;
221 }
222 return SOFTBUS_OK;
223 }
224
IsInvalidConnectionFsm(const LnnConnectionFsm * connFsm,const LeaveInvalidConnMsgPara * msgPara)225 static bool IsInvalidConnectionFsm(const LnnConnectionFsm *connFsm, const LeaveInvalidConnMsgPara *msgPara)
226 {
227 if (strcmp(msgPara->oldNetworkId, connFsm->connInfo.peerNetworkId) != 0) {
228 return false;
229 }
230 if (connFsm->isDead) {
231 LNN_LOGI(LNN_BUILDER, "connection is dead. fsmId=%{public}u", connFsm->id);
232 return false;
233 }
234 if (msgPara->addrType != CONNECTION_ADDR_MAX && msgPara->addrType != connFsm->connInfo.addr.type) {
235 LNN_LOGI(LNN_BUILDER,
236 "connection type not match. fsmId=%{public}u, msgAddrType=%{public}d, connAddrType=%{public}d", connFsm->id,
237 msgPara->addrType, connFsm->connInfo.addr.type);
238 return false;
239 }
240 if ((connFsm->connInfo.flag & LNN_CONN_INFO_FLAG_ONLINE) == 0) {
241 LNN_LOGI(LNN_BUILDER, "connection is not online. fsmId=%{public}u", connFsm->id);
242 return false;
243 }
244 if ((connFsm->connInfo.flag & LNN_CONN_INFO_FLAG_INITIATE_ONLINE) != 0) {
245 LNN_LOGI(LNN_BUILDER, "connection is already in leaving. fsmId=%{public}u", connFsm->id);
246 return false;
247 }
248 return true;
249 }
250
ProcessJoinLNNRequest(const void * para)251 static int32_t ProcessJoinLNNRequest(const void *para)
252 {
253 return TrySendJoinLNNRequest((const JoinLnnMsgPara *)para, true, false);
254 }
255
ProcessDevDiscoveryRequest(const void * para)256 static int32_t ProcessDevDiscoveryRequest(const void *para)
257 {
258 return TrySendJoinLNNRequest((const JoinLnnMsgPara *)para, false, false);
259 }
260
ProcessCleanConnectionFsm(const void * para)261 static int32_t ProcessCleanConnectionFsm(const void *para)
262 {
263 uint16_t connFsmId;
264 LnnConnectionFsm *connFsm = NULL;
265 int32_t rc = SOFTBUS_NETWORK_FSM_CLEAN_FAILED;
266
267 if (para == NULL) {
268 LNN_LOGW(LNN_BUILDER, "connFsmId is null");
269 return SOFTBUS_INVALID_PARAM;
270 }
271 connFsmId = *(uint16_t *)para;
272 do {
273 connFsm = FindConnectionFsmByConnFsmId(connFsmId);
274 if (connFsm == NULL) {
275 LNN_LOGE(LNN_BUILDER, "can not find connection fsm");
276 break;
277 }
278 StopConnectionFsm(connFsm);
279 TryInitiateNewNetworkOnline(connFsm);
280 TryDisconnectAllConnection(connFsm);
281 TryNotifyAllTypeOffline(connFsm);
282 TryRemovePendingJoinRequest();
283 rc = SOFTBUS_OK;
284 } while (false);
285 SoftBusFree((void *)para);
286 return rc;
287 }
288
ProcessVerifyResult(const void * para)289 static int32_t ProcessVerifyResult(const void *para)
290 {
291 int32_t rc;
292 LnnConnectionFsm *connFsm = NULL;
293 const VerifyResultMsgPara *msgPara = (const VerifyResultMsgPara *)para;
294
295 if (msgPara == NULL) {
296 LNN_LOGW(LNN_BUILDER, "para is null");
297 return SOFTBUS_INVALID_PARAM;
298 }
299
300 do {
301 connFsm = FindConnectionFsmByRequestId(msgPara->requestId);
302 if (connFsm == NULL || connFsm->isDead) {
303 LNN_LOGE(LNN_BUILDER, "can not find connection fsm by request. requestId=%{public}u", msgPara->requestId);
304 rc = SOFTBUS_NETWORK_NOT_FOUND;
305 break;
306 }
307 LNN_LOGI(LNN_BUILDER, "[id=%{public}u] connection fsm auth done, type=%{public}d, authId=%{public}"
308 PRId64 ", retCode=%{public}d", connFsm->id, msgPara->authHandle.type,
309 msgPara->authHandle.authId, msgPara->retCode);
310 if (msgPara->retCode == SOFTBUS_OK) {
311 if (msgPara->nodeInfo == NULL) {
312 LNN_LOGE(LNN_BUILDER, "msgPara node Info is null, stop fsm [id=%{public}u]", connFsm->id);
313 StopConnectionFsm(connFsm);
314 rc = SOFTBUS_INVALID_PARAM;
315 break;
316 }
317 connFsm->connInfo.authHandle = msgPara->authHandle;
318 connFsm->connInfo.nodeInfo = msgPara->nodeInfo;
319 }
320 rc = LnnSendAuthResultMsgToConnFsm(connFsm, msgPara->retCode);
321 if (rc != SOFTBUS_OK) {
322 LNN_LOGE(LNN_BUILDER, "send auth result to connection failed. [id=%{public}u]", connFsm->id);
323 connFsm->connInfo.nodeInfo = NULL;
324 break;
325 }
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
JudgingBleState(uint32_t remote)335 static int32_t JudgingBleState(uint32_t remote)
336 {
337 uint32_t local;
338 int32_t ret = LnnGetLocalNumU32Info(NUM_KEY_NET_CAP, &local);
339 if (ret != SOFTBUS_OK) {
340 LNN_LOGE(LNN_BUILDER, "get local num info failed");
341 return SOFTBUS_NETWORK_LEDGER_INIT_FAILED;
342 }
343 if (((local & (1 << BIT_BLE)) == 0) || ((remote & (1 << BIT_BLE)) == 0)) {
344 LNN_LOGE(LNN_BUILDER, "can't support BLE, local=%{public}u, remote=%{public}u", local, remote);
345 return SOFTBUS_BLUETOOTH_OFF;
346 }
347 return SOFTBUS_OK;
348 }
349
ProcessEnhancedP2pDupBle(const DeviceVerifyPassMsgPara * msgPara)350 static int32_t ProcessEnhancedP2pDupBle(const DeviceVerifyPassMsgPara *msgPara)
351 {
352 if (JudgingBleState(msgPara->nodeInfo->netCapacity) != SOFTBUS_OK) {
353 LNN_LOGE(LNN_BUILDER, "can't support BLE");
354 return SOFTBUS_BLUETOOTH_OFF;
355 }
356 int32_t ret = 0;
357 switch (msgPara->authHandle.type) {
358 case AUTH_LINK_TYPE_ENHANCED_P2P:
359 ret = ProcessBleOnline(msgPara->nodeInfo, &(msgPara->addr), BIT_SUPPORT_ENHANCEDP2P_DUP_BLE);
360 break;
361 case AUTH_LINK_TYPE_SESSION:
362 ret = ProcessBleOnline(msgPara->nodeInfo, &(msgPara->addr), BIT_SUPPORT_SESSION_DUP_BLE);
363 AuthRemoveAuthManagerByAuthHandle(msgPara->authHandle);
364 break;
365 default:
366 LNN_LOGE(LNN_BUILDER, "auth type is %{public}d, not support", msgPara->authHandle.type);
367 ret = SOFTBUS_FUNC_NOT_SUPPORT;
368 }
369 return ret;
370 }
371
ProcessDeviceVerifyPass(const void * para)372 static int32_t ProcessDeviceVerifyPass(const void *para)
373 {
374 int32_t rc;
375 LnnConnectionFsm *connFsm = NULL;
376 const DeviceVerifyPassMsgPara *msgPara = (const DeviceVerifyPassMsgPara *)para;
377
378 if (msgPara == NULL) {
379 LNN_LOGW(LNN_BUILDER, "para is null");
380 return SOFTBUS_INVALID_PARAM;
381 }
382 if (msgPara->nodeInfo == NULL) {
383 LNN_LOGE(LNN_BUILDER, "msgPara nodeInfo is null");
384 SoftBusFree((void *)msgPara);
385 return SOFTBUS_INVALID_PARAM;
386 }
387
388 if (msgPara->authHandle.type == AUTH_LINK_TYPE_ENHANCED_P2P ||
389 msgPara->authHandle.type == AUTH_LINK_TYPE_SESSION) {
390 LNN_LOGI(LNN_BUILDER, "auth type is %{public}d, start dup ble.", msgPara->authHandle.type);
391 rc = ProcessEnhancedP2pDupBle(msgPara);
392 if (msgPara->nodeInfo != NULL) {
393 SoftBusFree((void *)msgPara->nodeInfo);
394 }
395 SoftBusFree((void *)msgPara);
396 return rc;
397 }
398
399 do {
400 connFsm = FindConnectionFsmByAuthHandle(&msgPara->authHandle);
401 if (connFsm == NULL || connFsm->isDead) {
402 rc = CreatePassiveConnectionFsm(msgPara);
403 break;
404 }
405 if (LnnIsNeedCleanConnectionFsm(msgPara->nodeInfo, msgPara->addr.type)) {
406 rc = CreatePassiveConnectionFsm(msgPara);
407 break;
408 }
409 msgPara->nodeInfo->discoveryType = 1 << (uint32_t)LnnConvAddrTypeToDiscType(msgPara->addr.type);
410 if (LnnUpdateNodeInfo(msgPara->nodeInfo, msgPara->addr.type) != SOFTBUS_OK) {
411 LNN_LOGE(LNN_BUILDER, "LnnUpdateNodeInfo failed");
412 }
413 LNN_LOGI(LNN_BUILDER, "fsmId=%{public}u connection fsm exist, ignore VerifyPass authId=%{public}" PRId64,
414 connFsm->id, msgPara->authHandle.authId);
415 rc = SOFTBUS_ALREADY_EXISTED;
416 } while (false);
417
418 if (rc != SOFTBUS_OK && msgPara->nodeInfo != NULL) {
419 SoftBusFree((void *)msgPara->nodeInfo);
420 }
421 SoftBusFree((void *)msgPara);
422 return rc;
423 }
424
ProcessDeviceDisconnect(const void * para)425 static int32_t ProcessDeviceDisconnect(const void *para)
426 {
427 int32_t rc;
428 LnnConnectionFsm *connFsm = NULL;
429 const AuthHandle *authHandle = (const AuthHandle *)para;
430
431 if (authHandle == NULL) {
432 LNN_LOGW(LNN_BUILDER, "auth authHandle is null");
433 return SOFTBUS_INVALID_PARAM;
434 }
435
436 do {
437 connFsm = FindConnectionFsmByAuthHandle(authHandle);
438 if (connFsm == NULL || connFsm->isDead) {
439 LNN_LOGE(LNN_BUILDER, "can not find connection fsm. authId=%{public}" PRId64, authHandle->authId);
440 rc = SOFTBUS_NETWORK_NOT_FOUND;
441 break;
442 }
443 LNN_LOGI(LNN_BUILDER, "fsmId=%{public}u device disconnect, authId=%{public}" PRId64,
444 connFsm->id, authHandle->authId);
445 rc = LnnSendDisconnectMsgToConnFsm(connFsm);
446 if (rc != SOFTBUS_OK) {
447 LNN_LOGE(LNN_BUILDER, "send disconnect to connection failed. fsmId=%{public}u", connFsm->id);
448 break;
449 }
450 } while (false);
451 SoftBusFree((void *)authHandle);
452 return rc;
453 }
454
455
ProcessDeviceNotTrusted(const void * para)456 static int32_t ProcessDeviceNotTrusted(const void *para)
457 {
458 int32_t rc;
459 const char *udid = NULL;
460 LnnConnectionFsm *item = NULL;
461 const char *peerUdid = (const char *)para;
462
463 if (peerUdid == NULL) {
464 LNN_LOGW(LNN_BUILDER, "peer udid is null");
465 return SOFTBUS_INVALID_PARAM;
466 }
467
468 do {
469 char networkId[NETWORK_ID_BUF_LEN] = { 0 };
470 if (LnnGetNetworkIdByUdid(peerUdid, networkId, sizeof(networkId)) == SOFTBUS_OK) {
471 LnnRequestLeaveSpecific(networkId, CONNECTION_ADDR_MAX);
472 break;
473 }
474 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
475 udid = LnnGetDeviceUdid(item->connInfo.nodeInfo);
476 if (udid == NULL || strcmp(peerUdid, udid) != 0) {
477 continue;
478 }
479 rc = LnnSendNotTrustedToConnFsm(item);
480 LNN_LOGI(LNN_BUILDER, "send not trusted msg to connection fsm. fsmId=%{public}u, result=%{public}d",
481 item->id, rc);
482 }
483 } while (false);
484 SoftBusFree((void *)peerUdid);
485 return SOFTBUS_OK;
486 }
487
ProcessLeaveLNNRequest(const void * para)488 static int32_t ProcessLeaveLNNRequest(const void *para)
489 {
490 const char *networkId = (const char *)para;
491 LnnConnectionFsm *item = NULL;
492 int rc = SOFTBUS_NETWORK_NOT_FOUND;
493
494 if (networkId == NULL) {
495 LNN_LOGW(LNN_BUILDER, "leave networkId is null");
496 return SOFTBUS_INVALID_PARAM;
497 }
498
499 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
500 if (strcmp(networkId, item->connInfo.peerNetworkId) != 0 || item->isDead) {
501 continue;
502 }
503 rc = LnnSendLeaveRequestToConnFsm(item);
504 if (rc != SOFTBUS_OK) {
505 LNN_LOGE(LNN_BUILDER, "send leave LNN msg to connection failed. fsmId=%{public}u", item->id);
506 } else {
507 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_REQUEST;
508 LNN_LOGI(LNN_BUILDER, "send leave LNN msg to connection success. fsmId=%{public}u", item->id);
509 }
510 }
511 if (rc != SOFTBUS_OK) {
512 LnnNotifyLeaveResult(networkId, SOFTBUS_NETWORK_REQ_LEAVE_LNN_FAIL);
513 }
514 SoftBusFree((void *)networkId);
515 return rc;
516 }
517
ProcessSyncOfflineFinish(const void * para)518 static int32_t ProcessSyncOfflineFinish(const void *para)
519 {
520 const char *networkId = (const char *)para;
521 LnnConnectionFsm *item = NULL;
522 int rc = SOFTBUS_OK;
523
524 if (networkId == NULL) {
525 LNN_LOGW(LNN_BUILDER, "sync offline finish networkId is null");
526 return SOFTBUS_INVALID_PARAM;
527 }
528 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
529 if (strcmp(networkId, item->connInfo.peerNetworkId) != 0 || item->isDead) {
530 continue;
531 }
532 rc = LnnSendSyncOfflineFinishToConnFsm(item);
533 LNN_LOGI(LNN_BUILDER, "send sync offline msg to connection fsmId=%{public}u, result=%{public}d", item->id, rc);
534 }
535 SoftBusFree((void *)networkId);
536 return rc;
537 }
538
ProcessLeaveInvalidConn(const void * para)539 static int32_t ProcessLeaveInvalidConn(const void *para)
540 {
541 LnnConnectionFsm *item = NULL;
542 int32_t rc = SOFTBUS_OK;
543 int32_t count = 0;
544 const LeaveInvalidConnMsgPara *msgPara = (const LeaveInvalidConnMsgPara *)para;
545
546 if (msgPara == NULL) {
547 LNN_LOGW(LNN_BUILDER, "leave invalid connection msg para is null");
548 return SOFTBUS_INVALID_PARAM;
549 }
550 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
551 if (!IsInvalidConnectionFsm(item, msgPara)) {
552 continue;
553 }
554 // The new connFsm should timeout when following errors occur
555 ++count;
556 item->connInfo.cleanInfo = (LnnInvalidCleanInfo *)SoftBusMalloc(sizeof(LnnInvalidCleanInfo));
557 if (item->connInfo.cleanInfo == NULL) {
558 LNN_LOGI(LNN_BUILDER, "malloc invalid clean info failed. fsmId=%{public}u", item->id);
559 continue;
560 }
561 item->connInfo.cleanInfo->addrType = msgPara->addrType;
562 if (strncpy_s(item->connInfo.cleanInfo->networkId, NETWORK_ID_BUF_LEN,
563 msgPara->newNetworkId, strlen(msgPara->newNetworkId)) != EOK) {
564 LNN_LOGE(LNN_BUILDER, "copy new networkId failed. fsmId=%{public}u", item->id);
565 rc = SOFTBUS_STRCPY_ERR;
566 SoftBusFree(item->connInfo.cleanInfo);
567 item->connInfo.cleanInfo = NULL;
568 continue;
569 }
570 rc = LnnSendLeaveRequestToConnFsm(item);
571 if (rc == SOFTBUS_OK) {
572 item->connInfo.flag |= LNN_CONN_INFO_FLAG_INITIATE_ONLINE;
573 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_AUTO;
574 } else {
575 SoftBusFree(item->connInfo.cleanInfo);
576 item->connInfo.cleanInfo = NULL;
577 }
578 LNN_LOGI(
579 LNN_BUILDER, "send leave LNN msg to invalid connection. fsmId=%{public}u, result=%{public}d", item->id, rc);
580 }
581 if (count == 0) {
582 InitiateNewNetworkOnline(msgPara->addrType, msgPara->newNetworkId);
583 }
584 SoftBusFree((void *)msgPara);
585 return rc;
586 }
587
ProcessNodeStateChanged(const void * para)588 static int32_t ProcessNodeStateChanged(const void *para)
589 {
590 const ConnectionAddr *addr = (const ConnectionAddr *)para;
591 LnnConnectionFsm *connFsm = NULL;
592 int32_t rc = SOFTBUS_NETWORK_NOT_FOUND;
593 bool isOnline = false;
594
595 if (addr == NULL) {
596 LNN_LOGW(LNN_BUILDER, "node state changed msg is null");
597 return SOFTBUS_INVALID_PARAM;
598 }
599 do {
600 connFsm = FindConnectionFsmByAddr(addr, false);
601 if (connFsm == NULL) {
602 LNN_LOGE(LNN_BUILDER, "can't find connection fsm when node online state changed");
603 break;
604 }
605 isOnline = IsNodeOnline(connFsm->connInfo.peerNetworkId);
606 TryElectAsMasterState(connFsm->connInfo.peerNetworkId, isOnline);
607 if (!IsSupportMasterNodeElect(connFsm->connInfo.version)) {
608 LNN_LOGI(LNN_BUILDER, "peer not support master node elect. fsmId=%{public}u", connFsm->id);
609 rc = SOFTBUS_OK;
610 break;
611 }
612 rc = isOnline ? TryElectMasterNodeOnline(connFsm) : TryElectMasterNodeOffline(connFsm);
613 } while (false);
614 SoftBusFree((void *)addr);
615 if (isOnline) {
616 TryRemovePendingJoinRequest();
617 }
618 return rc;
619 }
620
ProcessMasterElect(const void * para)621 static int32_t ProcessMasterElect(const void *para)
622 {
623 const ElectMsgPara *msgPara = (const ElectMsgPara *)para;
624 LnnConnectionFsm *connFsm = NULL;
625 char localMasterUdid[UDID_BUF_LEN] = { 0 };
626 int32_t localMasterWeight;
627 int32_t compareRet;
628 int32_t rc = SOFTBUS_NETWORK_NOT_FOUND;
629
630 if (msgPara == NULL) {
631 LNN_LOGW(LNN_BUILDER, "elect msg para is null");
632 return SOFTBUS_INVALID_PARAM;
633 }
634 do {
635 connFsm = FindConnectionFsmByNetworkId(msgPara->networkId);
636 if (connFsm == NULL || connFsm->isDead) {
637 LNN_LOGE(LNN_BUILDER, "can't find connection fsm when receive elect node");
638 break;
639 }
640 if (!IsNodeOnline(connFsm->connInfo.peerNetworkId)) {
641 LNN_LOGE(LNN_BUILDER, "peer node is already offline. fsmId=%{public}u", connFsm->id);
642 break;
643 }
644 if (LnnGetLocalStrInfo(STRING_KEY_MASTER_NODE_UDID, localMasterUdid, UDID_BUF_LEN) != SOFTBUS_OK ||
645 LnnGetLocalNumInfo(NUM_KEY_MASTER_NODE_WEIGHT, &localMasterWeight) != SOFTBUS_OK) {
646 LNN_LOGE(LNN_BUILDER, "get local master node info from ledger failed. fsmId=%{public}u", connFsm->id);
647 break;
648 }
649 compareRet = LnnCompareNodeWeight(localMasterWeight, localMasterUdid,
650 msgPara->masterWeight, msgPara->masterUdid);
651 LNN_LOGI(LNN_BUILDER, "weight compare result: fsmId=%{public}u, result=%{public}d", connFsm->id, compareRet);
652 if (compareRet != 0) {
653 if (compareRet < 0) {
654 UpdateLocalMasterNode(false, msgPara->masterUdid, msgPara->masterWeight);
655 SendElectMessageToAll(connFsm->connInfo.peerNetworkId);
656 } else {
657 rc = SyncElectMessage(connFsm->connInfo.peerNetworkId);
658 LNN_LOGI(LNN_BUILDER, "sync elect info to connFsmId=%{public}u, result=%{public}d", connFsm->id, rc);
659 }
660 }
661 rc = SOFTBUS_OK;
662 } while (false);
663 SoftBusFree((void *)msgPara);
664 return rc;
665 }
666
ProcessLeaveByAddrType(const void * para)667 static int32_t ProcessLeaveByAddrType(const void *para)
668 {
669 bool *addrType = NULL;
670 LnnConnectionFsm *item = NULL;
671 int32_t rc;
672 bool notify = true;
673
674 if (para == NULL) {
675 LNN_LOGW(LNN_BUILDER, "leave by addr type msg para is null");
676 return SOFTBUS_INVALID_PARAM;
677 }
678
679 addrType = (bool *)para;
680 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
681 if (!addrType[item->connInfo.addr.type]) {
682 continue;
683 }
684 // if there are any same addr type, let last one send notify
685 notify = false;
686 if (item->isDead) {
687 continue;
688 }
689 rc = LnnSendLeaveRequestToConnFsm(item);
690 LNN_LOGI(LNN_BUILDER, "leave conn by addr. fsmId=%{public}u, type=%{public}d, rc=%{public}d", item->id,
691 item->connInfo.addr.type, rc);
692 if (rc == SOFTBUS_OK) {
693 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_AUTO;
694 }
695 }
696 LNN_LOGD(LNN_BUILDER, "notify=%{public}d, eth=%{public}d, wifi=%{public}d", notify, addrType[CONNECTION_ADDR_ETH],
697 addrType[CONNECTION_ADDR_WLAN]);
698 if (notify && (addrType[CONNECTION_ADDR_ETH] || addrType[CONNECTION_ADDR_WLAN])) {
699 (void)LnnNotifyAllTypeOffline(CONNECTION_ADDR_MAX);
700 }
701 RemovePendingRequestByAddrType(addrType, CONNECTION_ADDR_MAX);
702 SoftBusFree((void *)para);
703 return SOFTBUS_OK;
704 }
705
ProcessLeaveSpecific(const void * para)706 static int32_t ProcessLeaveSpecific(const void *para)
707 {
708 const SpecificLeaveMsgPara *msgPara = (const SpecificLeaveMsgPara *)para;
709 LnnConnectionFsm *item = NULL;
710
711 if (msgPara == NULL) {
712 LNN_LOGW(LNN_BUILDER, "leave specific msg is null");
713 return SOFTBUS_INVALID_PARAM;
714 }
715
716 int32_t rc;
717 bool deviceLeave = false;
718 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
719 if (strcmp(item->connInfo.peerNetworkId, msgPara->networkId) != 0 ||
720 (item->connInfo.addr.type != msgPara->addrType &&
721 msgPara->addrType != CONNECTION_ADDR_MAX)) {
722 continue;
723 }
724 deviceLeave = true;
725 rc = LnnSendLeaveRequestToConnFsm(item);
726 if (rc == SOFTBUS_OK) {
727 item->connInfo.flag |= LNN_CONN_INFO_FLAG_LEAVE_AUTO;
728 }
729 LNN_LOGI(LNN_BUILDER, "send leave LNN msg to connection. fsmId=%{public}u, result=%{public}d", item->id, rc);
730 }
731
732 if (deviceLeave) {
733 SoftBusFree((void *)msgPara);
734 return SOFTBUS_OK;
735 }
736
737 do {
738 NodeInfo nodeInfo;
739 (void)memset_s(&nodeInfo, sizeof(NodeInfo), 0, sizeof(NodeInfo));
740 if (LnnGetRemoteNodeInfoById(msgPara->networkId, CATEGORY_NETWORK_ID, &nodeInfo)) {
741 break;
742 }
743
744 if (nodeInfo.deviceInfo.deviceTypeId != TYPE_PC_ID ||
745 strcmp(nodeInfo.networkId, nodeInfo.deviceInfo.deviceUdid) != 0) {
746 break;
747 }
748
749 (void)LnnClearDiscoveryType(&nodeInfo, LnnConvAddrTypeToDiscType(msgPara->addrType));
750 if (nodeInfo.discoveryType != 0) {
751 LNN_LOGI(LNN_BUILDER, "pc without softbus has another discovery type");
752 break;
753 }
754
755 LNN_LOGI(LNN_BUILDER, "pc without softbus offline");
756 DeleteFromProfile(nodeInfo.deviceInfo.deviceUdid);
757 LnnRemoveNode(nodeInfo.deviceInfo.deviceUdid);
758 } while (false);
759 SoftBusFree((void *)msgPara);
760 return SOFTBUS_OK;
761 }
762
ProcessLeaveByAuthId(const void * para)763 static int32_t ProcessLeaveByAuthId(const void *para)
764 {
765 int32_t rc = SOFTBUS_OK;
766 const int64_t *authId = (const int64_t *)para;
767 if (authId == NULL) {
768 LNN_LOGE(LNN_BUILDER, "authId is null");
769 return SOFTBUS_INVALID_PARAM;
770 }
771 LnnConnectionFsm *item = NULL;
772 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
773 if (item->connInfo.authHandle.authId != *authId || item->isDead) {
774 continue;
775 }
776 LNN_LOGI(LNN_BUILDER, "[id=%{public}u]leave reqeust, authId: %{public}" PRId64, item->id, *authId);
777 rc = LnnSendLeaveRequestToConnFsm(item);
778 if (rc != SOFTBUS_OK) {
779 LNN_LOGE(LNN_BUILDER, "send leaveReqeust to connection fsm[id=%{public}u] failed", item->id);
780 }
781 }
782 SoftBusFree((void *) authId);
783 return rc;
784 }
785
ProcessSetReSyncDeviceName(const void * para)786 static int32_t ProcessSetReSyncDeviceName(const void *para)
787 {
788 (void)para;
789 LnnConnectionFsm *item = NULL;
790 LIST_FOR_EACH_ENTRY(item, &LnnGetNetBuilder()->fsmList, LnnConnectionFsm, node) {
791 if (!item->isDead && (item->connInfo.flag & LNN_CONN_INFO_FLAG_ONLINE) != 0) {
792 if (item->connInfo.nodeInfo != NULL) {
793 LNN_LOGI(LNN_BUILDER, "[id=%{public}u] need resync device name, authId: %{public}" PRId64, item->id,
794 item->connInfo.authHandle.authId);
795 item->connInfo.nodeInfo->isNeedReSyncDeviceName = true;
796 }
797 }
798 }
799 if (para != NULL) {
800 SoftBusFree((void *)para);
801 para = NULL;
802 }
803 return SOFTBUS_OK;
804 }
805
806 static NetBuilderMessageProcess g_messageProcessor[MSG_TYPE_BUILD_MAX] = {
807 ProcessJoinLNNRequest,
808 ProcessDevDiscoveryRequest,
809 ProcessCleanConnectionFsm,
810 ProcessVerifyResult,
811 ProcessDeviceVerifyPass,
812 ProcessDeviceDisconnect,
813 ProcessDeviceNotTrusted,
814 ProcessLeaveLNNRequest,
815 ProcessSyncOfflineFinish,
816 ProcessNodeStateChanged,
817 ProcessMasterElect,
818 ProcessLeaveInvalidConn,
819 ProcessLeaveByAddrType,
820 ProcessLeaveSpecific,
821 ProcessLeaveByAuthId,
822 ProcessSetReSyncDeviceName,
823 };
824
NetBuilderMessageHandler(SoftBusMessage * msg)825 void NetBuilderMessageHandler(SoftBusMessage *msg)
826 {
827 int32_t ret;
828
829 if (msg == NULL) {
830 LNN_LOGE(LNN_BUILDER, "msg is null in net builder handler");
831 return;
832 }
833 LNN_LOGI(LNN_BUILDER, "net builder process msg=%{public}d", msg->what);
834 if (msg->what >= MSG_TYPE_BUILD_MAX) {
835 LNN_LOGE(LNN_BUILDER, "invalid msg type");
836 return;
837 }
838 ret = g_messageProcessor[msg->what](msg->obj);
839 LNN_LOGD(LNN_BUILDER, "net builder process msg done, msg=%{public}d, ret=%{public}d", msg->what, ret);
840 }