• 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 #include "nstackx_device.h"
17 
18 #include <string.h>
19 #include <stdio.h>
20 #include <securec.h>
21 #include <sys/types.h>
22 #ifndef _WIN32
23 #include <unistd.h>
24 #endif
25 #ifdef SUPPORT_SMARTGENIUS
26 #include <linux/netlink.h>
27 #include <linux/rtnetlink.h>
28 #include <arpa/inet.h>
29 #endif /* SUPPORT_SMARTGENIUS */
30 
31 #include "cJSON.h"
32 #include "nstackx_dfinder_log.h"
33 #include "nstackx_event.h"
34 #include "nstackx_timer.h"
35 #include "nstackx_error.h"
36 #include "nstackx_util.h"
37 #include "nstackx_common.h"
38 #include "coap_app.h"
39 #include "coap_discover.h"
40 #include "json_payload.h"
41 #include "nstackx_statistics.h"
42 #include "nstackx_device_local.h"
43 #include "nstackx_device_remote.h"
44 
45 #define TAG "nStackXDFinder"
46 
47 #define NSTACKX_RESERVED_INFO_WIFI_IP "wifiIpAddr"
48 
49 #define NSTACKX_MAX_INTERFACE_NUM (IFACE_TYPE_USB + 1)
50 #ifdef DFINDER_USE_INTERFACE_PREFIX_WLAN0
51 #define NSTACKX_WLAN_INTERFACE_NAME_PREFIX "wlan0"
52 #else
53 #define NSTACKX_WLAN_INTERFACE_NAME_PREFIX "wlan"
54 #endif
55 #define NSTACKX_ETH_INTERFACE_NAME_PREFIX "eth"
56 #define NSTACKX_USB_SCALE_NCM_INTERFACE_NAME_PREFIX "ncm0"
57 #define NSTACKX_USB_SCALE_WWAN_INTERFACE_NAME_PREFIX "wwan0"
58 #define NSTACKX_P2P_INTERFACE_NAME_PREFIX "p2p-p2p0-"
59 #define NSTACKX_P2P_WLAN_INTERFACE_NAME_PREFIX "p2p-wlan0-"
60 #define NSTACKX_USB_INTERFACE_NAME_PREFIX "rndis0"
61 #define NSTACKX_DEFAULT_VER "1.0.0.0"
62 
63 /*
64  * Reserved info JSON format:
65  *   {"wifiIpAddr":[ip string]}
66  */
67 #define NSTACKX_RESERVED_INFO_JSON_FORMAT \
68     "{\"" NSTACKX_RESERVED_INFO_WIFI_IP "\":\"%s\"}"
69 
70 static uint32_t g_maxDeviceNum;
71 static uint32_t g_filterCapabilityBitmapNum = 0;
72 static uint32_t g_filterCapabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM] = {0};
73 /* g_interfaceList store the actual interface name prefix for one platform */
74 static NetworkInterfaceInfo g_interfaceList[NSTACKX_MAX_INTERFACE_NUM];
75 struct LocalSeq {
76     uint16_t seqBcast;
77     uint16_t seqUcastV4;
78     uint16_t seqUcastV6;
79 };
80 static struct LocalSeq g_localSeq = {0, 0, 0};
81 static uint32_t g_notifyTimeoutMs = 0;
82 static pthread_mutex_t g_filterCapabilityLock = PTHREAD_MUTEX_INITIALIZER;
83 static pthread_mutex_t g_maxDeviceNumLock = PTHREAD_MUTEX_INITIALIZER;
84 
85 #ifndef DFINDER_USE_MINI_NSTACKX
86 /*
87  * g_interfacePrefixList store all interface name prefix to adapt different platform
88  * when platform interface name prefix update, just update g_interfacePrefixList
89  */
90 static const NetworkInterfacePrefiexPossible g_interfacePrefixList[NSTACKX_MAX_INTERFACE_NUM] = {
91     {{"eth", "", ""}},
92     {{NSTACKX_WLAN_INTERFACE_NAME_PREFIX, "ap", ""}},
93     {{NSTACKX_USB_SCALE_NCM_INTERFACE_NAME_PREFIX, NSTACKX_USB_SCALE_WWAN_INTERFACE_NAME_PREFIX, ""}},
94     {{"p2p-p2p0-", "p2p-wlan0-", "p2p0"}},
95     {{"rndis0", "", ""}}
96 };
97 
98 #endif /* END OF (!DFINDER_USE_MINI_NSTACKX) */
99 
DeviceInfoNotify(const DeviceInfo * deviceInfo)100 int32_t DeviceInfoNotify(const DeviceInfo *deviceInfo)
101 {
102     if (!MatchDeviceFilter(deviceInfo)) {
103         return NSTACKX_EOK;
104     }
105     NSTACKX_DeviceInfo notifyDevice;
106     (void)memset_s(&notifyDevice, sizeof(notifyDevice), 0, sizeof(notifyDevice));
107     if (GetNotifyDeviceInfo(&notifyDevice, deviceInfo) != NSTACKX_EOK) {
108         DFINDER_LOGE(TAG, "get notify device info failed");
109         return NSTACKX_EFAILED;
110     }
111     notifyDevice.update = NSTACKX_TRUE;
112     NotifyDeviceListChanged(&notifyDevice, 1);
113     if (CoapDiscoverRequestOngoing()) {
114         NotifyDeviceFound(&notifyDevice, 1);
115     }
116     return NSTACKX_EOK;
117 }
118 
119 #ifdef DFINDER_SAVE_DEVICE_LIST
UpdateDeviceDbInDeviceList(const CoapCtxType * coapCtx,const DeviceInfo * deviceInfo,uint8_t forceUpdate,uint8_t receiveBcast)120 static int32_t UpdateDeviceDbInDeviceList(const CoapCtxType *coapCtx, const DeviceInfo *deviceInfo,
121     uint8_t forceUpdate, uint8_t receiveBcast)
122 {
123     const char *deviceId = deviceInfo->deviceId;
124     int8_t updated = NSTACKX_FALSE;
125     NSTACKX_InterfaceInfo info;
126     if (strcpy_s(info.networkIpAddr, NSTACKX_MAX_IP_STRING_LEN, GetLocalIfaceIpStr(coapCtx->iface)) != EOK ||
127         strcpy_s(info.networkName, NSTACKX_MAX_INTERFACE_NAME_LEN, GetLocalIfaceName(coapCtx->iface)) != EOK) {
128         DFINDER_LOGE(TAG, "copy interfaceinfo failed");
129         return NSTACKX_EFAILED;
130     }
131 
132     if (UpdateRemoteNodeByDeviceInfo(deviceId, &info, deviceInfo, &updated) != NSTACKX_EOK) {
133         DFINDER_LOGE(TAG, "update remote node by device info failed");
134         return NSTACKX_EFAILED;
135     }
136     if (!receiveBcast && (ShouldAutoReplyUnicast(deviceInfo->businessType) != NSTACKX_TRUE)) {
137         return updated ? DeviceInfoNotify(deviceInfo) : NSTACKX_EOK;
138     }
139     if (updated || forceUpdate) {
140         DFINDER_LOGD(TAG, "updated is: %hhu, forceUpdate is: %hhu", updated, forceUpdate);
141         DeviceInfoNotify(deviceInfo);
142     }
143     return NSTACKX_EOK;
144 }
145 
UpdateDeviceDb(const CoapCtxType * coapCtx,const DeviceInfo * deviceInfo,uint8_t forceUpdate,uint8_t receiveBcast)146 int32_t UpdateDeviceDb(const CoapCtxType *coapCtx, const DeviceInfo *deviceInfo, uint8_t forceUpdate,
147     uint8_t receiveBcast)
148 {
149     int32_t ret = UpdateDeviceDbInDeviceList(coapCtx, deviceInfo, forceUpdate, receiveBcast);
150     if (ret != NSTACKX_EOK) {
151         IncStatistics(STATS_UPDATE_DEVICE_DB_FAILED);
152     }
153     return ret;
154 }
155 
156 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
157 
ReportDiscoveredDevice(const CoapCtxType * coapCtx,const DeviceInfo * deviceInfo,uint8_t forceUpdate,uint8_t receiveBcast)158 int32_t ReportDiscoveredDevice(const CoapCtxType *coapCtx, const DeviceInfo *deviceInfo,
159     uint8_t forceUpdate, uint8_t receiveBcast)
160 {
161 #ifdef DFINDER_SAVE_DEVICE_LIST
162     return UpdateDeviceDb(coapCtx, deviceInfo, forceUpdate, receiveBcast);
163 #else
164     (void)coapCtx;
165     (void)forceUpdate;
166     (void)receiveBcast;
167     return DeviceInfoNotify(deviceInfo);
168 #endif
169 }
170 
MatchDeviceFilter(const DeviceInfo * deviceInfo)171 bool MatchDeviceFilter(const DeviceInfo *deviceInfo)
172 {
173     uint32_t i, ret;
174 
175     if (g_filterCapabilityBitmapNum == 0) {
176         return true;
177     }
178 
179     for (i = 0; ((i < g_filterCapabilityBitmapNum) && (i < deviceInfo->capabilityBitmapNum)); i++) {
180         ret = (g_filterCapabilityBitmap[i] & (deviceInfo->capabilityBitmap[i]));
181         if (ret != 0) {
182             return true;
183         }
184     }
185     return false;
186 }
187 
SetServiceDataFromDeviceInfo(cJSON * item,const DeviceInfo * deviceInfo)188 static int32_t SetServiceDataFromDeviceInfo(cJSON *item, const DeviceInfo *deviceInfo)
189 {
190     if (item == NULL || deviceInfo == NULL) {
191         DFINDER_LOGE(TAG, "item or deviceInfo is null");
192         return NSTACKX_EFAILED;
193     }
194     if (strlen(deviceInfo->serviceData) != 0 && strlen(deviceInfo->serviceData) < NSTACKX_MAX_SERVICE_DATA_LEN) {
195         if (!cJSON_AddStringToObject(item, "serviceData", deviceInfo->serviceData)) {
196             DFINDER_LOGE(TAG, "cJSON_AddStringToObject: serviceData error");
197             return NSTACKX_EFAILED;
198         }
199     }
200 #ifndef DFINDER_USE_MINI_NSTACKX
201     if (strlen(deviceInfo->extendServiceData) != 0 &&
202         strlen(deviceInfo->extendServiceData) < NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN) {
203         if (!cJSON_AddStringToObject(item, "extendServiceData", deviceInfo->extendServiceData)) {
204             DFINDER_LOGE(TAG, "cJSON_AddStringToObject: extendServiceData error");
205             return NSTACKX_EFAILED;
206         }
207     }
208 #endif
209     if (deviceInfo->businessData.isBroadcast == NSTACKX_TRUE) {
210         if (strlen(deviceInfo->businessData.businessDataBroadcast) != 0 &&
211             strlen(deviceInfo->businessData.businessDataBroadcast) < NSTACKX_MAX_BUSINESS_DATA_LEN) {
212             if (!cJSON_AddStringToObject(item, "bData", deviceInfo->businessData.businessDataBroadcast)) {
213                 DFINDER_LOGE(TAG, "cJSON_AddStringToObject: businessData error");
214                 return NSTACKX_EFAILED;
215             }
216         }
217     } else {
218         if (strlen(deviceInfo->businessData.businessDataUnicast) != 0 &&
219             strlen(deviceInfo->businessData.businessDataUnicast) < NSTACKX_MAX_BUSINESS_DATA_LEN) {
220             if (!cJSON_AddStringToObject(item, "bData", deviceInfo->businessData.businessDataUnicast)) {
221                 DFINDER_LOGE(TAG, "cJSON_AddStringToObject: businessData error");
222                 return NSTACKX_EFAILED;
223             }
224         }
225     }
226     return NSTACKX_EOK;
227 }
228 
SetReservedInfoFromDeviceInfo(NSTACKX_DeviceInfo * deviceList,const DeviceInfo * deviceInfo)229 int32_t SetReservedInfoFromDeviceInfo(NSTACKX_DeviceInfo *deviceList, const DeviceInfo *deviceInfo)
230 {
231     char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN];
232     int32_t ret  = NSTACKX_EFAILED;
233 
234     (void)memset_s(wifiIpAddr, sizeof(wifiIpAddr), 0, sizeof(wifiIpAddr));
235     if (inet_ntop(deviceInfo->netChannelInfo.wifiApInfo.af, &deviceInfo->netChannelInfo.wifiApInfo.addr,
236         wifiIpAddr, sizeof(wifiIpAddr)) == NULL) {
237         DFINDER_LOGW(TAG, "no set wifi ip addr, cause inet_ntop failed");
238         return NSTACKX_EINVAL;
239     }
240     if (sprintf_s(deviceList->reservedInfo, sizeof(deviceList->reservedInfo),
241         NSTACKX_RESERVED_INFO_JSON_FORMAT, wifiIpAddr) == -1) {
242         DFINDER_LOGE(TAG, "sprintf_s reservedInfo with wifiIpAddr fails");
243         return NSTACKX_EAGAIN;
244     }
245     cJSON *item = cJSON_Parse(deviceList->reservedInfo);
246     if (item == NULL) {
247         DFINDER_LOGE(TAG, "pares deviceList fails");
248         return NSTACKX_EINVAL;
249     }
250 
251     if (deviceInfo->mode != 0 && !cJSON_AddNumberToObject(item, "mode", deviceInfo->mode)) {
252         goto L_END;
253     }
254     if (!cJSON_AddStringToObject(item, "hwAccountHashVal", deviceInfo->deviceHash)) {
255         goto L_END;
256     }
257     if (SetServiceDataFromDeviceInfo(item, deviceInfo) != NSTACKX_EOK) {
258         goto L_END;
259     }
260     char *newData = cJSON_Print(item);
261     if (newData == NULL) {
262         goto L_END;
263     }
264     (void)memset_s(deviceList->reservedInfo, sizeof(deviceList->reservedInfo),
265                    0, sizeof(deviceList->reservedInfo));
266     if (strcpy_s(deviceList->reservedInfo, sizeof(deviceList->reservedInfo), newData) != EOK) {
267         cJSON_free(newData);
268         DFINDER_LOGE(TAG, "strcpy_s fails");
269         goto L_END;
270     }
271     cJSON_free(newData);
272     ret = NSTACKX_EOK;
273 L_END:
274     cJSON_Delete(item);
275     return ret;
276 }
277 
GetNotifyDeviceInfo(NSTACKX_DeviceInfo * notifyDevice,const DeviceInfo * deviceInfo)278 int32_t GetNotifyDeviceInfo(NSTACKX_DeviceInfo *notifyDevice, const DeviceInfo *deviceInfo)
279 {
280     if ((strcpy_s(notifyDevice->deviceId, sizeof(notifyDevice->deviceId), deviceInfo->deviceId) != EOK) ||
281         (strcpy_s(notifyDevice->deviceName, sizeof(notifyDevice->deviceName), deviceInfo->deviceName) != EOK)) {
282         DFINDER_LOGE(TAG, "strcpy_s fails");
283         return NSTACKX_EFAILED;
284     }
285     notifyDevice->capabilityBitmapNum = deviceInfo->capabilityBitmapNum;
286     if (deviceInfo->capabilityBitmapNum) {
287         if (memcpy_s(notifyDevice->capabilityBitmap, sizeof(notifyDevice->capabilityBitmap),
288             deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
289             DFINDER_LOGE(TAG, "memcpy_s fails");
290             return NSTACKX_EFAILED;
291         }
292     }
293 
294     int32_t result = SetReservedInfoFromDeviceInfo(notifyDevice, deviceInfo);
295     if (result != NSTACKX_EOK) {
296         DFINDER_LOGE(TAG, "SetReservedInfoFromDeviceInfo fails: %hhd", result);
297         return result;
298     }
299 
300     if (strcpy_s(notifyDevice->networkName, sizeof(notifyDevice->networkName), deviceInfo->networkName) != EOK) {
301         DFINDER_LOGE(TAG, "copy networkName failed");
302         return NSTACKX_EFAILED;
303     }
304 
305     notifyDevice->discoveryType = deviceInfo->discoveryType;
306     notifyDevice->deviceType = deviceInfo->deviceType;
307     notifyDevice->mode = deviceInfo->mode;
308     notifyDevice->businessType = deviceInfo->businessType;
309     return NSTACKX_EOK;
310 }
311 
312 /* Return NSTACKX_TRUE if ifName prefix is the same, else return false */
NetworkInterfaceNamePrefixCmp(const char * ifName,const char * prefix)313 static uint8_t NetworkInterfaceNamePrefixCmp(const char *ifName, const char *prefix)
314 {
315     if (strlen(ifName) < strlen(prefix)) {
316         return NSTACKX_FALSE;
317     }
318 
319     if (memcmp(ifName, prefix, strlen(prefix)) == 0) {
320         return NSTACKX_TRUE;
321     } else {
322         return NSTACKX_FALSE;
323     }
324 }
325 
SetModeInfo(uint8_t mode)326 void SetModeInfo(uint8_t mode)
327 {
328     SetLocalDeviceMode(mode);
329 }
330 
GetModeInfo(void)331 uint8_t GetModeInfo(void)
332 {
333     return GetLocalDeviceMode();
334 }
335 
CheckAdvertiseInfo(const uint32_t advertiseCount,const uint32_t advertiseDuration)336 static CoapBroadcastType CheckAdvertiseInfo(const uint32_t advertiseCount, const uint32_t advertiseDuration)
337 {
338     if ((advertiseCount == 0) && (advertiseDuration == 0)) {
339         return COAP_BROADCAST_TYPE_DEFAULT;
340     }
341     return COAP_BROADCAST_TYPE_USER;
342 }
343 
344 #define NOTIFY_TIMEOUT_FLUCATION_MS 500
345 
SetNotifyTimeoutMs(uint32_t timeoutMs)346 static void SetNotifyTimeoutMs(uint32_t timeoutMs)
347 {
348     g_notifyTimeoutMs = timeoutMs;
349 }
350 
GetNotifyTimeoutMs(void)351 uint32_t GetNotifyTimeoutMs(void)
352 {
353     return g_notifyTimeoutMs;
354 }
355 
ConfigureDiscoverySettings(const NSTACKX_DiscoverySettings * discoverySettings)356 int32_t ConfigureDiscoverySettings(const NSTACKX_DiscoverySettings *discoverySettings)
357 {
358     if (discoverySettings->businessData == NULL) {
359         DFINDER_LOGE(TAG, "businessData null");
360         return NSTACKX_EINVAL;
361     }
362     SetModeInfo(discoverySettings->discoveryMode);
363     if (SetLocalDeviceBusinessData(discoverySettings->businessData, NSTACKX_FALSE) != NSTACKX_EOK) {
364         DFINDER_LOGE(TAG, "businessData copy error");
365         return NSTACKX_EFAILED;
366     }
367     SetLocalDeviceBusinessType(discoverySettings->businessType);
368     DFINDER_LOGD(TAG, "disc, local device business type set to: %hu", GetLocalDeviceBusinessType());
369     uint32_t advertiseCount = discoverySettings->advertiseCount;
370     uint32_t advertiseDuration = discoverySettings->advertiseDuration;
371     // support fallback to default: 12 times with 5 sec
372     CoapBroadcastType ret = CheckAdvertiseInfo(advertiseCount, advertiseDuration);
373     if (ret == COAP_BROADCAST_TYPE_DEFAULT) {
374         SetCoapDiscoverType(COAP_BROADCAST_TYPE_DEFAULT);
375         SetNotifyTimeoutMs(NSTACKX_MIN_ADVERTISE_DURATION + NOTIFY_TIMEOUT_FLUCATION_MS);
376     } else if (ret == COAP_BROADCAST_TYPE_USER) {
377         SetCoapDiscoverType(COAP_BROADCAST_TYPE_USER);
378         SetCoapUserDiscoverInfo(advertiseCount, advertiseDuration);
379         SetNotifyTimeoutMs(advertiseDuration + NOTIFY_TIMEOUT_FLUCATION_MS);
380     }
381     IncreaseBcastSequenceNumber();
382     return NSTACKX_EOK;
383 }
384 
DiscConfigInner(const DFinderDiscConfig * discConfig)385 int32_t DiscConfigInner(const DFinderDiscConfig *discConfig)
386 {
387     if (discConfig->businessData == NULL) {
388         DFINDER_LOGE(TAG, "business data is null");
389         return NSTACKX_EINVAL;
390     }
391     SetModeInfo(discConfig->discoveryMode);
392     if (SetLocalDeviceBusinessData(discConfig->businessData, NSTACKX_FALSE) != NSTACKX_EOK) {
393         DFINDER_LOGE(TAG, "copy business data failed");
394         return  NSTACKX_EFAILED;
395     }
396     SetCoapDiscoverType(COAP_BROADCAST_TYPE_USER_DEFINE_INTERVAL);
397     // do not support fallback to default: 12 times with 5 sec
398     return SetCoapDiscConfig(discConfig);
399 }
400 
SetFilterCapability(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[])401 int32_t SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
402 {
403     if (PthreadMutexLock(&g_filterCapabilityLock) != 0) {
404         DFINDER_LOGE(TAG, "failed to lock");
405         return NSTACKX_EFAILED;
406     }
407     if (!memcmp(capabilityBitmap, g_filterCapabilityBitmap, sizeof(uint32_t) * capabilityBitmapNum)) {
408         if (PthreadMutexUnlock(&g_filterCapabilityLock) != 0) {
409             DFINDER_LOGE(TAG, "failed to unlock");
410             return NSTACKX_EFAILED;
411         }
412         return NSTACKX_EOK;
413     }
414     (void)memset_s(g_filterCapabilityBitmap, sizeof(g_filterCapabilityBitmap),
415         0, sizeof(g_filterCapabilityBitmap));
416     if (capabilityBitmapNum) {
417         if (memcpy_s(g_filterCapabilityBitmap, sizeof(g_filterCapabilityBitmap),
418             capabilityBitmap, sizeof(uint32_t) * capabilityBitmapNum) != EOK) {
419             DFINDER_LOGE(TAG, "FilterCapabilityBitmap copy error");
420             if (PthreadMutexUnlock(&g_filterCapabilityLock) != 0) {
421                 DFINDER_LOGE(TAG, "failed to unlock");
422             }
423             return NSTACKX_EFAILED;
424         }
425     }
426     g_filterCapabilityBitmapNum = capabilityBitmapNum;
427     if (PthreadMutexUnlock(&g_filterCapabilityLock) != 0) {
428         DFINDER_LOGE(TAG, "failed to unlock");
429         return NSTACKX_EFAILED;
430     }
431     return NSTACKX_EOK;
432 }
433 
GetFilterCapability(uint32_t * capabilityBitmapNum)434 uint32_t *GetFilterCapability(uint32_t *capabilityBitmapNum)
435 {
436     if (capabilityBitmapNum != NULL) {
437         *capabilityBitmapNum = g_filterCapabilityBitmapNum;
438     }
439 
440     return g_filterCapabilityBitmap;
441 }
442 
IncreaseUcastSequenceNumber(uint8_t af)443 void IncreaseUcastSequenceNumber(uint8_t af)
444 {
445     if (af == AF_INET) {
446         ++g_localSeq.seqUcastV4;
447     } else {
448         ++g_localSeq.seqUcastV6;
449     }
450 }
451 
IncreaseBcastSequenceNumber(void)452 void IncreaseBcastSequenceNumber(void)
453 {
454     ++g_localSeq.seqBcast;
455     DFINDER_LOGI(TAG, "config bcast seq number %hu", g_localSeq.seqBcast);
456 }
457 
GetSequenceNumber(uint8_t af,uint8_t sendBcast)458 uint16_t GetSequenceNumber(uint8_t af, uint8_t sendBcast)
459 {
460     if (sendBcast == NSTACKX_TRUE) {
461         return g_localSeq.seqBcast;
462     }
463     return af == AF_INET ? g_localSeq.seqUcastV4 : g_localSeq.seqUcastV6;
464 }
465 
ResetSequenceNumber(void)466 void ResetSequenceNumber(void)
467 {
468     (void)memset_s(&g_localSeq, sizeof(g_localSeq), 0, sizeof(g_localSeq));
469 }
470 
FilterCapabilityInit()471 static void FilterCapabilityInit()
472 {
473     (void)memset_s(g_filterCapabilityBitmap, sizeof(g_filterCapabilityBitmap),
474         0, sizeof(g_filterCapabilityBitmap));
475     g_filterCapabilityBitmapNum = 0;
476 }
477 
DeviceModuleClean(void)478 void DeviceModuleClean(void)
479 {
480 #ifdef DFINDER_SAVE_DEVICE_LIST
481     RemoteDeviceListDeinit();
482 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
483 
484     LocalDeviceDeinit();
485 }
486 
GlobalInterfaceListInit(void)487 static void GlobalInterfaceListInit(void)
488 {
489     (void)memset_s(g_interfaceList, sizeof(g_interfaceList), 0, sizeof(g_interfaceList));
490     (void)strcpy_s(g_interfaceList[IFACE_TYPE_WLAN].name,
491         sizeof(g_interfaceList[IFACE_TYPE_WLAN].name), NSTACKX_WLAN_INTERFACE_NAME_PREFIX);
492     (void)strcpy_s(g_interfaceList[IFACE_TYPE_ETH].name,
493         sizeof(g_interfaceList[IFACE_TYPE_ETH].name), NSTACKX_ETH_INTERFACE_NAME_PREFIX);
494     (void)strcpy_s(g_interfaceList[IFACE_TYPE_USB_SCALE].name,
495         sizeof(g_interfaceList[IFACE_TYPE_USB_SCALE].name), NSTACKX_USB_SCALE_NCM_INTERFACE_NAME_PREFIX);
496     (void)strcpy_s(g_interfaceList[IFACE_TYPE_USB_SCALE].alias,
497         sizeof(g_interfaceList[IFACE_TYPE_USB_SCALE].alias), NSTACKX_USB_SCALE_WWAN_INTERFACE_NAME_PREFIX);
498     (void)strcpy_s(g_interfaceList[IFACE_TYPE_P2P].name,
499         sizeof(g_interfaceList[IFACE_TYPE_P2P].name), NSTACKX_P2P_INTERFACE_NAME_PREFIX);
500     (void)strcpy_s(g_interfaceList[IFACE_TYPE_P2P].alias,
501         sizeof(g_interfaceList[IFACE_TYPE_P2P].alias), NSTACKX_P2P_WLAN_INTERFACE_NAME_PREFIX);
502     (void)strcpy_s(g_interfaceList[IFACE_TYPE_USB].name,
503         sizeof(g_interfaceList[IFACE_TYPE_USB].name), NSTACKX_USB_INTERFACE_NAME_PREFIX);
504 }
505 
SetMaxDeviceNum(uint32_t maxDeviceNum)506 void SetMaxDeviceNum(uint32_t maxDeviceNum)
507 {
508     if (PthreadMutexLock(&g_maxDeviceNumLock) != 0) {
509         DFINDER_LOGE(TAG, "failed to lock");
510         return;
511     }
512 #ifdef DFINDER_SAVE_DEVICE_LIST
513     if (maxDeviceNum < NSTACKX_MIN_DEVICE_NUM || maxDeviceNum > NSTACKX_MAX_DEVICE_NUM) {
514         DFINDER_LOGE(TAG, "illegal device num passed in, set device num to default value");
515         maxDeviceNum = NSTACKX_DEFAULT_DEVICE_NUM;
516     }
517     uint32_t remoteNodeCnt = GetRemoteNodeCount();
518     if (maxDeviceNum < remoteNodeCnt) {
519         uint32_t diffNum = remoteNodeCnt - maxDeviceNum;
520         DFINDER_LOGI(TAG, "maxDeviceNum is less than remoteNodeCount, remove %u oldest nodes", diffNum);
521         RemoveOldestNodesWithCount(diffNum);
522     }
523 #else
524     maxDeviceNum = NSTACKX_MAX_DEVICE_NUM;
525 #endif
526     g_maxDeviceNum = maxDeviceNum;
527     DFINDER_LOGD(TAG, "the maxDeviceNum is set to: %u", g_maxDeviceNum);
528     if (PthreadMutexUnlock(&g_maxDeviceNumLock) != 0) {
529         DFINDER_LOGE(TAG, "failed to unlock");
530     }
531 }
532 
GetMaxDeviceNum(void)533 uint32_t GetMaxDeviceNum(void)
534 {
535     return g_maxDeviceNum;
536 }
537 
DeviceModuleInit(EpollDesc epollfd,uint32_t maxDeviceNum)538 int32_t DeviceModuleInit(EpollDesc epollfd, uint32_t maxDeviceNum)
539 {
540     SetMaxDeviceNum(maxDeviceNum);
541 #ifdef DFINDER_SAVE_DEVICE_LIST
542     SetDeviceListAgingTime(NSTACKX_DEFAULT_AGING_TIME);
543 #endif
544     FilterCapabilityInit();
545 
546     if (LocalDeviceInit(epollfd) != NSTACKX_EOK) {
547         DFINDER_LOGE(TAG, "local device init failed");
548         return NSTACKX_EFAILED;
549     }
550 
551 #ifdef DFINDER_SAVE_DEVICE_LIST
552     if (RemoteDeviceListInit() != NSTACKX_EOK) {
553         DFINDER_LOGE(TAG, "remote device list init failed");
554         return NSTACKX_EFAILED;
555     }
556 #endif
557 
558     GlobalInterfaceListInit();
559 
560     return NSTACKX_EOK;
561 }
562 
563 #ifndef DFINDER_USE_MINI_NSTACKX
UpdateAllNetworkInterfaceNameIfNeed(const NetworkInterfaceInfo * interfaceInfo)564 void UpdateAllNetworkInterfaceNameIfNeed(const NetworkInterfaceInfo *interfaceInfo)
565 {
566     if (interfaceInfo == NULL) {
567         DFINDER_LOGE(TAG, "NetworkInterfaceInfo is Null");
568         return;
569     }
570     for (int i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
571         if (strlen(g_interfaceList[i].name) != 0 &&
572             strncmp(interfaceInfo->name, g_interfaceList[i].name, strlen(g_interfaceList[i].name)) == 0) {
573             return;
574         }
575     }
576     for (int i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
577         for (int j = 0; j < INTERFACE_NAME_POSSIBLE; j++) {
578             if (!(strlen(g_interfacePrefixList[i].name[j]) != 0 &&
579                 strncmp(interfaceInfo->name, g_interfacePrefixList[i].name[j],
580                         strlen(g_interfacePrefixList[i].name[j])) == 0)) {
581                 continue;
582             }
583             if (strncpy_s(g_interfaceList[i].name, sizeof(g_interfaceList[i].name),
584                 g_interfacePrefixList[i].name[j], strlen(g_interfacePrefixList[i].name[j])) != EOK) {
585                 DFINDER_LOGE(TAG, "interface update failed");
586             }
587             return;
588         }
589     }
590 }
591 
592 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
593 
ResetDeviceTaskCount(uint8_t isBusy)594 void ResetDeviceTaskCount(uint8_t isBusy)
595 {
596     ResetLocalDeviceTaskCount(isBusy);
597 }
598 
GetIfaceType(const char * ifname)599 uint8_t GetIfaceType(const char *ifname)
600 {
601     uint8_t i;
602     for (i = IFACE_TYPE_ETH; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
603         if (NetworkInterfaceNamePrefixCmp(ifname, g_interfaceList[i].name) ||
604             (g_interfaceList[i].alias[0] != '\0' && NetworkInterfaceNamePrefixCmp(ifname, g_interfaceList[i].alias))) {
605             return i;
606         }
607     }
608 
609     return IFACE_TYPE_UNKNOWN;
610 }
611