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