1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "lnn_topo_manager.h"
17
18 #include <securec.h>
19
20 #include "bus_center_event.h"
21 #include "bus_center_manager.h"
22 #include "common_list.h"
23 #include "lnn_async_callback_utils.h"
24 #include "lnn_distributed_net_ledger.h"
25 #include "lnn_sync_info_manager.h"
26 #include "softbus_adapter_crypto.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_adapter_thread.h"
29 #include "softbus_def.h"
30 #include "softbus_errcode.h"
31 #include "softbus_feature_config.h"
32 #include "softbus_json_utils.h"
33 #include "softbus_adapter_json.h"
34 #include "softbus_log.h"
35
36 #define JSON_KEY_TYPE "type"
37 #define JSON_KEY_SEQ "seq"
38 #define JSON_KEY_COMPLETE "complete"
39 #define JSON_KEY_INFO "info"
40 #define JSON_KEY_TYPE "type"
41 #define JSON_KEY_UDID "udid"
42 #define JSON_KEY_PEER_UDID "peerUdid"
43 #define JSON_KEY_WLAN_RELATION "wlanRelation"
44 #define JSON_KEY_BR_RELATION "brRelation"
45 #define JSON_KEY_BLE_RELATION "bleRelation"
46 #define JSON_KEY_ETH_RELATION "ethRelation"
47
48 #define LNN_RELATION_JOIN_THREAD 1
49 #define RELATION_CHANGED_MSG_DELAY (5 * 1000)
50
51 #define TOPO_HASH_TABLE_SIZE 16
52
53 typedef enum {
54 TOPO_MSG_TYPE_UPDATE,
55 } TopoUpdateMsgType;
56
57 typedef enum {
58 TOPO_MSG_FLAG_NOT_COMPLETE = 0,
59 TOPO_MSG_FLAG_COMPLETE,
60 } TopoUpdateMsgFlag;
61
62 typedef struct {
63 ListNode table[TOPO_HASH_TABLE_SIZE];
64 bool isSupportTopo;
65 uint32_t totalCount;
66 SoftBusMutex lock;
67 } TopoHashTable;
68
69 typedef struct {
70 ListNode node;
71 char udid[UDID_BUF_LEN];
72 uint32_t count;
73 ListNode joinList;
74 } TopoTableItem;
75
76 typedef struct {
77 ListNode node;
78 char peerUdid[UDID_BUF_LEN];
79 uint8_t relation[CONNECTION_ADDR_MAX];
80 } TopoInfo;
81
82 static TopoHashTable g_topoTable;
83
RouteLnnRelationEventHandler(const LnnRelationChangedMsg * msg)84 void __attribute__((weak)) RouteLnnRelationEventHandler(const LnnRelationChangedMsg *msg)
85 {
86 (void)msg;
87 }
88
IsSameRelation(const uint8_t * newRelation,const uint8_t * oldRelation,uint32_t len)89 static bool IsSameRelation(const uint8_t *newRelation, const uint8_t *oldRelation, uint32_t len)
90 {
91 uint32_t i;
92
93 for (i = 0; i < len; ++i) {
94 if ((newRelation[i] != 0 && oldRelation[i] == 0) || (newRelation[i] == 0 && oldRelation[i] != 0)) {
95 return false;
96 }
97 }
98 return true;
99 }
100
HasRelation(const uint8_t * relation,uint32_t len)101 static bool HasRelation(const uint8_t *relation, uint32_t len)
102 {
103 uint32_t i;
104
105 for (i = 0; i < len; ++i) {
106 if (relation[i] > 0) {
107 return true;
108 }
109 }
110 return false;
111 }
112
HashIndex(const char * udid)113 static uint32_t HashIndex(const char *udid)
114 {
115 return ((*(const uint32_t *)udid) % TOPO_HASH_TABLE_SIZE);
116 }
117
CreateTopoItem(const char * udid)118 static TopoTableItem *CreateTopoItem(const char *udid)
119 {
120 TopoTableItem *item = (TopoTableItem *)SoftBusMalloc(sizeof(TopoTableItem));
121 if (item == NULL) {
122 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "malloc topo item fail");
123 return NULL;
124 }
125 ListInit(&item->joinList);
126 ListInit(&item->node);
127 item->count = 0;
128 if (strcpy_s(item->udid, UDID_BUF_LEN, udid) != EOK) {
129 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "copy udid to topo item fail");
130 SoftBusFree(item);
131 return NULL;
132 }
133 return item;
134 }
135
CreateTopoInfo(const char * udid,const uint8_t * relation,uint32_t len)136 static TopoInfo *CreateTopoInfo(const char *udid, const uint8_t *relation, uint32_t len)
137 {
138 TopoInfo *info = (TopoInfo *)SoftBusMalloc(sizeof(TopoInfo));
139 if (info == NULL) {
140 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "malloc topo info fail");
141 return NULL;
142 }
143 ListInit(&info->node);
144 if (strcpy_s(info->peerUdid, UDID_BUF_LEN, udid) != EOK ||
145 memcpy_s(info->relation, CONNECTION_ADDR_MAX, relation, len) != EOK) {
146 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "copy info to topo info fail");
147 SoftBusFree(info);
148 return NULL;
149 }
150 return info;
151 }
152
FindTopoItem(const char * udid)153 static TopoTableItem *FindTopoItem(const char *udid)
154 {
155 TopoTableItem *item = NULL;
156
157 LIST_FOR_EACH_ENTRY(item, &g_topoTable.table[HashIndex(udid)], TopoTableItem, node) {
158 if (strcmp(item->udid, udid) == 0) {
159 return item;
160 }
161 }
162 return NULL;
163 }
164
FindTopoInfo(const char * udid,const char * peerUdid,TopoTableItem ** item,TopoInfo ** info)165 static int32_t FindTopoInfo(const char *udid, const char *peerUdid, TopoTableItem **item, TopoInfo **info)
166 {
167 TopoTableItem *topoItem = NULL;
168 TopoInfo *topoInfo = NULL;
169 const char *compareUdid = peerUdid;
170
171 topoItem = FindTopoItem(udid);
172 if (topoItem == NULL) {
173 topoItem = FindTopoItem(peerUdid);
174 if (topoItem != NULL) {
175 compareUdid = udid;
176 }
177 }
178 if (topoItem == NULL) {
179 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "topo item not exist");
180 return SOFTBUS_NOT_FIND;
181 }
182 *item = topoItem;
183 LIST_FOR_EACH_ENTRY(topoInfo, &topoItem->joinList, TopoInfo, node) {
184 if (strcmp(compareUdid, topoInfo->peerUdid) == 0) {
185 *info = topoInfo;
186 return SOFTBUS_OK;
187 }
188 }
189 return SOFTBUS_NOT_FIND;
190 }
191
ClearTopoTable(void)192 static void ClearTopoTable(void)
193 {
194 TopoTableItem *item = NULL;
195 TopoTableItem *itemNext = NULL;
196 TopoInfo *info = NULL;
197 TopoInfo *infoNext = NULL;
198 uint32_t i;
199
200 for (i = 0; i < TOPO_HASH_TABLE_SIZE; ++i) {
201 LIST_FOR_EACH_ENTRY_SAFE(item, itemNext, &g_topoTable.table[i], TopoTableItem, node) {
202 LIST_FOR_EACH_ENTRY_SAFE(info, infoNext, &item->joinList, TopoInfo, node) {
203 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "delete topo info, local:%s, peer:%s",
204 AnonymizesUDID(item->udid), AnonymizesUDID(info->peerUdid));
205 ListDelete(&info->node);
206 SoftBusFree(info);
207 }
208 ListDelete(&item->node);
209 SoftBusFree(item);
210 }
211 }
212 g_topoTable.totalCount = 0;
213 }
214
PackCommonTopoMsg(cJSON ** json,cJSON ** info)215 static int32_t PackCommonTopoMsg(cJSON **json, cJSON **info)
216 {
217 int32_t seq;
218
219 if (SoftBusGenerateRandomArray((uint8_t *)&seq, sizeof(uint32_t)) != SOFTBUS_OK) {
220 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "generate seq fail");
221 return SOFTBUS_ERR;
222 }
223 if (seq < 0) {
224 seq = -seq;
225 }
226 *json = cJSON_CreateObject();
227 if (*json == NULL) {
228 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "create topo update json fail");
229 return SOFTBUS_ERR;
230 }
231 if (!AddNumberToJsonObject(*json, JSON_KEY_TYPE, TOPO_MSG_TYPE_UPDATE) ||
232 !AddNumberToJsonObject(*json, JSON_KEY_SEQ, seq) ||
233 !AddNumberToJsonObject(*json, JSON_KEY_COMPLETE, TOPO_MSG_FLAG_COMPLETE)) {
234 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "pack topo common json fail");
235 cJSON_Delete(*json);
236 return SOFTBUS_ERR;
237 }
238 *info = cJSON_CreateArray();
239 if (*info == NULL) {
240 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "create topo info json fail");
241 cJSON_Delete(*json);
242 return SOFTBUS_ERR;
243 }
244 if (!cJSON_AddItemToObject(*json, JSON_KEY_INFO, *info)) {
245 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "pack topo info json to msg fail");
246 cJSON_Delete(*info);
247 cJSON_Delete(*json);
248 return SOFTBUS_ERR;
249 }
250 return SOFTBUS_OK;
251 }
252
PackTopoInfo(cJSON * info,const char * udid,const char * peerUdid,const uint8_t * relation,uint32_t len)253 static int32_t PackTopoInfo(cJSON *info, const char *udid, const char *peerUdid,
254 const uint8_t *relation, uint32_t len)
255 {
256 cJSON *item = cJSON_CreateObject();
257 if (item == NULL) {
258 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "create topo info json fail");
259 return SOFTBUS_ERR;
260 }
261 if (len != CONNECTION_ADDR_MAX) {
262 cJSON_Delete(item);
263 return SOFTBUS_INVALID_PARAM;
264 }
265 if (!AddStringToJsonObject(item, JSON_KEY_UDID, udid) ||
266 !AddStringToJsonObject(item, JSON_KEY_PEER_UDID, peerUdid)) {
267 cJSON_Delete(item);
268 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "pack topo udid json fail");
269 return SOFTBUS_ERR;
270 }
271 if (!AddNumberToJsonObject(item, JSON_KEY_WLAN_RELATION, relation[CONNECTION_ADDR_WLAN]) ||
272 !AddNumberToJsonObject(item, JSON_KEY_BR_RELATION, relation[CONNECTION_ADDR_BR]) ||
273 !AddNumberToJsonObject(item, JSON_KEY_BLE_RELATION, relation[CONNECTION_ADDR_BLE]) ||
274 !AddNumberToJsonObject(item, JSON_KEY_ETH_RELATION, relation[CONNECTION_ADDR_ETH]) ||
275 !cJSON_AddItemToArray(info, item)) {
276 cJSON_Delete(item);
277 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "pack topo relation json fail");
278 return SOFTBUS_ERR;
279 }
280 return SOFTBUS_OK;
281 }
282
PackOneLnnRelation(const char * udid,const char * peerUdid,const uint8_t * relation,uint32_t len)283 static const char *PackOneLnnRelation(const char *udid, const char *peerUdid,
284 const uint8_t *relation, uint32_t len)
285 {
286 cJSON *json = NULL;
287 cJSON *info = NULL;
288 const char *msg = NULL;
289
290 if (PackCommonTopoMsg(&json, &info) != SOFTBUS_OK) {
291 return NULL;
292 }
293 if (PackTopoInfo(info, udid, peerUdid, relation, len) != SOFTBUS_OK) {
294 cJSON_Delete(json);
295 return NULL;
296 }
297 msg = cJSON_PrintUnformatted(json);
298 if (msg == NULL) {
299 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "format lnn relation json fail");
300 }
301 cJSON_Delete(json);
302 return msg;
303 }
304
AddTopoInfo(const char * udid,const char * peerUdid,const uint8_t * relation,uint32_t len)305 static int32_t AddTopoInfo(const char *udid, const char *peerUdid, const uint8_t *relation, uint32_t len)
306 {
307 TopoTableItem *topoItem = NULL;
308 TopoInfo *topoInfo = NULL;
309 bool isKeyUdid = true;
310 bool isCreateTopoItem = false;
311
312 topoItem = FindTopoItem(udid);
313 if (topoItem == NULL) {
314 topoItem = FindTopoItem(peerUdid);
315 if (topoItem != NULL) {
316 isKeyUdid = false;
317 }
318 }
319 if (topoItem == NULL) {
320 topoItem = CreateTopoItem(udid);
321 if (topoItem == NULL) {
322 return SOFTBUS_MEM_ERR;
323 }
324 ListAdd(&g_topoTable.table[HashIndex(udid)], &topoItem->node);
325 isCreateTopoItem = true;
326 }
327 topoInfo = CreateTopoInfo(isKeyUdid ? peerUdid : udid, relation, len);
328 if (topoInfo == NULL) {
329 if (isCreateTopoItem) {
330 ListDelete(&topoItem->node);
331 SoftBusFree(topoItem);
332 }
333 return SOFTBUS_MEM_ERR;
334 }
335 ListAdd(&topoItem->joinList, &topoInfo->node);
336 topoItem->count++;
337 g_topoTable.totalCount++;
338 return SOFTBUS_OK;
339 }
340
UpdateLocalTopo(const char * udid,const char * peerUdid,const uint8_t * relation,uint32_t len)341 static int32_t UpdateLocalTopo(const char *udid, const char *peerUdid, const uint8_t *relation, uint32_t len)
342 {
343 TopoTableItem *topoItem = NULL;
344 TopoInfo *topoInfo = NULL;
345 bool hasRelation = HasRelation(relation, len);
346
347 if (FindTopoInfo(udid, peerUdid, &topoItem, &topoInfo) != SOFTBUS_OK) {
348 if (!hasRelation) {
349 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "topo info not exist when delete");
350 return SOFTBUS_NOT_FIND;
351 }
352 if (AddTopoInfo(udid, peerUdid, relation, len) != SOFTBUS_OK) {
353 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "add topo info fail");
354 return SOFTBUS_MEM_ERR;
355 }
356 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "add topo info: local:%s peer:%s",
357 AnonymizesUDID(udid), AnonymizesUDID(peerUdid));
358 } else {
359 if (IsSameRelation(topoInfo->relation, relation, len)) {
360 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "relation are same");
361 return SOFTBUS_ERR;
362 }
363 if (memcpy_s(topoInfo->relation, CONNECTION_ADDR_MAX, relation, len) != EOK) {
364 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "memcpy topo info relation fail");
365 return SOFTBUS_MEM_ERR;
366 }
367 if (!hasRelation) {
368 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "delete topo info: local:%s peer:%s",
369 AnonymizesUDID(topoItem->udid), AnonymizesUDID(topoInfo->peerUdid));
370 ListDelete(&topoInfo->node);
371 SoftBusFree(topoInfo);
372 topoItem->count--;
373 g_topoTable.totalCount--;
374 }
375 if (IsListEmpty(&topoItem->joinList)) {
376 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "delete topo item");
377 ListDelete(&topoItem->node);
378 SoftBusFree(topoItem);
379 }
380 }
381 return SOFTBUS_OK;
382 }
383
ForwardTopoMsgToAll(const char * networkId,const uint8_t * msg,uint32_t len)384 static void ForwardTopoMsgToAll(const char *networkId, const uint8_t *msg, uint32_t len)
385 {
386 NodeBasicInfo *info = NULL;
387 int32_t infoNum, i;
388
389 if (LnnGetAllOnlineNodeInfo(&info, &infoNum) != SOFTBUS_OK) {
390 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "get all online node info fail");
391 return;
392 }
393 for (i = 0; i < infoNum; ++i) {
394 if (LnnIsLSANode(&info[i])) {
395 continue;
396 }
397 if (strcmp(networkId, info[i].networkId) == 0) {
398 continue;
399 }
400 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "forward topo update msg");
401 if (LnnSendSyncInfoMsg(LNN_INFO_TYPE_TOPO_UPDATE, info[i].networkId, msg, len, NULL) != SOFTBUS_OK) {
402 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "sync topo update fail");
403 }
404 }
405 SoftBusFree(info);
406 }
407
TryCorrectRelation(const char * networkId,const char * udid,const char * peerUdid,const uint8_t * relation,uint32_t len)408 static void TryCorrectRelation(const char *networkId, const char *udid, const char *peerUdid,
409 const uint8_t *relation, uint32_t len)
410 {
411 uint8_t correctRelation[CONNECTION_ADDR_MAX] = {0};
412 const char *msg = NULL;
413 char localUdid[UDID_BUF_LEN];
414 const char *keyUdid = udid;
415
416 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN) != 0) {
417 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "read local udid fail");
418 return;
419 }
420 if (strcmp(localUdid, udid) == 0) {
421 keyUdid = peerUdid;
422 }
423 LnnGetLnnRelation(keyUdid, CATEGORY_UDID, correctRelation, CONNECTION_ADDR_MAX);
424 if (IsSameRelation(correctRelation, relation, len)) {
425 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "relation are ok, no need correct");
426 return;
427 }
428 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "relation not right and notify update: %d",
429 HasRelation(correctRelation, CONNECTION_ADDR_MAX));
430 msg = PackOneLnnRelation(udid, peerUdid, correctRelation, CONNECTION_ADDR_MAX);
431 if (msg == NULL) {
432 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "pack correct lnn relation msg fail");
433 return;
434 }
435 if (LnnSendSyncInfoMsg(LNN_INFO_TYPE_TOPO_UPDATE, networkId, (const uint8_t *)msg,
436 strlen(msg) + 1, NULL) != SOFTBUS_OK) {
437 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "sync correct lnn relation msg fail");
438 }
439 cJSON_free((void *)msg);
440 }
441
ProcessTopoUpdateInfo(cJSON * json,const char * networkId,const uint8_t * msg,uint32_t len)442 static void ProcessTopoUpdateInfo(cJSON *json, const char *networkId, const uint8_t *msg, uint32_t len)
443 {
444 char udid[UDID_BUF_LEN], peerUdid[UDID_BUF_LEN];
445 uint8_t relation[CONNECTION_ADDR_MAX];
446 int32_t value;
447 cJSON *item = NULL;
448 char localUdid[UDID_BUF_LEN];
449 bool needForward = false;
450 cJSON *info = cJSON_GetObjectItemCaseSensitive(json, JSON_KEY_INFO);
451 if (!cJSON_IsArray(info)) {
452 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "topo update msg not contain info");
453 return;
454 }
455 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN) != 0) {
456 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "read local udid fail");
457 return;
458 }
459 cJSON_ArrayForEach(item, info) {
460 if (!GetJsonObjectStringItem(item, JSON_KEY_UDID, udid, UDID_BUF_LEN) ||
461 !GetJsonObjectStringItem(item, JSON_KEY_PEER_UDID, peerUdid, UDID_BUF_LEN)) {
462 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "parse topo update for uuid fail");
463 continue;
464 }
465 if (strlen(udid) == 0 || strlen(peerUdid) == 0) {
466 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid uuid in topo update msg");
467 continue;
468 }
469 (void)GetJsonObjectNumberItem(item, JSON_KEY_WLAN_RELATION, &value);
470 relation[CONNECTION_ADDR_WLAN] = (uint8_t)value;
471 (void)GetJsonObjectNumberItem(item, JSON_KEY_BR_RELATION, &value);
472 relation[CONNECTION_ADDR_BR] = (uint8_t)value;
473 (void)GetJsonObjectNumberItem(item, JSON_KEY_BLE_RELATION, &value);
474 relation[CONNECTION_ADDR_BLE] = (uint8_t)value;
475 (void)GetJsonObjectNumberItem(item, JSON_KEY_ETH_RELATION, &value);
476 relation[CONNECTION_ADDR_ETH] = (uint8_t)value;
477 if (strcmp(localUdid, udid) == 0 || strcmp(localUdid, peerUdid) == 0) {
478 TryCorrectRelation(networkId, udid, peerUdid, relation, CONNECTION_ADDR_MAX);
479 continue;
480 }
481 if (UpdateLocalTopo(udid, peerUdid, relation, CONNECTION_ADDR_MAX) == SOFTBUS_OK) {
482 needForward = true;
483 }
484 }
485 if (needForward) {
486 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "notify local topo to others");
487 ForwardTopoMsgToAll(networkId, msg, len);
488 }
489 }
490
OnReceiveTopoUpdateMsg(LnnSyncInfoType type,const char * networkId,const uint8_t * msg,uint32_t len)491 static void OnReceiveTopoUpdateMsg(LnnSyncInfoType type, const char *networkId, const uint8_t *msg, uint32_t len)
492 {
493 cJSON *json = NULL;
494 int32_t topoMsgType, seq, complete;
495
496 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "recv topo update msg, type:%d, len:%d", type, len);
497 if (type != LNN_INFO_TYPE_TOPO_UPDATE) {
498 return;
499 }
500 json = cJSON_ParseWithLength((char *)msg, (size_t)len);
501 if (json == NULL) {
502 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "cjson parse topo msg fail");
503 return;
504 }
505 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "recv topo update msg");
506 if (!GetJsonObjectNumberItem(json, JSON_KEY_TYPE, &topoMsgType) ||
507 !GetJsonObjectNumberItem(json, JSON_KEY_SEQ, &seq) ||
508 !GetJsonObjectNumberItem(json, JSON_KEY_COMPLETE, &complete)) {
509 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "cjson parse topo common info fail");
510 cJSON_Delete(json);
511 return;
512 }
513 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "topoMsgType:%d, seq:%d, complete:%d", topoMsgType, seq, complete);
514 if (topoMsgType != TOPO_MSG_TYPE_UPDATE || complete != TOPO_MSG_FLAG_COMPLETE) {
515 cJSON_Delete(json);
516 return;
517 }
518 if (SoftBusMutexLock(&g_topoTable.lock) != SOFTBUS_OK) {
519 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lock topo table fail");
520 cJSON_Delete(json);
521 return;
522 }
523 ProcessTopoUpdateInfo(json, networkId, msg, len);
524 cJSON_Delete(json);
525 (void)SoftBusMutexUnlock(&g_topoTable.lock);
526 }
527
OnLnnRelationChangedDelay(void * para)528 static void OnLnnRelationChangedDelay(void *para)
529 {
530 LnnRelationChangedMsg *msg = (LnnRelationChangedMsg *)para;
531 if (msg == NULL) {
532 return;
533 }
534 RouteLnnRelationEventHandler(msg);
535 SoftBusFree(msg);
536 return;
537 }
538
OnLnnRelationChanged(const LnnEventBasicInfo * info)539 static void OnLnnRelationChanged(const LnnEventBasicInfo *info)
540 {
541 const LnnRelationChanedEventInfo *eventInfo = (const LnnRelationChanedEventInfo *)info;
542 LnnRelationChangedMsg *msg = NULL;
543
544 if (info == NULL || info->event != LNN_EVENT_RELATION_CHANGED) {
545 return;
546 }
547 if (eventInfo->udid == NULL || eventInfo->type == CONNECTION_ADDR_MAX) {
548 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid relation changed params");
549 return;
550 }
551 msg = (LnnRelationChangedMsg *)SoftBusMalloc(sizeof(LnnRelationChangedMsg));
552 if (msg == NULL) {
553 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "malloc relation changed msg fail");
554 return;
555 }
556 msg->type = eventInfo->type;
557 msg->relation = eventInfo->relation;
558 msg->isJoin = eventInfo->isJoin;
559 if (strcpy_s(msg->udid, UDID_BUF_LEN, eventInfo->udid) != EOK) {
560 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "copy udid to relation changed msg fail");
561 SoftBusFree(msg);
562 return;
563 }
564 if (LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), OnLnnRelationChangedDelay, (void *)msg,
565 RELATION_CHANGED_MSG_DELAY) != SOFTBUS_OK) {
566 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "async relation changed msg delay fail");
567 SoftBusFree(msg);
568 }
569 }
570
FillAllRelation(LnnRelation * relation,uint32_t relationNum)571 static int32_t FillAllRelation(LnnRelation *relation, uint32_t relationNum)
572 {
573 TopoTableItem *item = NULL;
574 TopoTableItem *itemNext = NULL;
575 TopoInfo *info = NULL;
576 TopoInfo *infoNext = NULL;
577 uint32_t i, index;
578
579 index = 0;
580 for (i = 0; i < TOPO_HASH_TABLE_SIZE; ++i) {
581 LIST_FOR_EACH_ENTRY_SAFE(item, itemNext, &g_topoTable.table[i], TopoTableItem, node) {
582 LIST_FOR_EACH_ENTRY_SAFE(info, infoNext, &item->joinList, TopoInfo, node) {
583 if (strcpy_s(relation[index].udid, UDID_BUF_LEN, item->udid) != EOK) {
584 return SOFTBUS_MEM_ERR;
585 }
586 if (strcpy_s(relation[index].peerUdid, UDID_BUF_LEN, info->peerUdid) != EOK) {
587 return SOFTBUS_MEM_ERR;
588 }
589 if (memcpy_s(relation[index].relation, sizeof(relation[index].relation), info->relation,
590 sizeof(info->relation)) != EOK) {
591 return SOFTBUS_MEM_ERR;
592 }
593 index++;
594 }
595 }
596 }
597 if (index != relationNum) {
598 return SOFTBUS_ERR;
599 }
600 return SOFTBUS_OK;
601 }
602
LnnInitTopoManager(void)603 NO_SANITIZE("cfi") int32_t LnnInitTopoManager(void)
604 {
605 int32_t i;
606
607 if (SoftbusGetConfig(SOFTBUS_BOOL_SUPPORT_TOPO, (unsigned char *)&g_topoTable.isSupportTopo,
608 sizeof(g_topoTable.isSupportTopo)) != SOFTBUS_OK) {
609 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "Cannot get isSupportTopo from config file");
610 g_topoTable.isSupportTopo = true;
611 }
612 if (!g_topoTable.isSupportTopo) {
613 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "not Support Topo");
614 return SOFTBUS_ERR;
615 }
616 for (i = 0; i < TOPO_HASH_TABLE_SIZE; ++i) {
617 ListInit(&g_topoTable.table[i]);
618 }
619 g_topoTable.totalCount = 0;
620 SoftBusMutexInit(&g_topoTable.lock, NULL);
621 if (LnnRegisterEventHandler(LNN_EVENT_RELATION_CHANGED, OnLnnRelationChanged) != SOFTBUS_OK) {
622 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "reg discovery type changed event fail");
623 return SOFTBUS_ERR;
624 }
625 if (LnnRegSyncInfoHandler(LNN_INFO_TYPE_TOPO_UPDATE, OnReceiveTopoUpdateMsg) != SOFTBUS_OK) {
626 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "reg recv topo update msg fail");
627 return SOFTBUS_ERR;
628 }
629 return SOFTBUS_OK;
630 }
631
LnnDeinitTopoManager(void)632 NO_SANITIZE("cfi") void LnnDeinitTopoManager(void)
633 {
634 if (!g_topoTable.isSupportTopo) {
635 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "not Support Topo");
636 return;
637 }
638 LnnUnregSyncInfoHandler(LNN_INFO_TYPE_TOPO_UPDATE, OnReceiveTopoUpdateMsg);
639 LnnUnregisterEventHandler(LNN_EVENT_RELATION_CHANGED, OnLnnRelationChanged);
640
641 if (SoftBusMutexLock(&g_topoTable.lock) != SOFTBUS_OK) {
642 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lock topo table fail");
643 return;
644 }
645 ClearTopoTable();
646 (void)SoftBusMutexUnlock(&g_topoTable.lock);
647 SoftBusMutexDestroy(&g_topoTable.lock);
648 }
649
LnnGetAllRelation(LnnRelation ** relation,uint32_t * relationNum)650 NO_SANITIZE("cfi") int32_t LnnGetAllRelation(LnnRelation **relation, uint32_t *relationNum)
651 {
652 int32_t rc;
653 if (relation == NULL || relationNum == NULL) {
654 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid params");
655 return SOFTBUS_INVALID_PARAM;
656 }
657 if (SoftBusMutexLock(&g_topoTable.lock) != SOFTBUS_OK) {
658 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lock topo table fail");
659 return SOFTBUS_LOCK_ERR;
660 }
661 *relation = NULL;
662 *relationNum = g_topoTable.totalCount;
663 if (*relationNum == 0) {
664 (void)SoftBusMutexUnlock(&g_topoTable.lock);
665 return SOFTBUS_OK;
666 }
667 *relation = (LnnRelation *)SoftBusMalloc(*relationNum * sizeof(LnnRelation));
668 if (*relation == NULL) {
669 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "malloc LnnRelation error");
670 (void)SoftBusMutexUnlock(&g_topoTable.lock);
671 return SOFTBUS_MEM_ERR;
672 }
673 rc = FillAllRelation(*relation, *relationNum);
674 (void)SoftBusMutexUnlock(&g_topoTable.lock);
675 if (rc != SOFTBUS_OK) {
676 SoftBusFree(*relation);
677 }
678 return rc;
679 }
680
LnnGetRelation(const char * udid,const char * peerUdid,uint8_t * relation,uint32_t len)681 NO_SANITIZE("cfi") int32_t LnnGetRelation(const char *udid, const char *peerUdid, uint8_t *relation, uint32_t len)
682 {
683 TopoTableItem *topoItem = NULL;
684 TopoInfo *topoInfo = NULL;
685 int32_t rc;
686 if (udid == NULL || peerUdid == NULL || relation == NULL || len != CONNECTION_ADDR_MAX) {
687 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "invalid params");
688 return SOFTBUS_INVALID_PARAM;
689 }
690 if (SoftBusMutexLock(&g_topoTable.lock) != SOFTBUS_OK) {
691 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lock topo table fail");
692 return SOFTBUS_LOCK_ERR;
693 }
694 rc = FindTopoInfo(udid, peerUdid, &topoItem, &topoInfo);
695 if (rc != SOFTBUS_OK) {
696 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "FindTopoInfo error");
697 (void)SoftBusMutexUnlock(&g_topoTable.lock);
698 return rc;
699 }
700 if (memcpy_s(relation, len * sizeof(relation[0]), topoInfo->relation, sizeof(topoInfo->relation)) != EOK) {
701 rc = SOFTBUS_MEM_ERR;
702 }
703 (void)SoftBusMutexUnlock(&g_topoTable.lock);
704 return rc;
705 }