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