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