• 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 <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