1 /*
2 * Copyright (C) 2021-2023 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 #ifdef DFINDER_SAVE_DEVICE_LIST
17 #include "nstackx_device_remote.h"
18 #include <securec.h>
19 #include "nstackx_device.h"
20 #include "nstackx_dfinder_log.h"
21 #include "nstackx_error.h"
22 #include "nstackx_dfinder_hidump.h"
23 #include "nstackx_list.h"
24 #include "nstackx_timer.h"
25 #include "nstackx_util.h"
26 #include "nstackx_statistics.h"
27 #ifdef ONE_RECORD_OF_DEVICE_FROM_ONE_LOCAL_NIF
28 #define RX_IFACE_REMOTE_NODE_COUNT 1
29 #else
30 #define RX_IFACE_REMOTE_NODE_COUNT 4
31 #endif
32
33 #define TAG "REMOTEDEVICE"
34 #define REPORT_INTERVAL 1000 /* 1 SECOND */
35 struct RxIface_;
36 struct RemoteDevice_;
37 typedef struct RemoteNode_ {
38 List node;
39 List orderedNode;
40 DeviceInfo deviceInfo;
41 struct in_addr remoteIp;
42 struct RxIface_ *rxIface;
43 UpdateState updateState;
44 struct timespec updateTs;
45 } RemoteNode;
46
47 typedef struct RxIface_ {
48 List node;
49 NSTACKX_InterfaceInfo localIfInfo;
50 List remoteNodeList;
51 uint32_t remoteNodeCnt;
52 struct RemoteDevice_ *device;
53 struct timespec updateTime;
54 } RxIface;
55
56 typedef struct RemoteDevice_ {
57 List node;
58 char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
59 List rxIfaceList;
60 } RemoteDevice;
61
62 static List *g_remoteDeviceList;
63 static List *g_remoteDeviceListBackup;
64 static List *g_remoteDeviceOrderedList;
65 static uint32_t g_remoteNodeCount;
66 static uint32_t g_agingTime;
67 static struct timespec g_lastReportedTime;
RemoteDeviceListInit(void)68 int32_t RemoteDeviceListInit(void)
69 {
70 g_remoteDeviceList = (List *)malloc(sizeof(List));
71 if (g_remoteDeviceList == NULL) {
72 DFINDER_LOGE(TAG, "malloc remote device list failed");
73 goto FAIL;
74 }
75 g_remoteDeviceListBackup = (List *)malloc(sizeof(List));
76 if (g_remoteDeviceListBackup == NULL) {
77 DFINDER_LOGE(TAG, "malloc remote device backup list failed");
78 goto FAIL;
79 }
80 g_remoteDeviceOrderedList = (List *)malloc(sizeof(List));
81 if (g_remoteDeviceOrderedList == NULL) {
82 DFINDER_LOGE(TAG, "malloc remote device ordered list failed");
83 goto FAIL;
84 }
85 ListInitHead(g_remoteDeviceList);
86 ListInitHead(g_remoteDeviceListBackup);
87 ListInitHead(g_remoteDeviceOrderedList);
88 g_remoteNodeCount = 0;
89 return NSTACKX_EOK;
90
91 FAIL:
92 free(g_remoteDeviceList);
93 g_remoteDeviceList = NULL;
94
95 free(g_remoteDeviceListBackup);
96 g_remoteDeviceListBackup = NULL;
97
98 return NSTACKX_EFAILED;
99 }
100
DestroyRemoteNode(RxIface * rxIface,RemoteNode * node)101 static void DestroyRemoteNode(RxIface *rxIface, RemoteNode *node)
102 {
103 ListRemoveNode(&node->node);
104 ListRemoveNode(&node->orderedNode);
105 if (g_remoteNodeCount > 0) {
106 g_remoteNodeCount--;
107 }
108 if (rxIface->remoteNodeCnt > 0) {
109 rxIface->remoteNodeCnt--;
110 }
111 free(node);
112 DFINDER_LOGD(TAG, "iface %s remove a node, node count: %u, total node count: %u",
113 rxIface->localIfInfo.networkName, rxIface->remoteNodeCnt, g_remoteNodeCount);
114 }
115
DestroyRxIface(RxIface * rxIface)116 void DestroyRxIface(RxIface *rxIface)
117 {
118 List *pos = NULL;
119 List *tmp = NULL;
120 LIST_FOR_EACH_SAFE(pos, tmp, &rxIface->remoteNodeList) {
121 DestroyRemoteNode(rxIface, (RemoteNode *)pos);
122 }
123 ListRemoveNode(&rxIface->node);
124 free(rxIface);
125 }
126
DestroyRemoteDevice(RemoteDevice * device)127 void DestroyRemoteDevice(RemoteDevice *device)
128 {
129 List *pos = NULL;
130 List *tmp = NULL;
131 RxIface *rxIface = NULL;
132 LIST_FOR_EACH_SAFE(pos, tmp, &device->rxIfaceList) {
133 rxIface = (RxIface *)pos;
134 DestroyRxIface(rxIface);
135 }
136 ListRemoveNode(&device->node);
137 free(device);
138 }
139
ClearRemoteDeviceList(List * list)140 static void ClearRemoteDeviceList(List *list)
141 {
142 if (list == NULL) {
143 return;
144 }
145 List *pos = NULL;
146 List *tmp = NULL;
147 RemoteDevice *device = NULL;
148 LIST_FOR_EACH_SAFE(pos, tmp, list) {
149 device = (RemoteDevice *)pos;
150 DestroyRemoteDevice(device);
151 }
152 }
153
RemoteDeviceListDeinit(void)154 void RemoteDeviceListDeinit(void)
155 {
156 ClearRemoteDeviceList(g_remoteDeviceList);
157 free(g_remoteDeviceList);
158 g_remoteDeviceList = NULL;
159 ClearRemoteDeviceList(g_remoteDeviceListBackup);
160 free(g_remoteDeviceListBackup);
161 g_remoteDeviceListBackup = NULL;
162 free(g_remoteDeviceOrderedList);
163 g_remoteDeviceOrderedList = NULL;
164 g_remoteNodeCount = 0;
165 }
166
ClearRemoteDeviceListBackup(void)167 void ClearRemoteDeviceListBackup(void)
168 {
169 ClearRemoteDeviceList(g_remoteDeviceListBackup);
170 }
171
BackupRemoteDeviceList(void)172 void BackupRemoteDeviceList(void)
173 {
174 ClearRemoteDeviceList(g_remoteDeviceListBackup);
175 List *tmp = g_remoteDeviceListBackup;
176 g_remoteDeviceListBackup = g_remoteDeviceList;
177 g_remoteDeviceList = tmp;
178 g_remoteNodeCount = 0;
179 }
180
FindRemoteDevice(List * list,const char * deviceId)181 static RemoteDevice *FindRemoteDevice(List *list, const char *deviceId)
182 {
183 List *pos = NULL;
184 RemoteDevice *device = NULL;
185 LIST_FOR_EACH(pos, list) {
186 device = (RemoteDevice *)pos;
187 if (strcmp(device->deviceId, deviceId) == 0) {
188 return device;
189 }
190 }
191 return NULL;
192 }
193
FindRxIface(const RemoteDevice * device,const NSTACKX_InterfaceInfo * interfaceInfo)194 static RxIface *FindRxIface(const RemoteDevice* device, const NSTACKX_InterfaceInfo *interfaceInfo)
195 {
196 List *pos = NULL;
197 RxIface *rxIface = NULL;
198 LIST_FOR_EACH(pos, &device->rxIfaceList) {
199 rxIface = (RxIface *)pos;
200 if ((strcmp(interfaceInfo->networkIpAddr, rxIface->localIfInfo.networkIpAddr) == 0) &&
201 (strcmp(interfaceInfo->networkName, rxIface->localIfInfo.networkName) == 0)) {
202 return rxIface;
203 }
204 }
205 return NULL;
206 }
207
FindRemoteNodeByRemoteIp(const RxIface * rxIface,const struct in_addr * remoteIp)208 static RemoteNode *FindRemoteNodeByRemoteIp(const RxIface* rxIface, const struct in_addr *remoteIp)
209 {
210 List *pos = NULL;
211 RemoteNode *remoteNode = NULL;
212 LIST_FOR_EACH(pos, &rxIface->remoteNodeList) {
213 remoteNode = (RemoteNode *)pos;
214 if (remoteNode->remoteIp.s_addr == remoteIp->s_addr) {
215 return remoteNode;
216 }
217 }
218 return NULL;
219 }
220
CreateRemoteDevice(const char * deviceId)221 static RemoteDevice *CreateRemoteDevice(const char *deviceId)
222 {
223 RemoteDevice *device = (RemoteDevice *)calloc(1, sizeof(RemoteDevice));
224 if (device == NULL) {
225 DFINDER_LOGE(TAG, "malloc RemoteDevice failed");
226 return NULL;
227 }
228 if (strcpy_s(device->deviceId, sizeof(device->deviceId), deviceId) != EOK) {
229 DFINDER_LOGE(TAG, "strcpy Remote device deviceId failed");
230 free(device);
231 return NULL;
232 }
233 ListInitHead(&(device->rxIfaceList));
234 return device;
235 }
236
CreateRxIface(RemoteDevice * device,const NSTACKX_InterfaceInfo * interfaceInfo)237 static RxIface *CreateRxIface(RemoteDevice *device, const NSTACKX_InterfaceInfo *interfaceInfo)
238 {
239 RxIface *rxIface = (RxIface *)calloc(1, sizeof(RxIface));
240 if (rxIface == NULL) {
241 DFINDER_LOGE(TAG, "malloc RxIface failed");
242 return NULL;
243 }
244 (void)memcpy_s(&rxIface->localIfInfo, sizeof(NSTACKX_InterfaceInfo), interfaceInfo,
245 sizeof(NSTACKX_InterfaceInfo));
246 rxIface->device = device;
247 ListInitHead(&(rxIface->remoteNodeList));
248 return rxIface;
249 }
250
CheckAndUpdateBusinessAll(BusinessDataAll * curInfo,const BusinessDataAll * newInfo,int8_t * updated)251 static uint32_t CheckAndUpdateBusinessAll(BusinessDataAll *curInfo, const BusinessDataAll *newInfo, int8_t *updated)
252 {
253 if (newInfo->isBroadcast == NSTACKX_TRUE) {
254 if (strcmp(curInfo->businessDataBroadcast, newInfo->businessDataBroadcast) != 0) {
255 if (strcpy_s(curInfo->businessDataBroadcast, NSTACKX_MAX_BUSINESS_DATA_LEN,
256 newInfo->businessDataBroadcast) != EOK) {
257 return NSTACKX_EFAILED;
258 }
259 *updated = NSTACKX_TRUE;
260 }
261 } else {
262 if (strcmp(curInfo->businessDataUnicast, newInfo->businessDataUnicast) != 0) {
263 if (strcpy_s(curInfo->businessDataUnicast, NSTACKX_MAX_BUSINESS_DATA_LEN,
264 newInfo->businessDataUnicast) != EOK) {
265 return NSTACKX_EFAILED;
266 }
267 *updated = NSTACKX_TRUE;
268 }
269 }
270 curInfo->isBroadcast = newInfo->isBroadcast;
271 return NSTACKX_EOK;
272 }
273
CreateRemoteNode(RxIface * rxIface,const struct in_addr * remoteIp,const DeviceInfo * deviceInfo)274 static RemoteNode *CreateRemoteNode(RxIface *rxIface, const struct in_addr *remoteIp, const DeviceInfo *deviceInfo)
275 {
276 RemoteNode *remoteNode = (RemoteNode *)calloc(1, sizeof(RemoteNode));
277 if (remoteNode == NULL) {
278 DFINDER_LOGE(TAG, "malloc RemoteNode failed");
279 return NULL;
280 }
281
282 remoteNode->rxIface = rxIface;
283 remoteNode->remoteIp = *remoteIp;
284 remoteNode->updateState = DFINDER_UPDATE_STATE_NULL;
285 (void)memcpy_s(&remoteNode->deviceInfo, sizeof(DeviceInfo), deviceInfo, sizeof(DeviceInfo));
286
287 if (strcpy_s(remoteNode->deviceInfo.networkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
288 rxIface->localIfInfo.networkName) != EOK) {
289 DFINDER_LOGE(TAG, "copy local report nif name failed");
290 free(remoteNode);
291 return NULL;
292 }
293 remoteNode->deviceInfo.update = NSTACKX_TRUE;
294 return remoteNode;
295 }
296
UpdateDeviceInfoBusinessData(DeviceInfo * curInfo,const DeviceInfo * newInfo,int8_t * updated)297 static int32_t UpdateDeviceInfoBusinessData(DeviceInfo *curInfo, const DeviceInfo *newInfo, int8_t *updated)
298 {
299 return CheckAndUpdateBusinessAll(&curInfo->businessData, &newInfo->businessData, updated);
300 }
301
UpdateCapabilityBitmap(DeviceInfo * curInfo,const DeviceInfo * newInfo,int8_t * updated)302 static int32_t UpdateCapabilityBitmap(DeviceInfo *curInfo, const DeviceInfo *newInfo,
303 int8_t *updated)
304 {
305 /* judge capabilityBitmap is or not different with new deviceInfo */
306 if ((curInfo->capabilityBitmapNum != newInfo->capabilityBitmapNum) ||
307 (newInfo->capabilityBitmapNum &&
308 memcmp(curInfo->capabilityBitmap, newInfo->capabilityBitmap,
309 newInfo->capabilityBitmapNum * sizeof(uint32_t)))) {
310 *updated = NSTACKX_TRUE;
311 }
312
313 curInfo->capabilityBitmapNum = newInfo->capabilityBitmapNum;
314
315 (void)memset_s(curInfo->capabilityBitmap, sizeof(curInfo->capabilityBitmap), 0,
316 sizeof(curInfo->capabilityBitmap));
317 if (newInfo->capabilityBitmapNum) {
318 if (memcpy_s(curInfo->capabilityBitmap, sizeof(curInfo->capabilityBitmap),
319 newInfo->capabilityBitmap, newInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
320 DFINDER_LOGE(TAG, "UpdateCapabilityBitmap, capabilityBitmap copy error");
321 return NSTACKX_EFAILED;
322 }
323 }
324 return NSTACKX_EOK;
325 }
326
UpdateDeviceInfoInner(DeviceInfo * curInfo,const DeviceInfo * newInfo,int8_t * updated)327 static int32_t UpdateDeviceInfoInner(DeviceInfo *curInfo, const DeviceInfo *newInfo, int8_t *updated)
328 {
329 if (curInfo->deviceType != newInfo->deviceType) {
330 DFINDER_LOGE(TAG, "deviceType is different");
331 return NSTACKX_EFAILED;
332 }
333
334 if (strcmp(curInfo->deviceName, newInfo->deviceName) != 0) {
335 if (strcpy_s(curInfo->deviceName, sizeof(curInfo->deviceName), newInfo->deviceName) != EOK) {
336 DFINDER_LOGE(TAG, "deviceName copy error");
337 return NSTACKX_EFAILED;
338 }
339 *updated = NSTACKX_TRUE;
340 }
341
342 if (strlen(newInfo->version) > 0 && strcmp(curInfo->version, newInfo->version) != 0) {
343 if (strcpy_s(curInfo->version, sizeof(curInfo->version), newInfo->version) != EOK) {
344 DFINDER_LOGE(TAG, "hicom version copy error");
345 return NSTACKX_EFAILED;
346 }
347 *updated = NSTACKX_TRUE;
348 }
349
350 if (UpdateCapabilityBitmap(curInfo, newInfo, updated) != NSTACKX_EOK) {
351 DFINDER_LOGE(TAG, "UpdateCapabilityBitmap fails");
352 return NSTACKX_EFAILED;
353 }
354
355 if (curInfo->mode != newInfo->mode) {
356 curInfo->mode = newInfo->mode;
357 *updated = NSTACKX_TRUE;
358 }
359
360 if (curInfo->businessType != newInfo->businessType) {
361 curInfo->businessType = newInfo->businessType;
362 *updated = NSTACKX_TRUE;
363 }
364 return NSTACKX_EOK;
365 }
366
UpdateDeviceInfo(DeviceInfo * curInfo,const RxIface * rxIface,const DeviceInfo * newInfo,int8_t * updatedPtr)367 static int32_t UpdateDeviceInfo(DeviceInfo *curInfo, const RxIface *rxIface, const DeviceInfo *newInfo,
368 int8_t *updatedPtr)
369 {
370 int8_t updated = NSTACKX_FALSE;
371 if (UpdateDeviceInfoInner(curInfo, newInfo, &updated) != NSTACKX_EOK) {
372 DFINDER_LOGE(TAG, "UpdateDeviceInfoInner error");
373 return NSTACKX_EFAILED;
374 }
375
376 if (strcmp(curInfo->deviceHash, newInfo->deviceHash) != 0) {
377 if (strcpy_s(curInfo->deviceHash, sizeof(curInfo->deviceHash), newInfo->deviceHash) != EOK) {
378 DFINDER_LOGE(TAG, "deviceHash copy error");
379 return NSTACKX_EFAILED;
380 }
381 updated = NSTACKX_TRUE;
382 }
383
384 if (strcmp(curInfo->serviceData, newInfo->serviceData) != 0) {
385 if (strcpy_s(curInfo->serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, newInfo->serviceData) != EOK) {
386 DFINDER_LOGE(TAG, "serviceData copy error");
387 return NSTACKX_EFAILED;
388 }
389 updated = NSTACKX_TRUE;
390 }
391 updated = (newInfo->seq.dealBcast) ?
392 (curInfo->seq.seqBcast != newInfo->seq.seqBcast) : (curInfo->seq.seqUcast != newInfo->seq.seqUcast);
393 if (newInfo->seq.dealBcast) {
394 curInfo->seq.seqBcast = newInfo->seq.seqBcast;
395 } else {
396 curInfo->seq.seqUcast = newInfo->seq.seqUcast;
397 }
398 #ifndef DFINDER_USE_MINI_NSTACKX
399 if (strcmp(curInfo->extendServiceData, newInfo->extendServiceData) != 0) {
400 if (strcpy_s(curInfo->extendServiceData, NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN,
401 newInfo->extendServiceData) != EOK) {
402 DFINDER_LOGE(TAG, "extendServiceData copy error");
403 return NSTACKX_EFAILED;
404 }
405 updated = NSTACKX_TRUE;
406 }
407 #endif
408
409 if (UpdateDeviceInfoBusinessData(curInfo, newInfo, &updated) != NSTACKX_EOK) {
410 DFINDER_LOGE(TAG, "businessData copy error");
411 return NSTACKX_EFAILED;
412 }
413
414 if (strcpy_s(curInfo->networkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
415 rxIface->localIfInfo.networkName) != EOK) {
416 DFINDER_LOGE(TAG, "copy local report nif name failed");
417 return NSTACKX_EFAILED;
418 }
419 curInfo->discoveryType = newInfo->discoveryType;
420 *updatedPtr |= updated;
421 return NSTACKX_EOK;
422 }
423
UpdatedByTimeout(RxIface * rxIface,int8_t * updated)424 static void UpdatedByTimeout(RxIface *rxIface, int8_t *updated)
425 {
426 struct timespec cur;
427 ClockGetTime(CLOCK_MONOTONIC, &cur);
428 uint32_t diffMs = GetTimeDiffMs(&cur, &(rxIface->updateTime));
429 if (diffMs > GetNotifyTimeoutMs()) {
430 *updated = NSTACKX_TRUE;
431 }
432 rxIface->updateTime = cur;
433 }
434
UpdateRemoteNode(RemoteNode * remoteNode,RxIface * rxIface,const DeviceInfo * deviceInfo,int8_t * updated)435 static int32_t UpdateRemoteNode(RemoteNode *remoteNode, RxIface *rxIface, const DeviceInfo *deviceInfo,
436 int8_t *updated)
437 {
438 int32_t ret = UpdateDeviceInfo(&remoteNode->deviceInfo, rxIface, deviceInfo, updated);
439 if (ret == NSTACKX_EOK && (*updated == NSTACKX_FALSE)) {
440 UpdatedByTimeout(rxIface, updated);
441 }
442 return ret;
443 }
444
445 #ifdef DFINDER_DISTINGUISH_ACTIVE_PASSIVE_DISCOVERY
UpdateRemoteNodeChangeStateActive(UpdateState * curState,int8_t * updated)446 static void UpdateRemoteNodeChangeStateActive(UpdateState *curState, int8_t *updated)
447 {
448 switch (*curState) {
449 case DFINDER_UPDATE_STATE_NULL:
450 *curState = DFINDER_UPDATE_STATE_UNICAST;
451 *updated = NSTACKX_TRUE;
452 break;
453 case DFINDER_UPDATE_STATE_BROADCAST:
454 if (*updated == NSTACKX_TRUE) {
455 *curState = DFINDER_UPDATE_STATE_UNICAST;
456 } else {
457 *curState = DFINDER_UPDATE_STATE_ALL;
458 *updated = NSTACKX_TRUE;
459 }
460 break;
461 case DFINDER_UPDATE_STATE_UNICAST:
462 break;
463 case DFINDER_UPDATE_STATE_ALL:
464 if (*updated == NSTACKX_TRUE) {
465 *curState = DFINDER_UPDATE_STATE_UNICAST;
466 }
467 break;
468 default:
469 break;
470 }
471 }
472
UpdateRemoteNodeChangeStatePassive(UpdateState * curState,int8_t * updated)473 static void UpdateRemoteNodeChangeStatePassive(UpdateState *curState, int8_t *updated)
474 {
475 switch (*curState) {
476 case DFINDER_UPDATE_STATE_NULL:
477 *curState = DFINDER_UPDATE_STATE_BROADCAST;
478 *updated = NSTACKX_TRUE;
479 break;
480 case DFINDER_UPDATE_STATE_BROADCAST:
481 break;
482 case DFINDER_UPDATE_STATE_UNICAST:
483 if (*updated == NSTACKX_TRUE) {
484 *curState = DFINDER_UPDATE_STATE_BROADCAST;
485 } else {
486 *curState = DFINDER_UPDATE_STATE_ALL;
487 *updated = NSTACKX_TRUE;
488 }
489 break;
490 case DFINDER_UPDATE_STATE_ALL:
491 if (*updated == NSTACKX_TRUE) {
492 *curState = DFINDER_UPDATE_STATE_BROADCAST;
493 }
494 break;
495 default:
496 break;
497 }
498 }
499
CheckAndUpdateRemoteNodeChangeState(RemoteNode * remoteNode,const DeviceInfo * deviceInfo,int8_t * updated)500 static void CheckAndUpdateRemoteNodeChangeState(RemoteNode *remoteNode,
501 const DeviceInfo *deviceInfo, int8_t *updated)
502 {
503 UpdateState *curState = &(remoteNode->updateState);
504 if (deviceInfo->discoveryType == NSTACKX_DISCOVERY_TYPE_PASSIVE) {
505 UpdateRemoteNodeChangeStatePassive(curState, updated);
506 } else {
507 UpdateRemoteNodeChangeStateActive(curState, updated);
508 }
509 }
510 #endif /* END OF DFINDER_DISTINGUISH_ACTIVE_PASSIVE_DISCOVERY */
511
DestroyOldestRemoteNode(RxIface * rxIface)512 static void DestroyOldestRemoteNode(RxIface *rxIface)
513 {
514 DFINDER_LOGD(TAG, "rx iface %s release the oldest remote node",
515 rxIface->localIfInfo.networkName);
516 List *pos = NULL;
517 List *tmp = NULL;
518 RemoteNode *oldestNode = NULL;
519 LIST_FOR_EACH_SAFE(pos, tmp, &rxIface->remoteNodeList) {
520 RemoteNode *tmpNode = (RemoteNode *)pos;
521 if (oldestNode == NULL || GetTimeDiffMs(&tmpNode->updateTs, &oldestNode->updateTs) == 0) {
522 oldestNode = tmpNode;
523 }
524 }
525
526 if (oldestNode != NULL) {
527 DestroyRemoteNode(rxIface, oldestNode);
528 }
529 }
530
AddRemoteNodeToList(RxIface * rxIface,RemoteNode * remoteNode)531 static void AddRemoteNodeToList(RxIface *rxIface, RemoteNode *remoteNode)
532 {
533 ListInsertTail(&rxIface->remoteNodeList, &remoteNode->node);
534 rxIface->remoteNodeCnt++;
535 g_remoteNodeCount++;
536 DFINDER_LOGD(TAG, "iface %s add a node, iface node count: %u, total node count: %u",
537 rxIface->localIfInfo.networkName, rxIface->remoteNodeCnt, g_remoteNodeCount);
538 }
539
SetDeviceListAgingTime(uint32_t agingTime)540 void SetDeviceListAgingTime(uint32_t agingTime)
541 {
542 if (agingTime < NSTACKX_MIN_AGING_TIME || agingTime > NSTACKX_MAX_AGING_TIME) {
543 DFINDER_LOGE(TAG, "illegal agingTime passed in, set agingTime default value");
544 g_agingTime = NSTACKX_DEFAULT_AGING_TIME;
545 return;
546 }
547 g_agingTime = agingTime;
548 DFINDER_LOGD(TAG, "the agingTime is set to: %u seconds", g_agingTime);
549 }
550
IsAllowToBeRemoved(RemoteNode * remoteNode)551 static bool IsAllowToBeRemoved(RemoteNode *remoteNode)
552 {
553 struct timespec now;
554 ClockGetTime(CLOCK_MONOTONIC, &now);
555 uint32_t diffTime = GetTimeDiffMs(&now, &remoteNode->updateTs);
556 return diffTime >= g_agingTime * NSTACKX_MILLI_TICKS;
557 }
558
OrderedNodeEntry(List * node)559 static __inline RemoteNode *OrderedNodeEntry(List *node)
560 {
561 return (RemoteNode *)((char *)(node) - (uintptr_t)(&(((RemoteNode *)0)->orderedNode)));
562 }
563
CheckAndRemoveAgingNode(void)564 static int32_t CheckAndRemoveAgingNode(void)
565 {
566 RemoteNode *oldestNode = OrderedNodeEntry(ListGetFront(g_remoteDeviceOrderedList));
567 if (!IsAllowToBeRemoved(oldestNode)) {
568 DFINDER_LOGD(TAG, "remote node count %u reach the max device num, please reset the max value",
569 g_remoteNodeCount);
570 struct timespec now;
571 ClockGetTime(CLOCK_MONOTONIC, &now);
572 uint32_t measureElapse = GetTimeDiffMs(&now, &g_lastReportedTime);
573 if (measureElapse > REPORT_INTERVAL) {
574 NotifyDFinderMsgRecver(DFINDER_ON_TOO_MANY_DEVICE);
575 g_lastReportedTime = now;
576 }
577 return NSTACKX_EFAILED;
578 }
579 RxIface *rxIface = (RxIface *)oldestNode->rxIface;
580 DestroyRemoteNode(rxIface, oldestNode);
581 return NSTACKX_EOK;
582 }
583
RemoveOldestNodesWithCount(uint32_t diffNum)584 void RemoveOldestNodesWithCount(uint32_t diffNum)
585 {
586 RemoteNode *oldestNode = NULL;
587 RxIface *rxIface = NULL;
588 for (uint32_t i = 0; i < diffNum; i++) {
589 oldestNode = OrderedNodeEntry(ListGetFront(g_remoteDeviceOrderedList));
590 rxIface = (RxIface *)oldestNode->rxIface;
591 DestroyRemoteNode(rxIface, oldestNode);
592 }
593 }
594
GetRemoteNodeCount(void)595 uint32_t GetRemoteNodeCount(void)
596 {
597 return g_remoteNodeCount;
598 }
599
CheckAndCreateRemoteNode(RxIface * rxIface,const struct in_addr * remoteIp,const DeviceInfo * deviceInfo)600 static RemoteNode *CheckAndCreateRemoteNode(RxIface *rxIface,
601 const struct in_addr *remoteIp, const DeviceInfo *deviceInfo)
602 {
603 if (rxIface->remoteNodeCnt >= RX_IFACE_REMOTE_NODE_COUNT) {
604 DestroyOldestRemoteNode(rxIface);
605 }
606
607 if (g_remoteNodeCount == GetMaxDeviceNum() && CheckAndRemoveAgingNode() != NSTACKX_EOK) {
608 DFINDER_LOGE(TAG, "remote node count %u reach the max device num", g_remoteNodeCount);
609 IncStatistics(STATS_OVER_DEVICE_LIMIT);
610 return NULL;
611 }
612
613 RemoteNode *remoteNode = CreateRemoteNode(rxIface, remoteIp, deviceInfo);
614 if (remoteNode == NULL) {
615 return NULL;
616 }
617 AddRemoteNodeToList(rxIface, remoteNode);
618 ListInsertTail(g_remoteDeviceOrderedList, &remoteNode->orderedNode);
619
620 return remoteNode;
621 }
622
UpdateRemoteNodeByDeviceInfo(const char * deviceId,const NSTACKX_InterfaceInfo * interfaceInfo,const struct in_addr * remoteIp,const DeviceInfo * deviceInfo,int8_t * updated)623 int32_t UpdateRemoteNodeByDeviceInfo(const char *deviceId, const NSTACKX_InterfaceInfo *interfaceInfo,
624 const struct in_addr *remoteIp, const DeviceInfo *deviceInfo, int8_t *updated)
625 {
626 RemoteDevice *device = FindRemoteDevice(g_remoteDeviceList, deviceId);
627 if (device == NULL) {
628 device = CreateRemoteDevice(deviceId);
629 if (device == NULL) {
630 return NSTACKX_EFAILED;
631 }
632 ListInsertTail(g_remoteDeviceList, &(device->node));
633 }
634
635 RxIface *rxIface = FindRxIface(device, interfaceInfo);
636 if (rxIface == NULL) {
637 rxIface = CreateRxIface(device, interfaceInfo);
638 if (rxIface == NULL) {
639 goto FAIL_AND_FREE;
640 }
641 ClockGetTime(CLOCK_MONOTONIC, &(rxIface->updateTime));
642 ListInsertTail(&(device->rxIfaceList), &(rxIface->node));
643 }
644
645 RemoteNode *remoteNode = FindRemoteNodeByRemoteIp(rxIface, remoteIp);
646 if (remoteNode == NULL) {
647 remoteNode = CheckAndCreateRemoteNode(rxIface, remoteIp, deviceInfo);
648 if (remoteNode == NULL) {
649 goto FAIL_AND_FREE;
650 }
651 ClockGetTime(CLOCK_MONOTONIC, &(rxIface->updateTime));
652 *updated = NSTACKX_TRUE;
653 } else {
654 if (UpdateRemoteNode(remoteNode, rxIface, deviceInfo, updated) != NSTACKX_EOK) {
655 return NSTACKX_EFAILED;
656 }
657 ListRemoveNode(&remoteNode->orderedNode);
658 ListInsertTail(g_remoteDeviceOrderedList, &remoteNode->orderedNode);
659 }
660 #ifdef DFINDER_DISTINGUISH_ACTIVE_PASSIVE_DISCOVERY
661 CheckAndUpdateRemoteNodeChangeState(remoteNode, deviceInfo, updated);
662 #endif
663 remoteNode->deviceInfo.update = *updated;
664 ClockGetTime(CLOCK_MONOTONIC, &remoteNode->updateTs);
665 return NSTACKX_EOK;
666
667 FAIL_AND_FREE:
668 if (rxIface != NULL && ListIsEmpty(&rxIface->remoteNodeList)) {
669 ListRemoveNode(&rxIface->node);
670 free(rxIface);
671 }
672
673 if (ListIsEmpty(&device->rxIfaceList)) {
674 ListRemoveNode(&device->node);
675 free(device);
676 }
677 return NSTACKX_EFAILED;
678 }
679
CopyRemoteNodeToDeviceInfo(DeviceInfo * deviceInfo,NSTACKX_DeviceInfo * deviceList,uint32_t * count,bool doFilter)680 static int32_t CopyRemoteNodeToDeviceInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList,
681 uint32_t *count, bool doFilter)
682 {
683 if (doFilter && !MatchDeviceFilter(deviceInfo)) {
684 DFINDER_LOGI(TAG, "Filter device");
685 return NSTACKX_EOK;
686 }
687
688 if (GetIsNotifyPerDevice() == true && deviceInfo->update != NSTACKX_TRUE) {
689 return NSTACKX_EOK;
690 }
691
692 if (GetNotifyDeviceInfo(&deviceList[*count], deviceInfo) != NSTACKX_EOK) {
693 DFINDER_LOGE(TAG, "GetNotifyDeviceInfo failed");
694 return NSTACKX_EFAILED;
695 }
696
697 deviceList[*count].update = deviceInfo->update;
698 deviceInfo->update = NSTACKX_FALSE;
699 ++(*count);
700 return NSTACKX_EOK;
701 }
702
CopyRemoteNodeListToDeviceInfo(List * rxIfaceList,NSTACKX_DeviceInfo * deviceList,uint32_t maxDeviceNum,uint32_t * deviceCountPtr,bool doFilter)703 static int32_t CopyRemoteNodeListToDeviceInfo(List *rxIfaceList, NSTACKX_DeviceInfo *deviceList,
704 uint32_t maxDeviceNum, uint32_t *deviceCountPtr, bool doFilter)
705 {
706 List *pos = NULL;
707 RemoteNode *remoteNode = NULL;
708 int32_t ret;
709 LIST_FOR_EACH(pos, rxIfaceList) {
710 if (*deviceCountPtr >= maxDeviceNum) {
711 break;
712 }
713 remoteNode = (RemoteNode *)pos;
714 ret = CopyRemoteNodeToDeviceInfo(&(remoteNode->deviceInfo), deviceList, deviceCountPtr, doFilter);
715 if (ret != NSTACKX_EOK) {
716 DFINDER_LOGE(TAG, "copy remote node to deviceinfo failed");
717 return NSTACKX_EFAILED;
718 }
719 }
720 return NSTACKX_EOK;
721 }
722
CopyRxIfaceListToDeviceInfo(List * rxIfaceList,NSTACKX_DeviceInfo * deviceList,uint32_t maxDeviceNum,uint32_t * deviceCountPtr,bool doFilter)723 static int32_t CopyRxIfaceListToDeviceInfo(List *rxIfaceList, NSTACKX_DeviceInfo *deviceList,
724 uint32_t maxDeviceNum, uint32_t *deviceCountPtr, bool doFilter)
725 {
726 List *pos = NULL;
727 RxIface *rxIface = NULL;
728 LIST_FOR_EACH(pos, rxIfaceList) {
729 rxIface = (RxIface *)pos;
730 if (CopyRemoteNodeListToDeviceInfo(&rxIface->remoteNodeList, deviceList, maxDeviceNum,
731 deviceCountPtr, doFilter) != NSTACKX_EOK) {
732 DFINDER_LOGE(TAG, "copy remote node list to deviceinfo failed");
733 return NSTACKX_EFAILED;
734 }
735 }
736 return NSTACKX_EOK;
737 }
738
CopyRemoteDeviceListToDeviceInfo(NSTACKX_DeviceInfo * deviceList,uint32_t maxDeviceNum,uint32_t * deviceCountPtr,bool doFilter)739 static int32_t CopyRemoteDeviceListToDeviceInfo(NSTACKX_DeviceInfo *deviceList, uint32_t maxDeviceNum,
740 uint32_t *deviceCountPtr, bool doFilter)
741 {
742 List *pos = NULL;
743 RemoteDevice *device = NULL;
744 LIST_FOR_EACH(pos, g_remoteDeviceList) {
745 device = (RemoteDevice *)pos;
746 if (CopyRxIfaceListToDeviceInfo(&device->rxIfaceList, deviceList, maxDeviceNum,
747 deviceCountPtr, doFilter) != NSTACKX_EOK) {
748 DFINDER_LOGE(TAG, "copy rxIface list to deviceinfo failed");
749 return NSTACKX_EFAILED;
750 }
751 }
752 return NSTACKX_EOK;
753 }
754
DestroyRxIfaceByIfnameInner(RemoteDevice * device,const char * ifName)755 static void DestroyRxIfaceByIfnameInner(RemoteDevice *device, const char *ifName)
756 {
757 List *pos = NULL;
758 List *tmp = NULL;
759 RxIface *rxIface = NULL;
760 LIST_FOR_EACH_SAFE(pos, tmp, &device->rxIfaceList) {
761 rxIface = (RxIface *)pos;
762 if (strcmp(rxIface->localIfInfo.networkName, ifName) == 0) {
763 DFINDER_LOGD(TAG, "destroy rxIface: %s", ifName);
764 DestroyRxIface(rxIface);
765 }
766 }
767 }
768
DestroyRxIfaceByIfname(const char * ifName)769 void DestroyRxIfaceByIfname(const char *ifName)
770 {
771 if (g_remoteDeviceList == NULL) {
772 return;
773 }
774 List *pos = NULL;
775 List *tmp = NULL;
776 RemoteDevice *device = NULL;
777 LIST_FOR_EACH_SAFE(pos, tmp, g_remoteDeviceList) {
778 device = (RemoteDevice *)pos;
779 DestroyRxIfaceByIfnameInner(device, ifName);
780 }
781 }
782
GetRxIfaceFirstRemoteNode(RxIface * rxIface)783 static RemoteNode *GetRxIfaceFirstRemoteNode(RxIface *rxIface)
784 {
785 List *pos = NULL;
786 RemoteNode *remoteNode = NULL;
787 LIST_FOR_EACH(pos, &rxIface->remoteNodeList) {
788 remoteNode = (RemoteNode *)pos;
789 if (remoteNode->remoteIp.s_addr != 0) {
790 return remoteNode;
791 }
792 }
793 return NULL;
794 }
795
GetRemoteDevcieFirstRxIface(RemoteDevice * device)796 static RxIface *GetRemoteDevcieFirstRxIface(RemoteDevice *device)
797 {
798 List *pos = NULL;
799 RxIface *rxIface = NULL;
800 LIST_FOR_EACH(pos, &device->rxIfaceList) {
801 rxIface = (RxIface *)pos;
802 if (!ListIsEmpty(&rxIface->remoteNodeList)) {
803 return rxIface;
804 }
805 }
806 return NULL;
807 }
808
GetRemoteDeviceIpInner(List * list,const char * deviceId)809 const struct in_addr *GetRemoteDeviceIpInner(List *list, const char *deviceId)
810 {
811 RemoteDevice *device = FindRemoteDevice(list, deviceId);
812 if (device == NULL || ListIsEmpty(&device->rxIfaceList)) {
813 return NULL;
814 }
815
816 RxIface *rxIface = GetRemoteDevcieFirstRxIface(device);
817 if (rxIface == NULL) {
818 return NULL;
819 }
820
821 RemoteNode *remoteNode = GetRxIfaceFirstRemoteNode(rxIface);
822 if (remoteNode == NULL) {
823 return NULL;
824 }
825
826 return &remoteNode->remoteIp;
827 }
828
GetRemoteDeviceIp(const char * deviceId)829 const struct in_addr *GetRemoteDeviceIp(const char *deviceId)
830 {
831 const struct in_addr *remoteIp;
832 remoteIp = GetRemoteDeviceIpInner(g_remoteDeviceList, deviceId);
833 if (remoteIp != NULL) {
834 return remoteIp;
835 }
836 return GetRemoteDeviceIpInner(g_remoteDeviceListBackup, deviceId);
837 }
838
839 #ifdef NSTACKX_DFINDER_HIDUMP
DumpRemoteNode(const RemoteDevice * dev,char * buf,size_t len)840 static int DumpRemoteNode(const RemoteDevice *dev, char *buf, size_t len)
841 {
842 List *pos = NULL;
843 size_t index = 0;
844 LIST_FOR_EACH(pos, &dev->rxIfaceList) {
845 RxIface *rxIface = (RxIface *)pos;
846 List *tmp = NULL;
847 LIST_FOR_EACH(tmp, &rxIface->remoteNodeList) {
848 RemoteNode *node = (RemoteNode *)tmp;
849 int ret = DumpDeviceInfo(&node->deviceInfo, buf + index, len - index, NSTACKX_TRUE);
850 if (ret < 0 || (size_t)ret > len - index) {
851 DFINDER_LOGE(TAG, "dump remote node failed");
852 return NSTACKX_EFAILED;
853 }
854
855 index += (size_t)ret;
856 }
857 }
858
859 return index;
860 }
861
DumpRemoteDevice(char * buf,size_t len)862 int DumpRemoteDevice(char *buf, size_t len)
863 {
864 List *pos = NULL;
865 size_t index = 0;
866 LIST_FOR_EACH(pos, g_remoteDeviceList) {
867 RemoteDevice *device = (RemoteDevice *)pos;
868 int ret = DumpRemoteNode(device, buf + index, len - index);
869 if (ret < 0 || (size_t)ret > len - index) {
870 DFINDER_LOGE(TAG, "dump remote device failed");
871 return NSTACKX_EFAILED;
872 }
873
874 index += (size_t)ret;
875 }
876
877 return index;
878 }
879 #endif
880
GetDeviceList(NSTACKX_DeviceInfo * deviceList,uint32_t * deviceListLen,bool doFilter)881 void GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceListLen, bool doFilter)
882 {
883 if (deviceList == NULL) {
884 DFINDER_LOGE(TAG, "device list is null");
885 return;
886 }
887
888 uint32_t maxDeviceNum = *deviceListLen;
889 uint32_t count = 0;
890 (void)CopyRemoteDeviceListToDeviceInfo(deviceList, maxDeviceNum, &count, doFilter);
891 *deviceListLen = count;
892 }
893 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
894