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 <limits.h>
21 #include "nstackx_device.h"
22 #include "nstackx_dfinder_log.h"
23 #include "nstackx_error.h"
24 #include "nstackx_dfinder_hidump.h"
25 #include "nstackx_list.h"
26 #include "nstackx_timer.h"
27 #include "nstackx_util.h"
28 #include "nstackx_statistics.h"
29 #ifdef ONE_RECORD_OF_DEVICE_FROM_ONE_LOCAL_NIF
30 #define RX_IFACE_REMOTE_NODE_COUNT 1
31 #else
32 #define RX_IFACE_REMOTE_NODE_COUNT 4
33 #endif
34
35 #define TAG "REMOTEDEVICE"
36 #define REPORT_INTERVAL 1000 /* 1 SECOND */
37 struct RxIface_;
38 struct RemoteDevice_;
39 typedef struct RemoteNode_ {
40 List node;
41 List orderedNode;
42 DeviceInfo deviceInfo;
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 DeviceInfo * deviceInfo)217 static RemoteNode *FindRemoteNodeByRemoteIp(const RxIface* rxIface, const DeviceInfo *deviceInfo)
218 {
219 List *pos = NULL;
220 RemoteNode *remoteNode = NULL;
221 LIST_FOR_EACH(pos, &rxIface->remoteNodeList) {
222 remoteNode = (RemoteNode *)pos;
223 WifiApChannelInfo *info = &(remoteNode->deviceInfo.netChannelInfo.wifiApInfo);
224 if (info->af != deviceInfo->netChannelInfo.wifiApInfo.af) {
225 continue;
226 }
227 if (InetEqual(info->af, &(info->addr), &(deviceInfo->netChannelInfo.wifiApInfo.addr))) {
228 return remoteNode;
229 }
230 }
231 return NULL;
232 }
233
CreateRemoteDevice(const char * deviceId)234 static RemoteDevice *CreateRemoteDevice(const char *deviceId)
235 {
236 RemoteDevice *device = (RemoteDevice *)calloc(1, sizeof(RemoteDevice));
237 if (device == NULL) {
238 DFINDER_LOGE(TAG, "malloc RemoteDevice failed");
239 return NULL;
240 }
241 if (strcpy_s(device->deviceId, sizeof(device->deviceId), deviceId) != EOK) {
242 DFINDER_LOGE(TAG, "strcpy Remote device deviceId failed");
243 free(device);
244 return NULL;
245 }
246 ListInitHead(&(device->rxIfaceList));
247 return device;
248 }
249
CreateRxIface(RemoteDevice * device,const NSTACKX_InterfaceInfo * interfaceInfo)250 static RxIface *CreateRxIface(RemoteDevice *device, const NSTACKX_InterfaceInfo *interfaceInfo)
251 {
252 RxIface *rxIface = (RxIface *)calloc(1, sizeof(RxIface));
253 if (rxIface == NULL) {
254 DFINDER_LOGE(TAG, "malloc RxIface failed");
255 return NULL;
256 }
257 (void)memcpy_s(&rxIface->localIfInfo, sizeof(NSTACKX_InterfaceInfo), interfaceInfo,
258 sizeof(NSTACKX_InterfaceInfo));
259 rxIface->device = device;
260 ListInitHead(&(rxIface->remoteNodeList));
261 return rxIface;
262 }
263
CheckAndUpdateBusinessAll(BusinessDataAll * curInfo,const BusinessDataAll * newInfo,int8_t * updated)264 static uint32_t CheckAndUpdateBusinessAll(BusinessDataAll *curInfo, const BusinessDataAll *newInfo, int8_t *updated)
265 {
266 if (newInfo->isBroadcast == NSTACKX_TRUE) {
267 if (strcmp(curInfo->businessDataBroadcast, newInfo->businessDataBroadcast) != 0) {
268 if (strcpy_s(curInfo->businessDataBroadcast, NSTACKX_MAX_BUSINESS_DATA_LEN,
269 newInfo->businessDataBroadcast) != EOK) {
270 return NSTACKX_EFAILED;
271 }
272 *updated = NSTACKX_TRUE;
273 }
274 } else {
275 if (strcmp(curInfo->businessDataUnicast, newInfo->businessDataUnicast) != 0) {
276 if (strcpy_s(curInfo->businessDataUnicast, NSTACKX_MAX_BUSINESS_DATA_LEN,
277 newInfo->businessDataUnicast) != EOK) {
278 return NSTACKX_EFAILED;
279 }
280 *updated = NSTACKX_TRUE;
281 }
282 }
283 curInfo->isBroadcast = newInfo->isBroadcast;
284 return NSTACKX_EOK;
285 }
286
CreateRemoteNode(RxIface * rxIface,const DeviceInfo * deviceInfo)287 static RemoteNode *CreateRemoteNode(RxIface *rxIface, const DeviceInfo *deviceInfo)
288 {
289 RemoteNode *remoteNode = (RemoteNode *)calloc(1, sizeof(RemoteNode));
290 if (remoteNode == NULL) {
291 DFINDER_LOGE(TAG, "malloc RemoteNode failed");
292 return NULL;
293 }
294
295 remoteNode->rxIface = rxIface;
296 remoteNode->updateState = DFINDER_UPDATE_STATE_NULL;
297 (void)memcpy_s(&remoteNode->deviceInfo, sizeof(DeviceInfo), deviceInfo, sizeof(DeviceInfo));
298
299 if (strcpy_s(remoteNode->deviceInfo.networkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
300 rxIface->localIfInfo.networkName) != EOK) {
301 DFINDER_LOGE(TAG, "copy local report nif name failed");
302 free(remoteNode);
303 return NULL;
304 }
305 remoteNode->deviceInfo.update = NSTACKX_TRUE;
306 return remoteNode;
307 }
308
UpdateDeviceInfoBusinessData(DeviceInfo * curInfo,const DeviceInfo * newInfo,int8_t * updated)309 static int32_t UpdateDeviceInfoBusinessData(DeviceInfo *curInfo, const DeviceInfo *newInfo, int8_t *updated)
310 {
311 return CheckAndUpdateBusinessAll(&curInfo->businessData, &newInfo->businessData, updated);
312 }
313
UpdateCapabilityBitmap(DeviceInfo * curInfo,const DeviceInfo * newInfo,int8_t * updated)314 static int32_t UpdateCapabilityBitmap(DeviceInfo *curInfo, const DeviceInfo *newInfo,
315 int8_t *updated)
316 {
317 /* judge capabilityBitmap is or not different with new deviceInfo */
318 if ((curInfo->capabilityBitmapNum != newInfo->capabilityBitmapNum) ||
319 (newInfo->capabilityBitmapNum &&
320 memcmp(curInfo->capabilityBitmap, newInfo->capabilityBitmap,
321 newInfo->capabilityBitmapNum * sizeof(uint32_t)))) {
322 *updated = NSTACKX_TRUE;
323 }
324
325 curInfo->capabilityBitmapNum = newInfo->capabilityBitmapNum;
326
327 (void)memset_s(curInfo->capabilityBitmap, sizeof(curInfo->capabilityBitmap), 0,
328 sizeof(curInfo->capabilityBitmap));
329 if (newInfo->capabilityBitmapNum) {
330 if (memcpy_s(curInfo->capabilityBitmap, sizeof(curInfo->capabilityBitmap),
331 newInfo->capabilityBitmap, newInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
332 DFINDER_LOGE(TAG, "UpdateCapabilityBitmap, capabilityBitmap copy error");
333 return NSTACKX_EFAILED;
334 }
335 }
336 return NSTACKX_EOK;
337 }
338
UpdataeDeviceSeqInfo(DeviceInfo * curInfo,const DeviceInfo * newInfo,int8_t * updated)339 static void UpdataeDeviceSeqInfo(DeviceInfo *curInfo, const DeviceInfo *newInfo, int8_t *updated)
340 {
341 switch (newInfo->seq.seqType) {
342 case DFINDER_SEQ_TYPE_NONE:
343 return;
344 case DFINDER_SEQ_TYPE_BCAST:
345 if (curInfo->seq.seqBcast != newInfo->seq.seqBcast) {
346 curInfo->seq.seqBcast = newInfo->seq.seqBcast;
347 *updated = NSTACKX_TRUE;
348 }
349 return;
350 case DFINDER_SEQ_TYPE_UNICAST:
351 if (curInfo->seq.seqUcast != newInfo->seq.seqUcast) {
352 curInfo->seq.seqUcast = newInfo->seq.seqUcast;
353 *updated = NSTACKX_TRUE;
354 }
355 return;
356 default:
357 DFINDER_LOGE(TAG, "unknown seqType %hhu", newInfo->seq.seqType);
358 return;
359 }
360 }
361
UpdateDeviceInfoInner(DeviceInfo * curInfo,const DeviceInfo * newInfo,int8_t * updated)362 static int32_t UpdateDeviceInfoInner(DeviceInfo *curInfo, const DeviceInfo *newInfo, int8_t *updated)
363 {
364 if (curInfo->deviceType != newInfo->deviceType) {
365 DFINDER_LOGE(TAG, "deviceType is different");
366 return NSTACKX_EFAILED;
367 }
368
369 if (strcmp(curInfo->deviceName, newInfo->deviceName) != 0) {
370 if (strcpy_s(curInfo->deviceName, sizeof(curInfo->deviceName), newInfo->deviceName) != EOK) {
371 DFINDER_LOGE(TAG, "deviceName copy error");
372 return NSTACKX_EFAILED;
373 }
374 *updated = NSTACKX_TRUE;
375 }
376
377 if (UpdateCapabilityBitmap(curInfo, newInfo, updated) != NSTACKX_EOK) {
378 DFINDER_LOGE(TAG, "UpdateCapabilityBitmap fails");
379 return NSTACKX_EFAILED;
380 }
381
382 if (curInfo->mode != newInfo->mode) {
383 curInfo->mode = newInfo->mode;
384 *updated = NSTACKX_TRUE;
385 }
386
387 if (curInfo->businessType != newInfo->businessType) {
388 curInfo->businessType = newInfo->businessType;
389 *updated = NSTACKX_TRUE;
390 }
391 return NSTACKX_EOK;
392 }
393
UpdateDeviceInfo(DeviceInfo * curInfo,const RxIface * rxIface,const DeviceInfo * newInfo,int8_t * updatedPtr)394 static int32_t UpdateDeviceInfo(DeviceInfo *curInfo, const RxIface *rxIface, const DeviceInfo *newInfo,
395 int8_t *updatedPtr)
396 {
397 int8_t updated = NSTACKX_FALSE;
398 if (UpdateDeviceInfoInner(curInfo, newInfo, &updated) != NSTACKX_EOK) {
399 DFINDER_LOGE(TAG, "UpdateDeviceInfoInner error");
400 return NSTACKX_EFAILED;
401 }
402
403 if (strcmp(curInfo->deviceHash, newInfo->deviceHash) != 0) {
404 if (strcpy_s(curInfo->deviceHash, sizeof(curInfo->deviceHash), newInfo->deviceHash) != EOK) {
405 DFINDER_LOGE(TAG, "deviceHash copy error");
406 return NSTACKX_EFAILED;
407 }
408 updated = NSTACKX_TRUE;
409 }
410
411 if (strcmp(curInfo->serviceData, newInfo->serviceData) != 0) {
412 if (strcpy_s(curInfo->serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, newInfo->serviceData) != EOK) {
413 DFINDER_LOGE(TAG, "serviceData copy error");
414 return NSTACKX_EFAILED;
415 }
416 updated = NSTACKX_TRUE;
417 }
418
419 UpdataeDeviceSeqInfo(curInfo, newInfo, &updated);
420 #ifndef DFINDER_USE_MINI_NSTACKX
421 if (strcmp(curInfo->extendServiceData, newInfo->extendServiceData) != 0) {
422 if (strcpy_s(curInfo->extendServiceData, NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN,
423 newInfo->extendServiceData) != EOK) {
424 DFINDER_LOGE(TAG, "extendServiceData copy error");
425 return NSTACKX_EFAILED;
426 }
427 updated = NSTACKX_TRUE;
428 }
429 #endif
430
431 if (UpdateDeviceInfoBusinessData(curInfo, newInfo, &updated) != NSTACKX_EOK) {
432 DFINDER_LOGE(TAG, "businessData copy error");
433 return NSTACKX_EFAILED;
434 }
435
436 if (strcpy_s(curInfo->networkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
437 rxIface->localIfInfo.networkName) != EOK) {
438 DFINDER_LOGE(TAG, "copy local report nif name failed");
439 return NSTACKX_EFAILED;
440 }
441 curInfo->discoveryType = newInfo->discoveryType;
442 *updatedPtr |= updated;
443 return NSTACKX_EOK;
444 }
445
UpdatedByTimeout(RxIface * rxIface,int8_t * updated)446 static void UpdatedByTimeout(RxIface *rxIface, int8_t *updated)
447 {
448 struct timespec preTime = rxIface->updateTime;
449 ClockGetTime(CLOCK_MONOTONIC, &rxIface->updateTime);
450 if (*updated == NSTACKX_TRUE) {
451 return;
452 }
453 uint32_t diffMs = GetTimeDiffMs(&preTime, &(rxIface->updateTime));
454 uint32_t timeoutMs = GetNotifyTimeoutMs();
455 if (timeoutMs != 0 && diffMs > timeoutMs) {
456 *updated = NSTACKX_TRUE;
457 }
458 }
459
UpdateRemoteNode(RemoteNode * remoteNode,RxIface * rxIface,const DeviceInfo * deviceInfo,int8_t * updated)460 static int32_t UpdateRemoteNode(RemoteNode *remoteNode, RxIface *rxIface, const DeviceInfo *deviceInfo,
461 int8_t *updated)
462 {
463 int32_t ret = UpdateDeviceInfo(&remoteNode->deviceInfo, rxIface, deviceInfo, updated);
464 if (ret == NSTACKX_EOK) {
465 UpdatedByTimeout(rxIface, updated);
466 }
467 return ret;
468 }
469
470 #ifdef DFINDER_DISTINGUISH_ACTIVE_PASSIVE_DISCOVERY
IsNeedUpdate(uint8_t seqType,int8_t * updated)471 static bool IsNeedUpdate(uint8_t seqType, int8_t *updated)
472 {
473 if (seqType == DFINDER_SEQ_TYPE_BCAST && *updated == NSTACKX_FALSE) {
474 return false;
475 }
476
477 return true;
478 }
479
UpdateRemoteNodeChangeStateActive(UpdateState * curState,int8_t * updated)480 static void UpdateRemoteNodeChangeStateActive(UpdateState *curState, int8_t *updated)
481 {
482 switch (*curState) {
483 case DFINDER_UPDATE_STATE_NULL:
484 *curState = DFINDER_UPDATE_STATE_UNICAST;
485 *updated = NSTACKX_TRUE;
486 break;
487 case DFINDER_UPDATE_STATE_BROADCAST:
488 if (*updated == NSTACKX_TRUE) {
489 *curState = DFINDER_UPDATE_STATE_UNICAST;
490 } else {
491 *curState = DFINDER_UPDATE_STATE_ALL;
492 *updated = NSTACKX_TRUE;
493 }
494 break;
495 case DFINDER_UPDATE_STATE_UNICAST:
496 break;
497 case DFINDER_UPDATE_STATE_ALL:
498 if (*updated == NSTACKX_TRUE) {
499 *curState = DFINDER_UPDATE_STATE_UNICAST;
500 }
501 break;
502 default:
503 break;
504 }
505 }
506
UpdateRemoteNodeChangeStatePassive(UpdateState * curState,int8_t * updated)507 static void UpdateRemoteNodeChangeStatePassive(UpdateState *curState, int8_t *updated)
508 {
509 switch (*curState) {
510 case DFINDER_UPDATE_STATE_NULL:
511 *curState = DFINDER_UPDATE_STATE_BROADCAST;
512 *updated = NSTACKX_TRUE;
513 break;
514 case DFINDER_UPDATE_STATE_BROADCAST:
515 break;
516 case DFINDER_UPDATE_STATE_UNICAST:
517 if (*updated == NSTACKX_TRUE) {
518 *curState = DFINDER_UPDATE_STATE_BROADCAST;
519 } else {
520 *curState = DFINDER_UPDATE_STATE_ALL;
521 *updated = NSTACKX_TRUE;
522 }
523 break;
524 case DFINDER_UPDATE_STATE_ALL:
525 if (*updated == NSTACKX_TRUE) {
526 *curState = DFINDER_UPDATE_STATE_BROADCAST;
527 }
528 break;
529 default:
530 break;
531 }
532 }
533
CheckAndUpdateRemoteNodeChangeState(RemoteNode * remoteNode,const DeviceInfo * deviceInfo,int8_t * updated)534 static void CheckAndUpdateRemoteNodeChangeState(RemoteNode *remoteNode,
535 const DeviceInfo *deviceInfo, int8_t *updated)
536 {
537 if (!IsNeedUpdate(deviceInfo->seq.seqType, updated)) {
538 return;
539 }
540 UpdateState *curState = &(remoteNode->updateState);
541 if (deviceInfo->discoveryType == NSTACKX_DISCOVERY_TYPE_PASSIVE) {
542 UpdateRemoteNodeChangeStatePassive(curState, updated);
543 } else {
544 UpdateRemoteNodeChangeStateActive(curState, updated);
545 }
546 }
547 #endif /* END OF DFINDER_DISTINGUISH_ACTIVE_PASSIVE_DISCOVERY */
548
DestroyOldestRemoteNode(RxIface * rxIface)549 static void DestroyOldestRemoteNode(RxIface *rxIface)
550 {
551 DFINDER_LOGD(TAG, "rx iface %s release the oldest remote node",
552 rxIface->localIfInfo.networkName);
553 List *pos = NULL;
554 List *tmp = NULL;
555 RemoteNode *oldestNode = NULL;
556 LIST_FOR_EACH_SAFE(pos, tmp, &rxIface->remoteNodeList) {
557 RemoteNode *tmpNode = (RemoteNode *)pos;
558 if (oldestNode == NULL || GetTimeDiffMs(&tmpNode->updateTs, &oldestNode->updateTs) == 0) {
559 oldestNode = tmpNode;
560 }
561 }
562
563 if (oldestNode != NULL) {
564 DestroyRemoteNodeAndDevice(rxIface, oldestNode);
565 }
566 }
567
AddRemoteNodeToList(RxIface * rxIface,RemoteNode * remoteNode)568 static void AddRemoteNodeToList(RxIface *rxIface, RemoteNode *remoteNode)
569 {
570 ListInsertTail(&rxIface->remoteNodeList, &remoteNode->node);
571 rxIface->remoteNodeCnt++;
572 g_remoteNodeCount++;
573 DFINDER_LOGD(TAG, "iface %s add a node, iface node count: %u, total node count: %u",
574 rxIface->localIfInfo.networkName, rxIface->remoteNodeCnt, g_remoteNodeCount);
575 }
576
SetDeviceListAgingTime(uint32_t agingTime)577 void SetDeviceListAgingTime(uint32_t agingTime)
578 {
579 if (agingTime < NSTACKX_MIN_AGING_TIME || agingTime > NSTACKX_MAX_AGING_TIME) {
580 DFINDER_LOGE(TAG, "illegal agingTime passed in, set agingTime default value");
581 g_agingTime = NSTACKX_DEFAULT_AGING_TIME;
582 return;
583 }
584 g_agingTime = agingTime;
585 DFINDER_LOGD(TAG, "the agingTime is set to: %u seconds", g_agingTime);
586 }
587
IsAllowToBeRemoved(RemoteNode * remoteNode)588 static bool IsAllowToBeRemoved(RemoteNode *remoteNode)
589 {
590 struct timespec now;
591 ClockGetTime(CLOCK_MONOTONIC, &now);
592 uint32_t diffTime = GetTimeDiffMs(&now, &remoteNode->updateTs);
593 return diffTime >= g_agingTime * NSTACKX_MILLI_TICKS;
594 }
595
OrderedNodeEntry(List * node)596 static __inline RemoteNode *OrderedNodeEntry(List *node)
597 {
598 return (RemoteNode *)((char *)(node) - (uintptr_t)(&(((RemoteNode *)0)->orderedNode)));
599 }
600
CheckAndRemoveAgingNode(void)601 static int32_t CheckAndRemoveAgingNode(void)
602 {
603 RemoteNode *oldestNode = OrderedNodeEntry(ListGetFront(g_remoteDeviceOrderedList));
604 if (!IsAllowToBeRemoved(oldestNode)) {
605 DFINDER_LOGD(TAG, "remote node count %u reach the max device num, please reset the max value",
606 g_remoteNodeCount);
607 struct timespec now;
608 ClockGetTime(CLOCK_MONOTONIC, &now);
609 uint32_t measureElapse = GetTimeDiffMs(&now, &g_lastReportedTime);
610 if (measureElapse > REPORT_INTERVAL) {
611 NotifyDFinderMsgRecver(DFINDER_ON_TOO_MANY_DEVICE);
612 g_lastReportedTime = now;
613 }
614 return NSTACKX_EFAILED;
615 }
616 RxIface *rxIface = (RxIface *)oldestNode->rxIface;
617 DestroyRemoteNodeAndDevice(rxIface, oldestNode);
618 return NSTACKX_EOK;
619 }
620
RemoveOldestNodesWithCount(uint32_t diffNum)621 void RemoveOldestNodesWithCount(uint32_t diffNum)
622 {
623 RemoteNode *oldestNode = NULL;
624 RxIface *rxIface = NULL;
625 for (uint32_t i = 0; i < diffNum; i++) {
626 oldestNode = OrderedNodeEntry(ListGetFront(g_remoteDeviceOrderedList));
627 rxIface = (RxIface *)oldestNode->rxIface;
628 DestroyRemoteNodeAndDevice(rxIface, oldestNode);
629 }
630 }
631
GetRemoteNodeCount(void)632 uint32_t GetRemoteNodeCount(void)
633 {
634 return g_remoteNodeCount;
635 }
636
CheckAndCreateRemoteNode(RxIface * rxIface,const DeviceInfo * deviceInfo)637 static RemoteNode *CheckAndCreateRemoteNode(RxIface *rxIface, const DeviceInfo *deviceInfo)
638 {
639 if (rxIface->remoteNodeCnt >= RX_IFACE_REMOTE_NODE_COUNT) {
640 DestroyOldestRemoteNode(rxIface);
641 }
642
643 RemoteNode *remoteNode = CreateRemoteNode(rxIface, deviceInfo);
644 if (remoteNode == NULL) {
645 return NULL;
646 }
647 AddRemoteNodeToList(rxIface, remoteNode);
648 ListInsertTail(g_remoteDeviceOrderedList, &remoteNode->orderedNode);
649
650 return remoteNode;
651 }
652
UpdateOldRemoteNode(void)653 static bool UpdateOldRemoteNode(void)
654 {
655 if (g_remoteNodeCount == GetMaxDeviceNum() && CheckAndRemoveAgingNode() != NSTACKX_EOK) {
656 DFINDER_LOGE(TAG, "remote node count %u reach the max device num", g_remoteNodeCount);
657 IncStatistics(STATS_OVER_DEVICE_LIMIT);
658 return false;
659 }
660 return true;
661 }
662
UpdateRemoteNodeByDeviceInfo(const char * deviceId,const NSTACKX_InterfaceInfo * interfaceInfo,const DeviceInfo * deviceInfo,int8_t * updated)663 int32_t UpdateRemoteNodeByDeviceInfo(const char *deviceId, const NSTACKX_InterfaceInfo *interfaceInfo,
664 const DeviceInfo *deviceInfo, int8_t *updated)
665 {
666 if (!UpdateOldRemoteNode()) {
667 return NSTACKX_EFAILED;
668 }
669
670 RemoteDevice *device = FindRemoteDevice(g_remoteDeviceList, deviceId);
671 if (device == NULL) {
672 device = CreateRemoteDevice(deviceId);
673 if (device == NULL) {
674 return NSTACKX_EFAILED;
675 }
676 ListInsertTail(g_remoteDeviceList, &(device->node));
677 }
678
679 RxIface *rxIface = FindRxIface(device, interfaceInfo);
680 if (rxIface == NULL) {
681 rxIface = CreateRxIface(device, interfaceInfo);
682 if (rxIface == NULL) {
683 goto FAIL_AND_FREE;
684 }
685 ClockGetTime(CLOCK_MONOTONIC, &(rxIface->updateTime));
686 ListInsertTail(&(device->rxIfaceList), &(rxIface->node));
687 }
688
689 RemoteNode *remoteNode = FindRemoteNodeByRemoteIp(rxIface, deviceInfo);
690 if (remoteNode == NULL) {
691 remoteNode = CheckAndCreateRemoteNode(rxIface, deviceInfo);
692 if (remoteNode == NULL) {
693 goto FAIL_AND_FREE;
694 }
695 ClockGetTime(CLOCK_MONOTONIC, &(rxIface->updateTime));
696 *updated = NSTACKX_TRUE;
697 } else {
698 if (UpdateRemoteNode(remoteNode, rxIface, deviceInfo, updated) != NSTACKX_EOK) {
699 return NSTACKX_EFAILED;
700 }
701 ListRemoveNode(&remoteNode->orderedNode);
702 ListInsertTail(g_remoteDeviceOrderedList, &remoteNode->orderedNode);
703 }
704 #ifdef DFINDER_DISTINGUISH_ACTIVE_PASSIVE_DISCOVERY
705 CheckAndUpdateRemoteNodeChangeState(remoteNode, deviceInfo, updated);
706 #endif
707 remoteNode->deviceInfo.update = *updated;
708 ClockGetTime(CLOCK_MONOTONIC, &remoteNode->updateTs);
709 return NSTACKX_EOK;
710
711 FAIL_AND_FREE:
712 if (rxIface != NULL && ListIsEmpty(&rxIface->remoteNodeList)) {
713 ListRemoveNode(&rxIface->node);
714 free(rxIface);
715 }
716
717 if (ListIsEmpty(&device->rxIfaceList)) {
718 ListRemoveNode(&device->node);
719 free(device);
720 }
721 return NSTACKX_EFAILED;
722 }
723
CopyRemoteNodeToDeviceInfo(DeviceInfo * deviceInfo,NSTACKX_DeviceInfo * deviceList,uint32_t * count,bool doFilter)724 static int32_t CopyRemoteNodeToDeviceInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList,
725 uint32_t *count, bool doFilter)
726 {
727 if (doFilter && !MatchDeviceFilter(deviceInfo)) {
728 DFINDER_LOGI(TAG, "Filter device");
729 return NSTACKX_EOK;
730 }
731
732 if (GetIsNotifyPerDevice() == true && deviceInfo->update != NSTACKX_TRUE) {
733 return NSTACKX_EOK;
734 }
735
736 if (GetNotifyDeviceInfo(&deviceList[*count], deviceInfo) != NSTACKX_EOK) {
737 DFINDER_LOGE(TAG, "GetNotifyDeviceInfo failed");
738 return NSTACKX_EFAILED;
739 }
740
741 deviceList[*count].update = deviceInfo->update;
742 deviceInfo->update = NSTACKX_FALSE;
743 ++(*count);
744 return NSTACKX_EOK;
745 }
746
CopyRemoteNodeListToDeviceInfo(List * rxIfaceList,NSTACKX_DeviceInfo * deviceList,uint32_t maxDeviceNum,uint32_t * deviceCountPtr,bool doFilter)747 static int32_t CopyRemoteNodeListToDeviceInfo(List *rxIfaceList, NSTACKX_DeviceInfo *deviceList,
748 uint32_t maxDeviceNum, uint32_t *deviceCountPtr, bool doFilter)
749 {
750 List *pos = NULL;
751 RemoteNode *remoteNode = NULL;
752 int32_t ret;
753 LIST_FOR_EACH(pos, rxIfaceList) {
754 if (*deviceCountPtr >= maxDeviceNum) {
755 break;
756 }
757 remoteNode = (RemoteNode *)pos;
758 ret = CopyRemoteNodeToDeviceInfo(&(remoteNode->deviceInfo), deviceList, deviceCountPtr, doFilter);
759 if (ret != NSTACKX_EOK) {
760 DFINDER_LOGE(TAG, "copy remote node to deviceinfo failed");
761 return NSTACKX_EFAILED;
762 }
763 }
764 return NSTACKX_EOK;
765 }
766
CopyRxIfaceListToDeviceInfo(List * rxIfaceList,NSTACKX_DeviceInfo * deviceList,uint32_t maxDeviceNum,uint32_t * deviceCountPtr,bool doFilter)767 static int32_t CopyRxIfaceListToDeviceInfo(List *rxIfaceList, NSTACKX_DeviceInfo *deviceList,
768 uint32_t maxDeviceNum, uint32_t *deviceCountPtr, bool doFilter)
769 {
770 List *pos = NULL;
771 RxIface *rxIface = NULL;
772 LIST_FOR_EACH(pos, rxIfaceList) {
773 rxIface = (RxIface *)pos;
774 if (CopyRemoteNodeListToDeviceInfo(&rxIface->remoteNodeList, deviceList, maxDeviceNum,
775 deviceCountPtr, doFilter) != NSTACKX_EOK) {
776 DFINDER_LOGE(TAG, "copy remote node list to deviceinfo failed");
777 return NSTACKX_EFAILED;
778 }
779 }
780 return NSTACKX_EOK;
781 }
782
CopyRemoteDeviceListToDeviceInfo(NSTACKX_DeviceInfo * deviceList,uint32_t maxDeviceNum,uint32_t * deviceCountPtr,bool doFilter)783 static int32_t CopyRemoteDeviceListToDeviceInfo(NSTACKX_DeviceInfo *deviceList, uint32_t maxDeviceNum,
784 uint32_t *deviceCountPtr, bool doFilter)
785 {
786 List *pos = NULL;
787 RemoteDevice *device = NULL;
788 LIST_FOR_EACH(pos, g_remoteDeviceList) {
789 device = (RemoteDevice *)pos;
790 if (CopyRxIfaceListToDeviceInfo(&device->rxIfaceList, deviceList, maxDeviceNum,
791 deviceCountPtr, doFilter) != NSTACKX_EOK) {
792 DFINDER_LOGE(TAG, "copy rxIface list to deviceinfo failed");
793 return NSTACKX_EFAILED;
794 }
795 }
796 return NSTACKX_EOK;
797 }
798
DestroyRxIfaceByIfnameInner(RemoteDevice * device,const char * ifName)799 static void DestroyRxIfaceByIfnameInner(RemoteDevice *device, const char *ifName)
800 {
801 List *pos = NULL;
802 List *tmp = NULL;
803 RxIface *rxIface = NULL;
804 LIST_FOR_EACH_SAFE(pos, tmp, &device->rxIfaceList) {
805 rxIface = (RxIface *)pos;
806 if (strcmp(rxIface->localIfInfo.networkName, ifName) == 0) {
807 DFINDER_LOGD(TAG, "destroy rxIface: %s", ifName);
808 DestroyRxIface(rxIface);
809 }
810 }
811 }
812
DestroyRxIfaceByIfname(const char * ifName)813 void DestroyRxIfaceByIfname(const char *ifName)
814 {
815 if (g_remoteDeviceList == NULL) {
816 return;
817 }
818 List *pos = NULL;
819 List *tmp = NULL;
820 RemoteDevice *device = NULL;
821 LIST_FOR_EACH_SAFE(pos, tmp, g_remoteDeviceList) {
822 device = (RemoteDevice *)pos;
823 DestroyRxIfaceByIfnameInner(device, ifName);
824 }
825 }
826
GetRxIfaceFirstRemoteNode(RxIface * rxIface)827 static RemoteNode *GetRxIfaceFirstRemoteNode(RxIface *rxIface)
828 {
829 List *pos = NULL;
830 RemoteNode *remoteNode = NULL;
831 LIST_FOR_EACH(pos, &rxIface->remoteNodeList) {
832 remoteNode = (RemoteNode *)pos;
833 // use only double frames, only support iopv4
834 WifiApChannelInfo *info = &(remoteNode->deviceInfo.netChannelInfo.wifiApInfo);
835 if (info->af != AF_INET) {
836 continue;
837 }
838 if (info->addr.in.s_addr != 0) {
839 return remoteNode;
840 }
841 }
842 return NULL;
843 }
844
GetRemoteDevcieFirstRxIface(RemoteDevice * device)845 static RxIface *GetRemoteDevcieFirstRxIface(RemoteDevice *device)
846 {
847 List *pos = NULL;
848 RxIface *rxIface = NULL;
849 LIST_FOR_EACH(pos, &device->rxIfaceList) {
850 rxIface = (RxIface *)pos;
851 if (!ListIsEmpty(&rxIface->remoteNodeList)) {
852 return rxIface;
853 }
854 }
855 return NULL;
856 }
857
GetRemoteDeviceIpInner(List * list,const char * deviceId)858 const struct in_addr *GetRemoteDeviceIpInner(List *list, const char *deviceId)
859 {
860 RemoteDevice *device = FindRemoteDevice(list, deviceId);
861 if (device == NULL || ListIsEmpty(&device->rxIfaceList)) {
862 return NULL;
863 }
864
865 RxIface *rxIface = GetRemoteDevcieFirstRxIface(device);
866 if (rxIface == NULL) {
867 return NULL;
868 }
869
870 RemoteNode *remoteNode = GetRxIfaceFirstRemoteNode(rxIface);
871 if (remoteNode == NULL) {
872 return NULL;
873 }
874
875 return &(remoteNode->deviceInfo.netChannelInfo.wifiApInfo.addr.in);
876 }
877
GetRemoteDeviceIp(const char * deviceId)878 const struct in_addr *GetRemoteDeviceIp(const char *deviceId)
879 {
880 const struct in_addr *remoteIp;
881 remoteIp = GetRemoteDeviceIpInner(g_remoteDeviceList, deviceId);
882 if (remoteIp != NULL) {
883 return remoteIp;
884 }
885 return GetRemoteDeviceIpInner(g_remoteDeviceListBackup, deviceId);
886 }
887
888 #ifdef NSTACKX_DFINDER_HIDUMP
DumpRemoteNode(const RemoteDevice * dev,char * buf,size_t len)889 static int DumpRemoteNode(const RemoteDevice *dev, char *buf, size_t len)
890 {
891 List *pos = NULL;
892 size_t index = 0;
893 LIST_FOR_EACH(pos, &dev->rxIfaceList) {
894 RxIface *rxIface = (RxIface *)pos;
895 List *tmp = NULL;
896 LIST_FOR_EACH(tmp, &rxIface->remoteNodeList) {
897 RemoteNode *node = (RemoteNode *)tmp;
898 int ret = DumpDeviceInfo(&node->deviceInfo, buf + index, len - index, NSTACKX_TRUE);
899 if (ret < 0 || (size_t)ret > len - index) {
900 DFINDER_LOGE(TAG, "dump remote node failed");
901 return NSTACKX_EFAILED;
902 }
903
904 index += (size_t)ret;
905 }
906 }
907
908 if (index > INT_MAX) {
909 DFINDER_LOGE(TAG, "dump node msg exceed");
910 return NSTACKX_EFAILED;
911 }
912 return (int)index;
913 }
914
DumpRemoteDevice(char * buf,size_t len)915 int DumpRemoteDevice(char *buf, size_t len)
916 {
917 List *pos = NULL;
918 size_t index = 0;
919 LIST_FOR_EACH(pos, g_remoteDeviceList) {
920 RemoteDevice *device = (RemoteDevice *)pos;
921 int ret = DumpRemoteNode(device, buf + index, len - index);
922 if (ret < 0 || (size_t)ret > len - index) {
923 DFINDER_LOGE(TAG, "dump remote device failed");
924 return NSTACKX_EFAILED;
925 }
926
927 index += (size_t)ret;
928 }
929
930 if (index > INT_MAX) {
931 DFINDER_LOGE(TAG, "dump remote device exceed");
932 return NSTACKX_EFAILED;
933 }
934 return (int)index;
935 }
936 #endif
937
GetDeviceList(NSTACKX_DeviceInfo * deviceList,uint32_t * deviceListLen,bool doFilter)938 void GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceListLen, bool doFilter)
939 {
940 if (deviceList == NULL) {
941 DFINDER_LOGE(TAG, "device list is null");
942 return;
943 }
944
945 uint32_t maxDeviceNum = *deviceListLen;
946 uint32_t count = 0;
947 (void)CopyRemoteDeviceListToDeviceInfo(deviceList, maxDeviceNum, &count, doFilter);
948 *deviceListLen = count;
949 }
950 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
951