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