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(¬ifyDevice, sizeof(notifyDevice), 0, sizeof(notifyDevice));
107 if (GetNotifyDeviceInfo(¬ifyDevice, deviceInfo) != NSTACKX_EOK) {
108 DFINDER_LOGE(TAG, "get notify device info failed");
109 return NSTACKX_EFAILED;
110 }
111 notifyDevice.update = NSTACKX_TRUE;
112 NotifyDeviceListChanged(¬ifyDevice, 1);
113 if (CoapDiscoverRequestOngoing()) {
114 NotifyDeviceFound(¬ifyDevice, 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