• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #ifdef DFINDER_SAVE_DEVICE_LIST
39 #include "nstackx_database.h"
40 #endif
41 #include "coap_app.h"
42 #include "coap_discover.h"
43 #include "json_payload.h"
44 #include "nstackx_statistics.h"
45 
46 #define TAG "nStackXDFinder"
47 
48 #define NSTACKX_OFFLINE_DEFERRED_DURATION 5000 /* Defer local device offline event, 5 seconds */
49 #define NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES 4
50 
51 #define NSTACKX_DEFAULT_DEVICE_NAME "nStack Device"
52 
53 #define NSTACKX_RESERVED_INFO_WIFI_IP "wifiIpAddr"
54 
55 #define NSTACKX_WLAN_INDEX 0
56 #define NSTACKX_ETH_INDEX 1
57 #define NSTACKX_P2P_INDEX 2
58 #define NSTACKX_USB_INDEX 3
59 #define NSTACKX_MAX_INTERFACE_NUM 4
60 #define NETWORKTYPE_LENGTH 20
61 #define NSTACKX_WLAN_INTERFACE_NAME_PREFIX "wlan"
62 #define NSTACKX_ETH_INTERFACE_NAME_PREFIX "eth"
63 #define NSTACKX_P2P_INTERFACE_NAME_PREFIX "p2p-p2p0-"
64 #define NSTACKX_P2P_WLAN_INTERFACE_NAME_PREFIX "p2p-wlan0-"
65 #define NSTACKX_USB_INTERFACE_NAME_PREFIX "rndis0"
66 #define NSTACKX_DEFAULT_VER "1.0.0.0"
67 
68 /*
69  * Reserved info JSON format:
70  *   {"wifiIpAddr":[ip string]}
71  */
72 #define NSTACKX_RESERVED_INFO_JSON_FORMAT \
73     "{\"" NSTACKX_RESERVED_INFO_WIFI_IP "\":\"%s\"}"
74 
75 #define NET_CHANNEL_INFO_STATE_INVALID(info) \
76     ((info)->state <= NET_CHANNEL_STATE_START || (info)->state >= NET_CHANNEL_STATE_END)
77 
78 #ifdef DFINDER_SUPPORT_MULTI_NIF
79 #define IF_STATE_INIT 0
80 #define IF_STATE_UPDATED 1
81 #define IF_STATE_REMAIN_UP 2
82 #endif
83 
84 #ifdef DFINDER_SAVE_DEVICE_LIST
85 static void *g_deviceList = NULL;
86 static void *g_deviceListBackup = NULL;
87 #endif
88 
89 static Timer *g_offlineDeferredTimer = NULL;
90 #ifndef DFINDER_SUPPORT_MULTI_NIF
91 static Timer *g_p2pServerInitDeferredTimer = NULL;
92 static Timer *g_usbServerInitDeferredTimer = NULL;
93 #endif
94 
95 static uint32_t g_maxDeviceNum;
96 static uint8_t g_deviceInited;
97 static DeviceInfo g_localDeviceInfo;
98 static uint32_t g_filterCapabilityBitmapNum = 0;
99 static uint32_t g_filterCapabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM] = {0};
100 /* g_interfaceList store the actual interface name prefix for one platform */
101 static NetworkInterfaceInfo g_interfaceList[NSTACKX_MAX_INTERFACE_NUM];
102 
103 #if !defined(DFINDER_SUPPORT_MULTI_NIF)
104 static char g_networkType[NETWORKTYPE_LENGTH] = {0};
105 #endif
106 #if !defined(DFINDER_SUPPORT_MULTI_NIF) && !defined(DFINDER_USE_MINI_NSTACKX)
107 /*
108  * g_interfacePrefixList store all interface name prefix to adapt different platform
109  * when platform interface name prefix update, just update g_interfacePrefixList
110  */
111 static const NetworkInterfacePrefiexPossible g_interfacePrefixList[NSTACKX_MAX_INTERFACE_NUM] = {
112     {{"wlan", "ap", ""}},
113     {{"eth", "", ""}},
114     {{"p2p-p2p0-", "p2p-wlan0-", "p2p0"}},
115     {{"rndis0", "", ""}}
116 };
117 static const uint32_t g_serverInitRetryBackoffList[NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES] = { 10, 15, 25, 100 };
118 static uint32_t g_p2pRetryCount = 0;
119 static uint32_t g_usbRetryCount = 0;
120 
121 static struct in_addr g_p2pIp;
122 static struct in_addr g_usbIp;
123 #endif /* END OF (!DFINDER_USE_MINI_NSTACKX) && (!DFINDER_SUPPORT_MULTI_NIF) */
124 
125 #ifdef DFINDER_SAVE_DEVICE_LIST
126 static void DeviceListChangeHandle(void);
127 static void GetDeviceList(void *dbList, NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr, bool doFilter);
128 #endif
129 
130 static bool MatchDeviceFilter(const DeviceInfo *deviceInfo);
131 
132 #ifndef DFINDER_SAVE_DEVICE_LIST
133 static int32_t GetNotifyDeviceInfo(NSTACKX_DeviceInfo *notifyDevice, const DeviceInfo *deviceInfo);
134 #endif
135 
136 #ifdef DFINDER_SAVE_DEVICE_LIST
137 static uint8_t IsSameDevice(void *recptr, void *myptr);
138 #ifdef DFINDER_SUPPORT_MULTI_NIF
139 static void GetDeviceListWithReportIdx(void *dbList, NSTACKX_DeviceInfo *deviceList,
140     uint32_t *deviceCountPtr, bool doFilter);
141 static uint32_t CheckAndUpdateBusinessAll(BusinessDataAll *a, const BusinessDataAll *b, uint8_t *updated);
142 #endif
143 #endif
144 
145 #ifdef DFINDER_SAVE_DEVICE_LIST
ClearDevices(void * deviceList)146 uint8_t ClearDevices(void *deviceList)
147 {
148     uint32_t i;
149     int64_t idx = -1;
150     DeviceInfo *dev = NULL;
151     uint8_t deviceRemoved = NSTACKX_FALSE;
152 
153     if (deviceList == NULL) {
154         return deviceRemoved;
155     }
156 
157     for (i = 0; i < g_maxDeviceNum; i++) {
158         dev = DatabaseGetNextRecord(deviceList, &idx);
159         if (dev == NULL) {
160             break;
161         }
162         DatabaseFreeRecord(deviceList, (void *)dev);
163         deviceRemoved = NSTACKX_TRUE;
164     }
165     return deviceRemoved;
166 }
167 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
168 
LocalDeviceOffline(void * data)169 static void LocalDeviceOffline(void *data)
170 {
171 #ifdef DFINDER_SAVE_DEVICE_LIST
172     uint8_t deviceRemoved;
173     (void)data;
174     (void)ClearDevices(g_deviceListBackup);
175     DFINDER_LOGW(TAG, "clear device list backup");
176     deviceRemoved = ClearDevices(g_deviceList);
177     DFINDER_LOGW(TAG, "clear device list");
178 #ifdef DFINDER_SUPPORT_MULTI_NIF
179     for (uint32_t i = 0; i < NSTACKX_MAX_LISTENED_NIF_NUM; ++i) {
180         CoapServerDestroyWithIdx(i);
181     }
182 #else
183     CoapServerDestroy();
184 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
185     if (deviceRemoved) {
186         DeviceListChangeHandle();
187     }
188 #else
189     (void)data;
190 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
191 }
192 
193 #if !defined(DFINDER_SUPPORT_MULTI_NIF) && !defined(DFINDER_USE_MINI_NSTACKX)
StopP2pServerInitRetryTimer(void)194 static void StopP2pServerInitRetryTimer(void)
195 {
196     if (g_p2pRetryCount != 0 && g_p2pServerInitDeferredTimer != NULL) {
197         TimerSetTimeout(g_p2pServerInitDeferredTimer, 0, NSTACKX_FALSE); // stop previous timer
198         g_p2pRetryCount = 0;
199     }
200 }
201 
StopUsbServerInitRetryTimer(void)202 static void StopUsbServerInitRetryTimer(void)
203 {
204     if (g_usbRetryCount != 0 && g_usbServerInitDeferredTimer != NULL) {
205         TimerSetTimeout(g_usbServerInitDeferredTimer, 0, NSTACKX_FALSE); // stop previous timer
206         g_usbRetryCount = 0;
207         (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp));
208     }
209 }
210 
DestroyP2pUsbServerInitRetryTimer(void)211 void DestroyP2pUsbServerInitRetryTimer(void)
212 {
213     if (g_p2pServerInitDeferredTimer != NULL) {
214         StopP2pServerInitRetryTimer();
215         TimerDelete(g_p2pServerInitDeferredTimer);
216         g_p2pServerInitDeferredTimer = NULL;
217     }
218     if (g_usbServerInitDeferredTimer != NULL) {
219         StopUsbServerInitRetryTimer();
220         TimerDelete(g_usbServerInitDeferredTimer);
221         g_usbServerInitDeferredTimer = NULL;
222     }
223 }
224 
CoapP2pServerInitDelayHandler(void * data)225 static void CoapP2pServerInitDelayHandler(void *data)
226 {
227     (void)data;
228     DFINDER_LOGD(TAG, "CoapP2pServerInitDelay, retry %u times", g_p2pRetryCount);
229     if (CoapP2pServerInit(&g_p2pIp) == NSTACKX_EOK) {
230         DFINDER_LOGE(TAG, "CoapP2pServerInitDelay success");
231         g_p2pRetryCount = 0;
232         return;
233     }
234     if (g_p2pRetryCount >= NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES) {
235         DFINDER_LOGE(TAG, "CoapP2pServerInitDelay retry reach max times");
236         g_p2pRetryCount = 0;
237         (void)memset_s(&g_p2pIp, sizeof(g_p2pIp), 0, sizeof(g_p2pIp));
238         return;
239     }
240     TimerSetTimeout(g_p2pServerInitDeferredTimer, g_serverInitRetryBackoffList[g_p2pRetryCount], NSTACKX_FALSE);
241     g_p2pRetryCount++;
242 }
243 
CoapUsbServerInitDelayHandler(void * data)244 static void CoapUsbServerInitDelayHandler(void *data)
245 {
246     DFINDER_LOGD(TAG, "CoapUsbServerInitDelay, retry %u times", g_usbRetryCount);
247     (void)data;
248     if (CoapUsbServerInit(&g_usbIp) == NSTACKX_EOK) {
249         DFINDER_LOGE(TAG, "CoapUsbServerInitDelay success");
250         g_usbRetryCount = 0;
251         (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp));
252         return;
253     }
254     if (g_usbRetryCount >= NSTACKX_P2PUSB_SERVERINIT_MAX_RETRY_TIMES) {
255         DFINDER_LOGE(TAG, "CoapUsbServerInitDelay retry reach max times");
256         g_usbRetryCount = 0;
257         (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp));
258         return;
259     }
260 
261     TimerSetTimeout(g_usbServerInitDeferredTimer, g_serverInitRetryBackoffList[g_usbRetryCount], NSTACKX_FALSE);
262     g_usbRetryCount++;
263 }
264 
P2pUsbTimerInit(EpollDesc epollfd)265 int32_t P2pUsbTimerInit(EpollDesc epollfd)
266 {
267     g_p2pRetryCount = 0;
268     g_usbRetryCount = 0;
269     g_p2pServerInitDeferredTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, CoapP2pServerInitDelayHandler, NULL);
270     if (g_p2pServerInitDeferredTimer == NULL) {
271         DFINDER_LOGE(TAG, "g_p2pServerInitDeferredTimer start failed");
272         return NSTACKX_EFAILED;
273     }
274     (void)memset_s(&g_p2pIp, sizeof(g_p2pIp), 0, sizeof(g_p2pIp));
275     g_usbServerInitDeferredTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, CoapUsbServerInitDelayHandler, NULL);
276     if (g_usbServerInitDeferredTimer == NULL) {
277         DFINDER_LOGE(TAG, "g_UsbServerInitDeferredTimer start failed");
278         return NSTACKX_EFAILED;
279     }
280     (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp));
281 
282     return NSTACKX_EOK;
283 }
284 #endif /* END OF (!DFINDER_USE_MINI_NSTACKX) && (!DFINDER_SUPPORT_MULTI_NIF) */
285 
286 #ifdef DFINDER_SUPPORT_MULTI_NIF
DeviceListChangeHandleMultiNif()287 static void DeviceListChangeHandleMultiNif()
288 {
289     uint32_t count = g_maxDeviceNum;
290     DFINDER_LOGD(TAG, "max device num:%d", g_maxDeviceNum);
291     size_t listLen = sizeof(NSTACKX_DeviceInfo) * count;
292     NSTACKX_DeviceInfo *deviceList = (NSTACKX_DeviceInfo *)malloc(listLen);
293     if (deviceList == NULL) {
294         DFINDER_LOGE(TAG, "malloc for device list failed when for multi network interface");
295         return;
296     }
297     (void)memset_s(deviceList, listLen, 0, listLen);
298     GetDeviceListWithReportIdx(g_deviceList, deviceList, &count, true);
299     if (count == 0) {
300         DFINDER_LOGW(TAG, "MULTI_NIF count is zero, do not notify");
301         free(deviceList);
302         return;
303     }
304     NotifyDeviceListChanged(deviceList, count);
305     if (CoapDiscoverRequestOngoing()) {
306         NotifyDeviceFound(deviceList, count);
307     }
308     free(deviceList);
309 }
310 #endif
311 
312 #ifdef DFINDER_SAVE_DEVICE_LIST
313 #ifndef DFINDER_SUPPORT_MULTI_NIF
CreateNewDevice(void * deviceList,const DeviceInfo * deviceInfo)314 static DeviceInfo *CreateNewDevice(void *deviceList, const DeviceInfo *deviceInfo)
315 {
316     /* Allocate DB for newly joined device */
317     DeviceInfo *internalDevice = DatabaseAllocRecord(deviceList);
318     if (internalDevice == NULL) {
319         DFINDER_LOGE(TAG, "Failed to allocate device info");
320         return NULL;
321     }
322     *internalDevice = *deviceInfo;
323     if (strcpy_s(internalDevice->networkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
324         g_localDeviceInfo.networkName) != EOK) {
325         DFINDER_LOGE(TAG, "copy local nif name failed");
326         DatabaseFreeRecord(deviceList, (void*)internalDevice);
327         return NULL;
328     }
329     internalDevice->updateState = DFINDER_UPDATE_STATE_NULL;
330     return internalDevice;
331 }
332 #endif
333 
334 #ifdef DFINDER_SUPPORT_MULTI_NIF
CreateNewDeviceWithIdx(void * deviceList,const DeviceInfo * deviceInfo,uint8_t idx)335 static DeviceInfo *CreateNewDeviceWithIdx(void *deviceList, const DeviceInfo *deviceInfo, uint8_t idx)
336 {
337     DFINDER_LOGD(TAG, "crete new device with idx-%hhu", idx);
338     uint8_t updated;
339     /* Allocate DB for newly joined device */
340     DeviceInfo *internalDevice = DatabaseAllocRecord(deviceList);
341     if (internalDevice == NULL) {
342         DFINDER_LOGE(TAG, "Failed to allocate device info");
343         return NULL;
344     }
345     *internalDevice = *deviceInfo;
346 
347     const char *lNifName = GetLocalNifNameWithIdx(idx);
348     if (lNifName == NULL) {
349         DFINDER_LOGE(TAG, "get local nif name with idx-%hhu failed", idx);
350         DatabaseFreeRecord(deviceList, (void *)internalDevice);
351         return NULL;
352     }
353 
354     DFINDER_LOGD(TAG, "create new device, nif name to copy is: %s", lNifName);
355     if (strcpy_s(internalDevice->localIfInfoAll[0].localIfInfo.networkName,
356         NSTACKX_MAX_INTERFACE_NAME_LEN, lNifName) != EOK) {
357         DFINDER_LOGE(TAG, "report network name copy failed");
358         DatabaseFreeRecord(deviceList, (void *)internalDevice);
359         return NULL;
360     }
361     internalDevice->nextNifIdx = 1;
362     internalDevice->localIfInfoAll[0].deviceRemoteChannelInfo[0].remoteChannelInfo = deviceInfo->netChannelInfo;
363     ClockGetTime(CLOCK_MONOTONIC, &internalDevice->localIfInfoAll[0].deviceRemoteChannelInfo[0].lastRecvTime);
364     internalDevice->localIfInfoAll[0].nextRemoteIdx = 1;
365     internalDevice->localIfInfoAll[0].deviceRemoteChannelInfo[0].updateState = DFINDER_UPDATE_STATE_NULL;
366 
367     if (CheckAndUpdateBusinessAll(&internalDevice->localIfInfoAll[0].deviceRemoteChannelInfo[0].businessDataAll,
368         &internalDevice->businessData, &updated) != NSTACKX_EOK) {
369         DatabaseFreeRecord(deviceList, (void *)internalDevice);
370         return NULL;
371     }
372 
373     return internalDevice;
374 }
375 #endif
376 
UpdateCapabilityBitmap(DeviceInfo * internalDevice,const DeviceInfo * deviceInfo,uint8_t * updated)377 static int32_t UpdateCapabilityBitmap(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo,
378     uint8_t *updated)
379 {
380     if (internalDevice == NULL || deviceInfo == NULL || updated == NULL) {
381         DFINDER_LOGE(TAG, "UpdateCapabilityBitmap, input parameter error");
382         return NSTACKX_EFAILED;
383     }
384 
385     /* judge capabilityBitmap is or not different with new deviceInfo */
386     if ((internalDevice->capabilityBitmapNum != deviceInfo->capabilityBitmapNum) ||
387         (deviceInfo->capabilityBitmapNum &&
388         memcmp(internalDevice->capabilityBitmap, deviceInfo->capabilityBitmap,
389                deviceInfo->capabilityBitmapNum * sizeof(uint32_t)))) {
390         *updated = NSTACKX_TRUE;
391     }
392 
393     internalDevice->capabilityBitmapNum = deviceInfo->capabilityBitmapNum;
394 
395     if (memset_s(internalDevice->capabilityBitmap, sizeof(internalDevice->capabilityBitmap),
396         0, sizeof(internalDevice->capabilityBitmap)) != EOK) {
397         DFINDER_LOGE(TAG, "UpdateCapabilityBitmap, memset_s fails");
398         return NSTACKX_EFAILED;
399     }
400     if (deviceInfo->capabilityBitmapNum) {
401         if (memcpy_s(internalDevice->capabilityBitmap, sizeof(internalDevice->capabilityBitmap),
402             deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
403             DFINDER_LOGE(TAG, "UpdateCapabilityBitmap, capabilityBitmap copy error");
404             return NSTACKX_EFAILED;
405         }
406     }
407     return NSTACKX_EOK;
408 }
409 
UpdateDeviceInfoInner(DeviceInfo * internalDevice,const DeviceInfo * deviceInfo,uint8_t * updated)410 static int32_t UpdateDeviceInfoInner(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo,
411     uint8_t *updated)
412 {
413     if (internalDevice == NULL || deviceInfo == NULL) {
414         DFINDER_LOGE(TAG, "UpdateDeviceInfo input error");
415         return NSTACKX_EFAILED;
416     }
417     if (internalDevice->deviceType != deviceInfo->deviceType) {
418         DFINDER_LOGE(TAG, "deviceType is different");
419         return NSTACKX_EFAILED;
420     }
421 
422     if (strcmp(internalDevice->deviceName, deviceInfo->deviceName) != 0) {
423         if (strcpy_s(internalDevice->deviceName, sizeof(internalDevice->deviceName), deviceInfo->deviceName) != EOK) {
424             DFINDER_LOGE(TAG, "deviceName copy error");
425             return NSTACKX_EFAILED;
426         }
427         *updated = NSTACKX_TRUE;
428     }
429 
430     if (strlen(deviceInfo->version) > 0 && strcmp(internalDevice->version, deviceInfo->version) != 0) {
431         if (strcpy_s(internalDevice->version, sizeof(internalDevice->version), deviceInfo->version) != EOK) {
432             DFINDER_LOGE(TAG, "hicom version copy error");
433             return NSTACKX_EFAILED;
434         }
435         *updated = NSTACKX_TRUE;
436     }
437 
438     if (UpdateCapabilityBitmap(internalDevice, deviceInfo, updated) != NSTACKX_EOK) {
439         DFINDER_LOGE(TAG, "UpdateCapabilityBitmap fails");
440         return NSTACKX_EFAILED;
441     }
442 
443     return NSTACKX_EOK;
444 }
445 
GetNetChannelChangeIdx(const LocalIfInfoAll * ifInfoAll,size_t size,uint8_t * changeIdx)446 static void GetNetChannelChangeIdx(const LocalIfInfoAll *ifInfoAll, size_t size, uint8_t *changeIdx)
447 {
448     struct timespec nowTime;
449     ClockGetTime(CLOCK_MONOTONIC, &nowTime);
450     uint32_t temp, max = 0;
451     for (uint32_t i = 0; i < size; i++) {
452         temp = GetTimeDiffUs(&nowTime, &ifInfoAll->deviceRemoteChannelInfo[i].lastRecvTime);
453         if (max < temp) {
454             max = temp;
455             *changeIdx = i;
456         }
457     }
458 }
459 
UpdateDeviceNetChannelInfo(DeviceInfo * internalDevice,const DeviceInfo * deviceInfo,uint8_t * updated)460 static void UpdateDeviceNetChannelInfo(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo, uint8_t *updated)
461 {
462 #ifdef DFINDER_SUPPORT_MULTI_NIF
463     uint8_t updateChannel = NSTACKX_TRUE;
464     uint8_t curNifIdx = internalDevice->nextNifIdx - 1;
465     uint8_t i;
466     for (i = 0; i < NSTACKX_MAX_NET_CHANNEL_NUM; ++i) {
467         if ((memcmp(&internalDevice->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[i].remoteChannelInfo,
468             &deviceInfo->netChannelInfo, sizeof(deviceInfo->netChannelInfo)) == 0) &&
469             (internalDevice->portNumber == deviceInfo->portNumber)) {
470             DFINDER_LOGD(TAG, "same remote channel info found at idx %u", i);
471             ClockGetTime(CLOCK_MONOTONIC,
472                 &internalDevice->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[i].lastRecvTime);
473             internalDevice->localIfInfoAll[curNifIdx].nextRemoteIdx = i + 1;
474             updateChannel = NSTACKX_FALSE;
475             break;
476         }
477     }
478     if (updateChannel) {
479         i = internalDevice->localIfInfoAll[curNifIdx].nextRemoteIdx;
480         if (i >= NSTACKX_MAX_NET_CHANNEL_NUM) {
481             DFINDER_LOGE(TAG, "next remote idx is over range, Replace one");
482             uint8_t changeIdx = 0;
483             GetNetChannelChangeIdx(&internalDevice->localIfInfoAll[curNifIdx], NSTACKX_MAX_NET_CHANNEL_NUM, &changeIdx);
484             internalDevice->portNumber = deviceInfo->portNumber;
485             internalDevice->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[changeIdx].remoteChannelInfo =
486                 deviceInfo->netChannelInfo;
487             ClockGetTime(CLOCK_MONOTONIC,
488                 &internalDevice->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[i].lastRecvTime);
489             internalDevice->localIfInfoAll[curNifIdx].nextRemoteIdx = changeIdx + 1;
490             *updated = NSTACKX_TRUE;
491         } else {
492             DFINDER_LOGD(TAG, "copy net channel info to next idx, idx-%u", i);
493             internalDevice->portNumber = deviceInfo->portNumber;
494             internalDevice->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[i].remoteChannelInfo =
495                 deviceInfo->netChannelInfo;
496             ClockGetTime(CLOCK_MONOTONIC,
497                 &internalDevice->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[i].lastRecvTime);
498             ++(internalDevice->localIfInfoAll[curNifIdx].nextRemoteIdx);
499             *updated = NSTACKX_TRUE;
500         }
501     }
502 #else
503     if (memcmp(&internalDevice->netChannelInfo, &deviceInfo->netChannelInfo, sizeof(deviceInfo->netChannelInfo)) ||
504         (internalDevice->portNumber != deviceInfo->portNumber)) {
505         (void)memcpy_s(&internalDevice->netChannelInfo, sizeof(internalDevice->netChannelInfo),
506             &deviceInfo->netChannelInfo, sizeof(deviceInfo->netChannelInfo));
507         internalDevice->portNumber = deviceInfo->portNumber;
508         *updated = NSTACKX_TRUE;
509     }
510 #endif
511 }
512 
CheckAndUpdateBusinessAll(BusinessDataAll * a,const BusinessDataAll * b,uint8_t * updated)513 static uint32_t CheckAndUpdateBusinessAll(BusinessDataAll *a, const BusinessDataAll *b, uint8_t *updated)
514 {
515     if (b->isBroadcast == NSTACKX_TRUE) {
516         if (strcmp(a->businessDataBroadcast, b->businessDataBroadcast) != 0) {
517             if (strcpy_s(a->businessDataBroadcast, NSTACKX_MAX_BUSINESS_DATA_LEN,
518                 b->businessDataBroadcast) != EOK) {
519                 return NSTACKX_EFAILED;
520             }
521             *updated = NSTACKX_TRUE;
522         }
523     } else {
524         if (strcmp(a->businessDataUnicast, b->businessDataUnicast) != 0) {
525             if (strcpy_s(a->businessDataUnicast, NSTACKX_MAX_BUSINESS_DATA_LEN,
526                 b->businessDataUnicast) != EOK) {
527                 return NSTACKX_EFAILED;
528             }
529             *updated = NSTACKX_TRUE;
530         }
531     }
532     a->isBroadcast = b->isBroadcast;
533     return NSTACKX_EOK;
534 }
535 
UpdateDeviceInfoBusinessData(DeviceInfo * internalDevice,const DeviceInfo * deviceInfo,uint8_t * updated)536 static int32_t UpdateDeviceInfoBusinessData(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo, uint8_t *updated)
537 {
538 #ifdef DFINDER_SUPPORT_MULTI_NIF
539     uint8_t curNifIdx = internalDevice->nextNifIdx - 1;
540     uint8_t curChannelIdx = internalDevice->localIfInfoAll[curNifIdx].nextRemoteIdx - 1;
541 
542     if (CheckAndUpdateBusinessAll(&internalDevice->localIfInfoAll[curNifIdx].
543         deviceRemoteChannelInfo[curChannelIdx].businessDataAll, &deviceInfo->businessData, updated) != NSTACKX_EOK) {
544         return NSTACKX_EFAILED;
545     }
546 
547 #else
548     if (CheckAndUpdateBusinessAll(&internalDevice->businessData, &deviceInfo->businessData, updated) != NSTACKX_EOK) {
549         return NSTACKX_EFAILED;
550     }
551 #endif
552     return NSTACKX_EOK;
553 }
554 
UpdateDeviceListChangeStateWhenActive(UpdateState * curState,uint8_t * updated)555 static void UpdateDeviceListChangeStateWhenActive(UpdateState *curState, uint8_t *updated)
556 {
557     switch (*curState) {
558         case DFINDER_UPDATE_STATE_NULL:
559             *curState = DFINDER_UPDATE_STATE_UNICAST;
560             *updated = NSTACKX_TRUE;
561             break;
562         case DFINDER_UPDATE_STATE_BROADCAST:
563             if (*updated == NSTACKX_TRUE) {
564                 *curState = DFINDER_UPDATE_STATE_UNICAST;
565             } else {
566                 *curState = DFINDER_UPDATE_STATE_ALL;
567                 *updated = NSTACKX_TRUE;
568             }
569             break;
570         case DFINDER_UPDATE_STATE_UNICAST:
571             break;
572         case DFINDER_UPDATE_STATE_ALL:
573             if (*updated == NSTACKX_TRUE) {
574                 *curState = DFINDER_UPDATE_STATE_UNICAST;
575             }
576             break;
577         default:
578             break;
579     }
580 }
581 
UpdateDeviceListChangeStateWhenPassive(UpdateState * curState,uint8_t * updated)582 static void UpdateDeviceListChangeStateWhenPassive(UpdateState *curState, uint8_t *updated)
583 {
584     switch (*curState) {
585         case DFINDER_UPDATE_STATE_NULL:
586             *curState = DFINDER_UPDATE_STATE_BROADCAST;
587             *updated = NSTACKX_TRUE;
588             break;
589         case DFINDER_UPDATE_STATE_BROADCAST:
590             break;
591         case DFINDER_UPDATE_STATE_UNICAST:
592             if (*updated == NSTACKX_TRUE) {
593                 *curState = DFINDER_UPDATE_STATE_BROADCAST;
594             } else {
595                 *curState = DFINDER_UPDATE_STATE_ALL;
596                 *updated = NSTACKX_TRUE;
597             }
598             break;
599         case DFINDER_UPDATE_STATE_ALL:
600             if (*updated == NSTACKX_TRUE) {
601                 *curState = DFINDER_UPDATE_STATE_BROADCAST;
602             }
603             break;
604         default:
605             break;
606     }
607 }
608 
CheckAndUpdateDeviceListChangeState(DeviceInfo * internalDevice,const DeviceInfo * deviceInfo,uint8_t * updated)609 static void CheckAndUpdateDeviceListChangeState(DeviceInfo *internalDevice,
610     const DeviceInfo *deviceInfo, uint8_t *updated)
611 {
612 #ifdef DFINDER_SUPPORT_MULTI_NIF
613     uint8_t curNifIdx = internalDevice->nextNifIdx - 1;
614     uint8_t curChannelIdx = internalDevice->localIfInfoAll[curNifIdx].nextRemoteIdx - 1;
615     UpdateState *curState = &(internalDevice->localIfInfoAll[curNifIdx].
616         deviceRemoteChannelInfo[curChannelIdx].updateState);
617 #else
618     UpdateState *curState = &(internalDevice->updateState);
619 #endif
620     if (deviceInfo->discoveryType == NSTACKX_DISCOVERY_TYPE_PASSIVE) {
621         UpdateDeviceListChangeStateWhenPassive(curState, updated);
622     } else {
623         UpdateDeviceListChangeStateWhenActive(curState, updated);
624     }
625 }
626 
UpdateDeviceInfo(DeviceInfo * internalDevice,const DeviceInfo * deviceInfo,uint8_t * updatedPtr)627 static int32_t UpdateDeviceInfo(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo, uint8_t *updatedPtr)
628 {
629     uint8_t updated = NSTACKX_FALSE;
630     if (UpdateDeviceInfoInner(internalDevice, deviceInfo, &updated) != NSTACKX_EOK) {
631         DFINDER_LOGE(TAG, "UpdateDeviceInfoInner error");
632         return NSTACKX_EFAILED;
633     }
634 
635     if (strcmp(internalDevice->deviceHash, deviceInfo->deviceHash) != 0) {
636         if (strcpy_s(internalDevice->deviceHash, sizeof(internalDevice->deviceHash), deviceInfo->deviceHash) != EOK) {
637             DFINDER_LOGE(TAG, "deviceHash copy error");
638             return NSTACKX_EFAILED;
639         }
640         updated = NSTACKX_TRUE;
641     }
642 
643     if (internalDevice->mode != deviceInfo->mode) {
644         internalDevice->mode = deviceInfo->mode;
645         updated = NSTACKX_TRUE;
646     }
647 
648     if (strcmp(internalDevice->serviceData, deviceInfo->serviceData) != 0) {
649         if (strcpy_s(internalDevice->serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, deviceInfo->serviceData) != EOK) {
650             DFINDER_LOGE(TAG, "serviceData copy error");
651             return NSTACKX_EFAILED;
652         }
653         updated = NSTACKX_TRUE;
654     }
655     if (internalDevice->businessType != deviceInfo->businessType) {
656         internalDevice->businessType = deviceInfo->businessType;
657         updated = NSTACKX_TRUE;
658     }
659 
660     if (UpdateDeviceInfoBusinessData(internalDevice, deviceInfo, &updated) != NSTACKX_EOK) {
661         DFINDER_LOGE(TAG, "businessData copy error");
662         return NSTACKX_EFAILED;
663     }
664     if (strcpy_s(internalDevice->networkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
665         g_localDeviceInfo.networkName) != EOK) {
666         DFINDER_LOGE(TAG, "copy local report nif name failed");
667         return NSTACKX_EFAILED;
668     }
669     internalDevice->discoveryType = deviceInfo->discoveryType;
670     *updatedPtr |= updated;
671     return NSTACKX_EOK;
672 }
673 
674 #ifdef DFINDER_SUPPORT_MULTI_NIF
UpdateDeviceInfoWithIdx(DeviceInfo * internalDevice,const DeviceInfo * deviceInfo,uint8_t * updatedPtr,uint8_t idx)675 static int32_t UpdateDeviceInfoWithIdx(DeviceInfo *internalDevice, const DeviceInfo *deviceInfo,
676     uint8_t *updatedPtr, uint8_t idx)
677 {
678     uint8_t updated = NSTACKX_FALSE;
679     uint8_t needUpdateNif = NSTACKX_TRUE;
680     uint8_t i;
681     const char *lNifName = GetLocalNifNameWithIdx(idx);
682     if (lNifName == NULL) {
683         DFINDER_LOGE(TAG, "get local nif name with idx-%hhu failed", idx);
684         return NSTACKX_EFAILED;
685     }
686 
687     for (i = 0; i < NSTACKX_MAX_LISTENED_NIF_NUM; ++i) {
688         if (strcmp(internalDevice->localIfInfoAll[i].localIfInfo.networkName, lNifName) == 0) {
689             DFINDER_LOGD(TAG, "same nif name found, at idx-%u", i);
690             needUpdateNif = NSTACKX_FALSE;
691             internalDevice->nextNifIdx = i + 1;
692             break;
693         }
694     }
695 
696     if (needUpdateNif) {
697         i = internalDevice->nextNifIdx;
698         if (i >= NSTACKX_MAX_LISTENED_NIF_NUM) {
699             DFINDER_LOGE(TAG, "next nif idx is over range, Replace one");
700             uint8_t changeIdx = internalDevice->nextNifIdx % NSTACKX_MAX_LISTENED_NIF_NUM;
701             if (strcpy_s(internalDevice->localIfInfoAll[changeIdx].localIfInfo.networkName,
702                 NSTACKX_MAX_INTERFACE_NAME_LEN, lNifName) != EOK) {
703                 DFINDER_LOGE(TAG, "copy local report nif name failed");
704                 return NSTACKX_EFAILED;
705             }
706             /* rely on NSTACKX_MAX_LISTENED_NIF_NUM == 2 */
707             internalDevice->nextNifIdx = changeIdx + 1;
708             updated = NSTACKX_TRUE;
709         } else {
710             DFINDER_LOGD(TAG, "not first time found, nif name to copy is: %s, idx is: %u", lNifName, i);
711             if (strcpy_s(internalDevice->localIfInfoAll[i].localIfInfo.networkName,
712                 NSTACKX_MAX_INTERFACE_NAME_LEN, lNifName) != EOK) {
713                 DFINDER_LOGE(TAG, "copy local report nif name failed");
714                 return NSTACKX_EFAILED;
715             }
716             ++(internalDevice->nextNifIdx);
717             updated = NSTACKX_TRUE;
718         }
719     }
720     UpdateDeviceNetChannelInfo(internalDevice, deviceInfo, &updated);
721     if (UpdateDeviceInfo(internalDevice, deviceInfo, &updated) != NSTACKX_EOK) {
722         return NSTACKX_EFAILED;
723     }
724 
725     *updatedPtr = updated;
726     return NSTACKX_EOK;
727 }
728 #endif
729 
DeviceListChangeHandle(void)730 static void DeviceListChangeHandle(void)
731 {
732     size_t deviceListLen = sizeof(NSTACKX_DeviceInfo) * g_maxDeviceNum;
733     NSTACKX_DeviceInfo *deviceList = (NSTACKX_DeviceInfo *)malloc(deviceListLen);
734     if (deviceList == NULL) {
735         DFINDER_LOGE(TAG, "malloc for device list failed");
736         return;
737     }
738     uint32_t count = g_maxDeviceNum;
739     (void)memset_s(deviceList, deviceListLen, 0, deviceListLen);
740     GetDeviceList(g_deviceList, deviceList, &count, true);
741     if (count == 0) {
742         DFINDER_LOGW(TAG, "count is zero, do not notify");
743         free(deviceList);
744         return;
745     }
746     NotifyDeviceListChanged(deviceList, count);
747     if (CoapDiscoverRequestOngoing()) {
748         NotifyDeviceFound(deviceList, count);
749     }
750     free(deviceList);
751 }
752 
UpdateDeviceDbInDeviceList(const DeviceInfo * deviceInfo,uint8_t idx,uint8_t forceUpdate)753 static int32_t UpdateDeviceDbInDeviceList(const DeviceInfo *deviceInfo, uint8_t idx, uint8_t forceUpdate)
754 {
755     DeviceInfo *internalDevice = NULL;
756     uint8_t updated = NSTACKX_FALSE;
757     internalDevice = GetDeviceInfoById(deviceInfo->deviceId, g_deviceList);
758     if (internalDevice == NULL) {
759 #ifdef DFINDER_SUPPORT_MULTI_NIF
760         internalDevice = CreateNewDeviceWithIdx(g_deviceList, deviceInfo, idx);
761 #else
762         (void)idx;
763         internalDevice = CreateNewDevice(g_deviceList, deviceInfo);
764 #endif
765         if (internalDevice == NULL) {
766             IncStatistics(STATS_OVER_DEVICE_LIMIT);
767             return NSTACKX_ENOMEM;
768         }
769         updated = NSTACKX_TRUE;
770     } else {
771 #ifdef DFINDER_SUPPORT_MULTI_NIF
772         if (UpdateDeviceInfoWithIdx(internalDevice, deviceInfo, &updated, idx) != NSTACKX_EOK) {
773 #else
774         (void)idx;
775         (void)UpdateDeviceNetChannelInfo(internalDevice, deviceInfo, &updated);
776         if (UpdateDeviceInfo(internalDevice, deviceInfo, &updated) != NSTACKX_EOK) {
777 #endif
778             return NSTACKX_EFAILED;
779         }
780     }
781     CheckAndUpdateDeviceListChangeState(internalDevice, deviceInfo, &updated);
782     internalDevice->update = updated;
783     if (updated || forceUpdate) {
784         DFINDER_LOGD(TAG, "updated is: %hhu, forceUpdate is: %hhu", updated, forceUpdate);
785 #ifdef DFINDER_SUPPORT_MULTI_NIF
786         DeviceListChangeHandleMultiNif();
787 #else
788         DeviceListChangeHandle();
789 #endif
790     }
791     return NSTACKX_EOK;
792 }
793 
794 static int32_t UpdateDeviceDbEx(const DeviceInfo *deviceInfo, uint8_t forceUpdate)
795 {
796     if (deviceInfo == NULL) {
797         return NSTACKX_EINVAL;
798     }
799     if (UpdateDeviceDbInDeviceList(deviceInfo, 0, forceUpdate) != NSTACKX_EOK) {
800         DFINDER_LOGE(TAG, "update when receive broadcast fail");
801         return NSTACKX_EFAILED;
802     }
803     return NSTACKX_EOK;
804 }
805 
806 int32_t UpdateDeviceDb(const DeviceInfo *deviceInfo, uint8_t forceUpdate)
807 {
808     int32_t ret = UpdateDeviceDbEx(deviceInfo, forceUpdate);
809     if (ret != NSTACKX_EOK) {
810         IncStatistics(STATS_UPDATE_DEVICE_DB_FAILED);
811     }
812     return ret;
813 }
814 #else
815 int32_t DeviceInfoNotify(const DeviceInfo *deviceInfo, uint8_t forceUpdate)
816 {
817     NSTACKX_DeviceInfo notifyDevice;
818 
819     (void)forceUpdate;
820     if (!MatchDeviceFilter(deviceInfo)) {
821         return NSTACKX_EOK;
822     }
823     (void)memset_s(&notifyDevice, sizeof(notifyDevice), 0, sizeof(notifyDevice));
824     if (GetNotifyDeviceInfo(&notifyDevice, deviceInfo) != NSTACKX_EOK) {
825         DFINDER_LOGE(TAG, "GetNotifyDeviceInfo failed");
826         return NSTACKX_EFAILED;
827     }
828     NotifyDeviceListChanged(&notifyDevice, NSTACKX_MAX_DEVICE_NUM);
829     if (CoapDiscoverRequestOngoing()) {
830         NotifyDeviceFound(&notifyDevice, NSTACKX_MAX_DEVICE_NUM);
831     }
832     return NSTACKX_EOK;
833 }
834 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
835 
836 #ifdef DFINDER_SUPPORT_MULTI_NIF
837 int32_t UpdateDeviceDbWithIdx(const DeviceInfo *deviceInfo, uint8_t forceUpdate, uint8_t idx)
838 {
839     if (deviceInfo == NULL) {
840         return NSTACKX_EINVAL;
841     }
842     if (UpdateDeviceDbInDeviceList(deviceInfo, idx, forceUpdate) != NSTACKX_EOK) {
843         DFINDER_LOGE(TAG, "update when receive broadcast fail with multi nif");
844         return NSTACKX_EFAILED;
845     }
846     return NSTACKX_EOK;
847 }
848 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
849 
850 static int32_t GetReservedInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList)
851 {
852     char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN];
853     (void)memset_s(wifiIpAddr, sizeof(wifiIpAddr), 0, sizeof(wifiIpAddr));
854     (void)inet_ntop(AF_INET, &deviceInfo->netChannelInfo.wifiApInfo.ip, wifiIpAddr, sizeof(wifiIpAddr));
855     if (sprintf_s(deviceList[0].reservedInfo, sizeof(deviceList[0].reservedInfo),
856         NSTACKX_RESERVED_INFO_JSON_FORMAT, wifiIpAddr) == NSTACKX_EFAILED) {
857         return NSTACKX_EFAILED;
858     }
859     cJSON *item = cJSON_Parse(deviceList[0].reservedInfo);
860     if (item == NULL) {
861         DFINDER_LOGE(TAG, "pares deviceList fails");
862         return NSTACKX_EFAILED;
863     }
864 
865     if (deviceInfo->mode != DEFAULT_MODE) {
866         if (!cJSON_AddNumberToObject(item, "mode", deviceInfo->mode)) {
867             DFINDER_LOGE(TAG, "add mode to object failed");
868         }
869     }
870     if (!cJSON_AddStringToObject(item, "hwAccountHashVal", deviceInfo->deviceHash)) {
871         DFINDER_LOGE(TAG, "add hwAccountHashVal to object failed");
872     }
873     const char *ver = (strlen(deviceInfo->version) == 0) ? NSTACKX_DEFAULT_VER : deviceInfo->version;
874     if (!cJSON_AddStringToObject(item, "version", ver)) {
875         DFINDER_LOGE(TAG, "add hwAccountHashVal to object failed");
876     }
877     char *newData = cJSON_Print(item);
878     if (newData == NULL) {
879         cJSON_Delete(item);
880         return NSTACKX_EFAILED;
881     }
882     (void)memset_s(deviceList[0].reservedInfo, sizeof(deviceList[0].reservedInfo), 0,
883                    sizeof(deviceList[0].reservedInfo));
884     if (strcpy_s(deviceList[0].reservedInfo, sizeof(deviceList[0].reservedInfo), newData) != EOK) {
885         cJSON_Delete(item);
886         free(newData);
887         return NSTACKX_EFAILED;
888     }
889     cJSON_Delete(item);
890     free(newData);
891     return NSTACKX_EOK;
892 }
893 
894 void PushPublishInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList, uint32_t deviceNum)
895 {
896     if (deviceNum != PUBLISH_DEVICE_NUM || deviceInfo == NULL || deviceList == NULL) {
897         return;
898     }
899     if (strcpy_s(deviceList[0].deviceId, sizeof(deviceList[0].deviceId), deviceInfo->deviceId) != EOK ||
900         strcpy_s(deviceList[0].deviceName, sizeof(deviceList[0].deviceName), deviceInfo->deviceName) != EOK ||
901         strcpy_s(deviceList[0].version, sizeof(deviceList[0].version), deviceInfo->version) != EOK) {
902         return;
903     }
904     deviceList[0].capabilityBitmapNum = deviceInfo->capabilityBitmapNum;
905     if (deviceInfo->capabilityBitmapNum) {
906         if (memcpy_s(deviceList[0].capabilityBitmap, sizeof(deviceList[0].capabilityBitmap),
907             deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
908             return;
909         }
910     }
911 
912     if (GetReservedInfo(deviceInfo, deviceList) != NSTACKX_EOK) {
913         DFINDER_LOGE(TAG, "GetReservedInfo Failed");
914         return;
915     }
916     deviceList[0].deviceType = deviceInfo->deviceType;
917 }
918 
919 static bool MatchDeviceFilter(const DeviceInfo *deviceInfo)
920 {
921     uint32_t i, ret;
922 
923     if (g_filterCapabilityBitmapNum == 0) {
924         return true;
925     }
926 
927     for (i = 0; ((i < g_filterCapabilityBitmapNum) && (i < deviceInfo->capabilityBitmapNum)); i++) {
928         ret = (g_filterCapabilityBitmap[i] & (deviceInfo->capabilityBitmap[i]));
929         if (ret != 0) {
930             return true;
931         }
932     }
933     return false;
934 }
935 
936 #ifdef DFINDER_SUPPORT_MULTI_NIF
937 static int32_t AddBusinessDataStringToJsonObj(const char* businessData, cJSON *item)
938 {
939     if (businessData == NULL || strlen(businessData) > NSTACKX_MAX_BUSINESS_DATA_LEN) {
940         DFINDER_LOGE(TAG, "AddBusinessDataStringToJsonObj error");
941         return NSTACKX_EFAILED;
942     }
943     if (!cJSON_AddStringToObject(item, "bData", businessData)) {
944         DFINDER_LOGE(TAG, "cJSON_AddStringToObject: businessData error");
945         return NSTACKX_EFAILED;
946     }
947     return NSTACKX_EOK;
948 }
949 
950 int32_t BuildBusinessDataJsonPayload(const DeviceInfo *deviceInfo, uint8_t curNifIdx,
951     uint8_t curChannelIdx, cJSON *item)
952 {
953     const DeviceRemoteChannelInfo *temp =
954         &deviceInfo->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[curChannelIdx];
955     if (temp->businessDataAll.isBroadcast == NSTACKX_TRUE) {
956         return AddBusinessDataStringToJsonObj(temp->businessDataAll.businessDataBroadcast, item);
957     } else {
958         return AddBusinessDataStringToJsonObj(temp->businessDataAll.businessDataUnicast, item);
959     }
960 }
961 #endif
962 
963 static int8_t SetServiceDataFromDeviceInfo(cJSON *item, const DeviceInfo *deviceInfo)
964 {
965     if (item == NULL || deviceInfo == NULL) {
966         DFINDER_LOGE(TAG, "item or deviceInfo is null");
967         return NSTACKX_EFAILED;
968     }
969     if (strlen(deviceInfo->serviceData) != 0 && strlen(deviceInfo->serviceData) < NSTACKX_MAX_SERVICE_DATA_LEN) {
970         if (!cJSON_AddStringToObject(item, "serviceData", deviceInfo->serviceData)) {
971             DFINDER_LOGE(TAG, "cJSON_AddStringToObject: serviceData error");
972             return NSTACKX_EFAILED;
973         }
974     }
975 #ifndef DFINDER_USE_MINI_NSTACKX
976     if (strlen(deviceInfo->extendServiceData) != 0 &&
977         strlen(deviceInfo->extendServiceData) < NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN) {
978         if (!cJSON_AddStringToObject(item, "extendServiceData", deviceInfo->extendServiceData)) {
979             DFINDER_LOGE(TAG, "cJSON_AddStringToObject: extendServiceData error");
980             return NSTACKX_EFAILED;
981         }
982     }
983 #endif
984 
985 #ifdef DFINDER_SUPPORT_MULTI_NIF
986     uint8_t curNifIdx = deviceInfo->nextNifIdx - 1;
987     uint8_t curChannelIdx = deviceInfo->localIfInfoAll[curNifIdx].nextRemoteIdx - 1;
988     if (BuildBusinessDataJsonPayload(deviceInfo, curNifIdx, curChannelIdx, item) != NSTACKX_EOK) {
989         return NSTACKX_EFAILED;
990     }
991 #else
992     if (deviceInfo->businessData.isBroadcast == NSTACKX_TRUE) {
993         if (strlen(deviceInfo->businessData.businessDataBroadcast) != 0 &&
994             strlen(deviceInfo->businessData.businessDataBroadcast) < NSTACKX_MAX_BUSINESS_DATA_LEN) {
995             if (!cJSON_AddStringToObject(item, "bData", deviceInfo->businessData.businessDataBroadcast)) {
996                 DFINDER_LOGE(TAG, "cJSON_AddStringToObject: businessData error");
997                 return NSTACKX_EFAILED;
998             }
999         }
1000     } else {
1001         if (strlen(deviceInfo->businessData.businessDataUnicast) != 0 &&
1002             strlen(deviceInfo->businessData.businessDataUnicast) < NSTACKX_MAX_BUSINESS_DATA_LEN) {
1003             if (!cJSON_AddStringToObject(item, "bData", deviceInfo->businessData.businessDataUnicast)) {
1004                 DFINDER_LOGE(TAG, "cJSON_AddStringToObject: businessData error");
1005                 return NSTACKX_EFAILED;
1006             }
1007         }
1008     }
1009 #endif
1010     return NSTACKX_EOK;
1011 }
1012 
1013 static int32_t SetReservedInfoFromDeviceInfoInner(NSTACKX_DeviceInfo *deviceList, uint32_t idx,
1014     const DeviceInfo *deviceInfo, const NetChannelInfo *netChannelInfo)
1015 {
1016     char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN];
1017     char *ver = NULL;
1018     char *newData = NULL;
1019     int32_t ret  = NSTACKX_EFAILED;
1020     if (deviceList == NULL) {
1021         DFINDER_LOGE(TAG, "deviceList or deviceInfo is null");
1022         return NSTACKX_EINVAL;
1023     }
1024 
1025     (void)memset_s(wifiIpAddr, sizeof(wifiIpAddr), 0, sizeof(wifiIpAddr));
1026     (void)inet_ntop(AF_INET, &netChannelInfo->wifiApInfo.ip, wifiIpAddr, sizeof(wifiIpAddr));
1027     if (sprintf_s(deviceList[idx].reservedInfo, sizeof(deviceList[idx].reservedInfo),
1028         NSTACKX_RESERVED_INFO_JSON_FORMAT, wifiIpAddr) == -1) {
1029         DFINDER_LOGE(TAG, "sprintf_s reservedInfo with wifiIpAddr fails");
1030         return NSTACKX_EAGAIN;
1031     }
1032     cJSON *item = cJSON_Parse(deviceList[idx].reservedInfo);
1033     if (item == NULL) {
1034         DFINDER_LOGE(TAG, "pares deviceList fails");
1035         return NSTACKX_EINVAL;
1036     }
1037 
1038     if (deviceInfo->mode != 0 && !cJSON_AddNumberToObject(item, "mode", deviceInfo->mode)) {
1039         goto L_END;
1040     }
1041     if (!cJSON_AddStringToObject(item, "hwAccountHashVal", deviceInfo->deviceHash)) {
1042         goto L_END;
1043     }
1044     ver = (strlen(deviceInfo->version) == 0) ? NSTACKX_DEFAULT_VER : (char *)deviceInfo->version;
1045     if (!cJSON_AddStringToObject(item, "version", ver)) {
1046         goto L_END;
1047     }
1048     if (SetServiceDataFromDeviceInfo(item, deviceInfo) != NSTACKX_EOK) {
1049         goto L_END;
1050     }
1051     newData = cJSON_Print(item);
1052     if (newData == NULL) {
1053         goto L_END;
1054     }
1055     (void)memset_s(deviceList[idx].reservedInfo, sizeof(deviceList[idx].reservedInfo),
1056                    0, sizeof(deviceList[idx].reservedInfo));
1057     if (strcpy_s(deviceList[idx].reservedInfo, sizeof(deviceList[idx].reservedInfo), newData) != EOK) {
1058         free(newData);
1059         DFINDER_LOGE(TAG, "strcpy_s fails");
1060         goto L_END;
1061     }
1062     free(newData);
1063     ret = NSTACKX_EOK;
1064 L_END:
1065     cJSON_Delete(item);
1066     return ret;
1067 }
1068 
1069 #ifdef DFINDER_SUPPORT_MULTI_NIF
1070 static void CopyDeviceListType(const DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *device)
1071 {
1072     device->discoveryType = deviceInfo->discoveryType;
1073     device->deviceType = deviceInfo->deviceType;
1074     device->businessType = deviceInfo->businessType;
1075     device->mode = deviceInfo->mode;
1076     device->update = deviceInfo->update;
1077 }
1078 
1079 static int32_t SetReservedInfoFromDeviceInfoWithIdx(NSTACKX_DeviceInfo *deviceList, uint32_t idx,
1080     const DeviceInfo *deviceInfo)
1081 {
1082     uint8_t curNifIdx = deviceInfo->nextNifIdx - 1;
1083     uint8_t curChannelIdx = deviceInfo->localIfInfoAll[curNifIdx].nextRemoteIdx - 1;
1084     return SetReservedInfoFromDeviceInfoInner(deviceList, idx, deviceInfo,
1085         &deviceInfo->localIfInfoAll[curNifIdx].deviceRemoteChannelInfo[curChannelIdx].remoteChannelInfo);
1086 }
1087 #endif
1088 
1089 static int32_t SetReservedInfoFromDeviceInfo(NSTACKX_DeviceInfo *deviceList, uint32_t idx,
1090     const DeviceInfo *deviceInfo)
1091 {
1092     return SetReservedInfoFromDeviceInfoInner(deviceList, idx, deviceInfo, &deviceInfo->netChannelInfo);
1093 }
1094 
1095 #ifdef DFINDER_SUPPORT_MULTI_NIF
1096 static void GetDeviceListWithReportIdx(void *dbList, NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr,
1097     bool doFilter)
1098 {
1099     DeviceInfo *deviceInfo = NULL;
1100     int64_t idx = -1;
1101     uint32_t count = 0;
1102 
1103     for (uint32_t i = 0; i < g_maxDeviceNum; i++) {
1104         if (count >= *deviceCountPtr) {
1105             break;
1106         }
1107 
1108         deviceInfo = DatabaseGetNextRecord(dbList, &idx);
1109         if (deviceInfo == NULL) {
1110             DFINDER_LOGE(TAG, "deviceInfo is null");
1111             break;
1112         }
1113 
1114         if (doFilter && !MatchDeviceFilter(deviceInfo)) {
1115             DFINDER_LOGW(TAG, "filter device");
1116             continue;
1117         }
1118 
1119         if (strcpy_s(deviceList[count].deviceId, sizeof(deviceList[count].deviceId), deviceInfo->deviceId) != EOK ||
1120             strcpy_s(deviceList[count].deviceName, sizeof(deviceList[count].deviceName),
1121                      deviceInfo->deviceName) != EOK ||
1122             strcpy_s(deviceList[count].version, sizeof(deviceList[count].version), deviceInfo->version) != EOK) {
1123             break;
1124         }
1125         deviceList[count].capabilityBitmapNum = deviceInfo->capabilityBitmapNum;
1126         if (deviceInfo->capabilityBitmapNum) {
1127             if (memcpy_s(deviceList[count].capabilityBitmap, sizeof(deviceList[count].capabilityBitmap),
1128                 deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
1129                 DFINDER_LOGE(TAG, "memcpy failed");
1130                 break;
1131             }
1132         }
1133 
1134         int8_t result = SetReservedInfoFromDeviceInfoWithIdx(deviceList, count, deviceInfo);
1135         if (result == NSTACKX_EAGAIN) {
1136             DFINDER_LOGE(TAG, "set reserved info from device info failed, sprintf_s or strcpy_s fails");
1137             break;
1138         } else if (result == NSTACKX_EINVAL || result == NSTACKX_EFAILED) {
1139             DFINDER_LOGE(TAG, "set reserved info from device info failed");
1140             return;
1141         }
1142         uint8_t curNifIdx = deviceInfo->nextNifIdx - 1;
1143         if (strcpy_s(deviceList[count].networkName, sizeof(deviceList[count].networkName),
1144                 deviceInfo->localIfInfoAll[curNifIdx].localIfInfo.networkName) != EOK) {
1145             DFINDER_LOGE(TAG, "copy deviceList[count].networkName failed");
1146             break;
1147         }
1148         CopyDeviceListType(deviceInfo, &deviceList[count]);
1149         deviceInfo->update = NSTACKX_FALSE;
1150         ++count;
1151     }
1152 
1153     *deviceCountPtr = count;
1154 }
1155 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
1156 
1157 #ifdef DFINDER_SAVE_DEVICE_LIST
1158 static void GetDeviceList(void *dbList, NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr, bool doFilter)
1159 {
1160     DeviceInfo *deviceInfo = NULL;
1161     int64_t idx = -1;
1162     uint32_t count = 0;
1163     uint32_t i;
1164 
1165     for (i = 0; i < g_maxDeviceNum; i++) {
1166         if (count >= *deviceCountPtr) {
1167             break;
1168         }
1169 
1170         deviceInfo = DatabaseGetNextRecord(dbList, &idx);
1171         if (deviceInfo == NULL) {
1172             break;
1173         }
1174 
1175         if (doFilter && !MatchDeviceFilter(deviceInfo)) {
1176             continue;
1177         }
1178 
1179         if (strcpy_s(deviceList[count].version, sizeof(deviceList[count].version), deviceInfo->version) != EOK ||
1180             strcpy_s(deviceList[count].deviceName, sizeof(deviceList[count].deviceName),
1181                      deviceInfo->deviceName) != EOK ||
1182             strcpy_s(deviceList[count].deviceId, sizeof(deviceList[count].deviceId), deviceInfo->deviceId) != EOK) {
1183             DFINDER_LOGE(TAG, "string copy failure when getting device list");
1184             break;
1185         }
1186         deviceList[count].capabilityBitmapNum = deviceInfo->capabilityBitmapNum;
1187         if (deviceInfo->capabilityBitmapNum) {
1188             if (memcpy_s(deviceList[count].capabilityBitmap, sizeof(deviceList[count].capabilityBitmap),
1189                 deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
1190                 break;
1191             }
1192         }
1193 
1194         deviceList[count].discoveryType = deviceInfo->discoveryType;
1195         int8_t result = SetReservedInfoFromDeviceInfo(deviceList, count, deviceInfo);
1196         if (result == NSTACKX_EAGAIN) {
1197             DFINDER_LOGE(TAG, "SetReservedInfoFromDeviceInfo fails, sprintf_s or strcpy_s fails");
1198             break;
1199         } else if (result == NSTACKX_EINVAL || result == NSTACKX_EFAILED) {
1200             DFINDER_LOGE(TAG, "SetReservedInfoFromDeviceInfo fails");
1201             break;
1202         }
1203         if (strcpy_s(deviceList[count].networkName, sizeof(deviceList[count].networkName),
1204             deviceInfo->networkName) != EOK) {
1205             DFINDER_LOGE(TAG, "copy networkName failed");
1206             break;
1207         }
1208         deviceList[count].deviceType = deviceInfo->deviceType;
1209         deviceList[count].mode = deviceInfo->mode;
1210         deviceList[count].update = deviceInfo->update;
1211         deviceList[count].businessType = deviceInfo->businessType;
1212         deviceInfo->update = NSTACKX_FALSE;
1213         ++count;
1214     }
1215 
1216     *deviceCountPtr = count;
1217 }
1218 
1219 void GetDeviceListWrapper(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr, bool doFilter)
1220 {
1221     GetDeviceList(g_deviceList, deviceList, deviceCountPtr, doFilter);
1222 }
1223 
1224 DeviceInfo *GetDeviceInfoById(const char *deviceId, const void *db)
1225 {
1226     DeviceInfo dev;
1227     (void)memset_s(&dev, sizeof(dev), 0, sizeof(dev));
1228     if (strcpy_s(dev.deviceId, sizeof(dev.deviceId), deviceId) != EOK) {
1229         return NULL;
1230     }
1231     return DatabaseSearchRecord(db, &dev);
1232 }
1233 
1234 static uint8_t IsSameDevice(void *recptr, void *myptr)
1235 {
1236     DeviceInfo *rec = recptr;
1237     DeviceInfo *my  = myptr;
1238 
1239     if (recptr == NULL || myptr == NULL) {
1240         DFINDER_LOGE(TAG, "NULL input, can't compare");
1241         return NSTACKX_FALSE;
1242     }
1243 
1244     if (strcmp(rec->deviceId, my->deviceId) == 0) {
1245         return NSTACKX_TRUE;
1246     }
1247     return NSTACKX_FALSE;
1248 }
1249 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
1250 
1251 #ifndef DFINDER_SAVE_DEVICE_LIST
1252 static int32_t GetNotifyDeviceInfo(NSTACKX_DeviceInfo *notifyDevice, const DeviceInfo *deviceInfo)
1253 {
1254     if ((strcpy_s(notifyDevice->deviceId, sizeof(notifyDevice->deviceId), deviceInfo->deviceId) != EOK) ||
1255         (strcpy_s(notifyDevice->deviceName, sizeof(notifyDevice->deviceName), deviceInfo->deviceName) != EOK) ||
1256         (strcpy_s(notifyDevice->version, sizeof(notifyDevice->version), deviceInfo->version) != EOK)) {
1257         DFINDER_LOGE(TAG, "strcpy_s fails");
1258         return NSTACKX_EFAILED;
1259     }
1260     notifyDevice->capabilityBitmapNum = deviceInfo->capabilityBitmapNum;
1261     if (deviceInfo->capabilityBitmapNum) {
1262         if (memcpy_s(notifyDevice->capabilityBitmap, sizeof(notifyDevice->capabilityBitmap),
1263             deviceInfo->capabilityBitmap, deviceInfo->capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
1264             DFINDER_LOGE(TAG, "memcpy_s fails");
1265             return NSTACKX_EFAILED;
1266         }
1267     }
1268 
1269     int8_t result = SetReservedInfoFromDeviceInfo(notifyDevice, 0, deviceInfo);
1270     if (result != NSTACKX_EOK) {
1271         DFINDER_LOGE(TAG, "SetReservedInfoFromDeviceInfo fails: %hhd", result);
1272         return result;
1273     }
1274     notifyDevice->discoveryType = deviceInfo->discoveryType;
1275     notifyDevice->deviceType = deviceInfo->deviceType;
1276     notifyDevice->mode = deviceInfo->mode;
1277     notifyDevice->businessType = deviceInfo->businessType;
1278 
1279     return NSTACKX_EOK;
1280 }
1281 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
1282 
1283 #ifdef DFINDER_SUPPORT_MULTI_NIF
1284 static char *GetLocalNifName(void)
1285 {
1286     struct in_addr ipAddr;
1287     for (uint32_t i = 0; i < NSTACKX_MAX_LISTENED_NIF_NUM; ++i) {
1288         if (inet_pton(AF_INET, g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkIpAddr, &ipAddr) == 1 &&
1289             (ipAddr.s_addr != 0)) {
1290             return g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkName;
1291         }
1292     }
1293     return NULL;
1294 }
1295 
1296 char *GetLocalNifNameWithIdx(uint32_t idx)
1297 {
1298     struct in_addr ipAddr;
1299     if (inet_pton(AF_INET, g_localDeviceInfo.localIfInfoAll[idx].localIfInfo.networkIpAddr, &ipAddr) == 1 &&
1300         (ipAddr.s_addr != 0)) {
1301         return g_localDeviceInfo.localIfInfoAll[idx].localIfInfo.networkName;
1302     }
1303     return NULL;
1304 }
1305 
1306 static char *GetLocalNifIpWithIdx(struct in_addr *ip, uint32_t idx)
1307 {
1308     if (inet_pton(AF_INET, g_localDeviceInfo.localIfInfoAll[idx].localIfInfo.networkIpAddr, ip) == 1 &&
1309         (ip->s_addr != 0)) {
1310         return g_localDeviceInfo.localIfInfoAll[idx].localIfInfo.networkIpAddr;
1311     }
1312     return NULL;
1313 }
1314 #else
1315 static const NetworkInterfaceInfo *GetLocalInterface(void)
1316 {
1317     /* Ethernet have higher priority */
1318     if (g_interfaceList[NSTACKX_ETH_INDEX].ip.s_addr) {
1319         return &g_interfaceList[NSTACKX_ETH_INDEX];
1320     }
1321 
1322     if (g_interfaceList[NSTACKX_WLAN_INDEX].ip.s_addr) {
1323         return &g_interfaceList[NSTACKX_WLAN_INDEX];
1324     }
1325 
1326 #ifndef DFINDER_USE_MINI_NSTACKX
1327     if (g_interfaceList[NSTACKX_P2P_INDEX].ip.s_addr) {
1328         return &g_interfaceList[NSTACKX_P2P_INDEX];
1329     }
1330 
1331     if (g_interfaceList[NSTACKX_USB_INDEX].ip.s_addr) {
1332         return &g_interfaceList[NSTACKX_USB_INDEX];
1333     }
1334 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
1335 
1336     return NULL;
1337 }
1338 
1339 void GetLocalIp(struct in_addr *ip)
1340 {
1341     const NetworkInterfaceInfo *ifInfo = GetLocalInterface();
1342     if (ifInfo != NULL) {
1343         (void)memcpy_s(ip, sizeof(struct in_addr),
1344                        &ifInfo->ip, sizeof(struct in_addr));
1345     } else {
1346         (void)memset_s(ip, sizeof(struct in_addr), 0, sizeof(struct in_addr));
1347     }
1348 }
1349 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
1350 
1351 /* Return NSTACKX_TRUE if ifName prefix is the same, else return false */
1352 static uint8_t NetworkInterfaceNamePrefixCmp(const char *ifName, const char *prefix)
1353 {
1354     if (strlen(ifName) < strlen(prefix)) {
1355         return NSTACKX_FALSE;
1356     }
1357 
1358     if (memcmp(ifName, prefix, strlen(prefix)) == 0) {
1359         return NSTACKX_TRUE;
1360     } else {
1361         return NSTACKX_FALSE;
1362     }
1363 }
1364 
1365 #ifdef DFINDER_SUPPORT_MULTI_NIF
1366 int32_t UpdateLocalNetworkInterface(void)
1367 {
1368     uint32_t i;
1369     struct in_addr ipAddr;
1370     uint8_t upState = NSTACKX_FALSE;
1371 
1372     for (i = 0; i < g_localDeviceInfo.ifNums; ++i) {
1373         if (g_localDeviceInfo.ifState[i] == IF_STATE_INIT) {
1374             continue;
1375         }
1376         if (g_localDeviceInfo.ifState[i] == IF_STATE_REMAIN_UP) {
1377             upState = NSTACKX_TRUE;
1378         }
1379         g_localDeviceInfo.ifState[i] = IF_STATE_INIT;
1380         (void)inet_pton(AF_INET, g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkIpAddr, &ipAddr);
1381         if (ipAddr.s_addr == 0) {
1382             DFINDER_LOGI(TAG, "trying to bring down interface %s",
1383                 g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkName);
1384             CoapServerDestroyWithIdx(i);
1385         } else {
1386             DFINDER_LOGI(TAG, "trying to bring up interface %s",
1387                 g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkName);
1388             TimerSetTimeout(g_offlineDeferredTimer, 0, NSTACKX_FALSE);
1389             // init the i-th coap server correspond to the i-th nif
1390             CoapServerInitWithIdx(&ipAddr, i, g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkName);
1391             upState = NSTACKX_TRUE;
1392         }
1393     }
1394     if (!upState) {
1395         DFINDER_LOGD(TAG, "all interfaces are down");
1396         TimerSetTimeout(g_offlineDeferredTimer, NSTACKX_OFFLINE_DEFERRED_DURATION, NSTACKX_FALSE);
1397     }
1398     return NSTACKX_EOK;
1399 }
1400 #else
1401 int32_t UpdateLocalNetworkInterface(const NetworkInterfaceInfo *interfaceInfo)
1402 {
1403     uint32_t i;
1404     struct in_addr preIp, newIp;
1405 
1406     if (interfaceInfo == NULL) {
1407         return NSTACKX_EINVAL;
1408     }
1409 
1410     GetLocalIp(&preIp);
1411     for (i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
1412         if (NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[i].name) &&
1413             (i == NSTACKX_ETH_INDEX || i == NSTACKX_WLAN_INDEX)) {
1414             (void)memcpy_s(&g_interfaceList[i].ip, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr));
1415             break;
1416         }
1417     }
1418 
1419     if (i == NSTACKX_MAX_INTERFACE_NUM) {
1420         return NSTACKX_EINVAL;
1421     }
1422 
1423     GetLocalIp(&newIp);
1424     if (newIp.s_addr == preIp.s_addr) {
1425         DFINDER_LOGI(TAG, "ip not changed");
1426         return NSTACKX_EOK;
1427     }
1428 
1429     /* Cleanup device db when Wifi AP disconnected. */
1430     if (interfaceInfo->ip.s_addr == 0) {
1431         /*
1432          * We don't cleanup DB and transport immediately.
1433          * Instead, defer the event for a while in case WiFi connected again.
1434          */
1435         DFINDER_LOGE(TAG, "g_networkType is %s and interfaceInfo is %s", g_networkType,  interfaceInfo->name);
1436         if (strcmp(g_networkType, interfaceInfo->name) != 0 && strcmp(g_networkType, "") != 0) {
1437             DFINDER_LOGE(TAG, "into ignore");
1438             return NSTACKX_EOK;
1439         }
1440         TimerSetTimeout(g_offlineDeferredTimer, NSTACKX_OFFLINE_DEFERRED_DURATION, NSTACKX_FALSE);
1441     } else {
1442         TimerSetTimeout(g_offlineDeferredTimer, 0, NSTACKX_FALSE);
1443         int32_t ret = memcpy_s(g_networkType, sizeof(g_networkType), interfaceInfo->name, sizeof(interfaceInfo->name));
1444         if (ret != EOK) {
1445             DFINDER_LOGE(TAG, "memcpy_s error");
1446             return NSTACKX_EFAILED;
1447         }
1448         struct in_addr ip;
1449         (void)memcpy_s(&ip, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr));
1450         CoapServerInit(&ip);
1451     }
1452 
1453     return NSTACKX_EOK;
1454 }
1455 #endif  /* END OF DFINDER_SUPPORT_MULTI_NIF */
1456 
1457 #if !defined(DFINDER_SUPPORT_MULTI_NIF) && !defined(DFINDER_USE_MINI_NSTACKX)
1458 void SetP2pIp(const struct in_addr *ip)
1459 {
1460     if (ip == NULL) {
1461         return;
1462     }
1463     if (memcpy_s(&g_p2pIp, sizeof(struct in_addr), ip, sizeof(struct in_addr)) != EOK) {
1464         DFINDER_LOGE(TAG, "memcpy_s failed");
1465     }
1466 }
1467 
1468 static void TryToInitP2pCoapServer(struct in_addr ip)
1469 {
1470     /* ignore p2p service when new ip is 0. */
1471     if (ip.s_addr == 0) {
1472         DFINDER_LOGE(TAG, "p2p newIp is 0");
1473         return;
1474     }
1475     StopP2pServerInitRetryTimer();
1476     if (CoapP2pServerInit(&ip) != NSTACKX_EOK) { /* If init fail, start retry */
1477         DFINDER_LOGE(TAG, "start p2p init delayed");
1478         if (g_p2pServerInitDeferredTimer == NULL) {
1479             return;
1480         }
1481         /* if CoapP2pServerInit failed, update the g_p2pIp */
1482         SetP2pIp(&ip);
1483         TimerSetTimeout(g_p2pServerInitDeferredTimer, g_serverInitRetryBackoffList[0], NSTACKX_FALSE);
1484         g_p2pRetryCount++;
1485         return;
1486     }
1487     DFINDER_LOGD(TAG, "start p2p init success");
1488 }
1489 
1490 int32_t UpdateLocalNetworkInterfaceP2pMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType)
1491 {
1492     struct in_addr newIp;
1493 
1494     if (interfaceInfo == NULL) {
1495         return NSTACKX_EINVAL;
1496     }
1497 
1498 #ifdef SUPPORT_SMARTGENIUS
1499     if (nlmsgType == RTM_DELADDR) {
1500         DFINDER_LOGD(TAG, "p2p delete address, call CoapP2pServerDestroy()");
1501         CoapP2pServerDestroy();
1502         StopP2pServerInitRetryTimer();
1503         (void)memset_s(&g_p2pIp, sizeof(g_p2pIp), 0, sizeof(g_p2pIp));
1504         return NSTACKX_EOK;
1505     }
1506 #else
1507     (void)nlmsgType;
1508 #endif /* SUPPORT_SMARTGENIUS */
1509 
1510     /* p2p new ip does not write to g_interfaceList */
1511     if (NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[NSTACKX_P2P_INDEX].name) ||
1512         NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[NSTACKX_P2P_INDEX].alias)) {
1513         if (memcpy_s(&newIp, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr)) != EOK) {
1514             DFINDER_LOGE(TAG, "newIp memcpy_s failed");
1515             return NSTACKX_EFAILED;
1516         }
1517     } else {
1518         DFINDER_LOGI(TAG, "NetworkInterfaceNamePrefixCmp p2p fail");
1519         return NSTACKX_EINVAL;
1520     }
1521     TryToInitP2pCoapServer(newIp);
1522     return NSTACKX_EOK;
1523 }
1524 
1525 void SetUsbIp(const struct in_addr *ip)
1526 {
1527     if (ip == NULL) {
1528         return;
1529     }
1530     if (memcpy_s(&g_usbIp, sizeof(struct in_addr), ip, sizeof(struct in_addr)) != EOK) {
1531         DFINDER_LOGE(TAG, "memcpy_s failed");
1532     }
1533 }
1534 
1535 static void TryToInitUsbCoapServer(struct in_addr ip)
1536 {
1537     /* ignore usb service when new ip is 0. */
1538     if (ip.s_addr == 0) {
1539         DFINDER_LOGE(TAG, "usb newIp is 0");
1540         return;
1541     }
1542 
1543     StopUsbServerInitRetryTimer();
1544     if (CoapUsbServerInit(&ip) != NSTACKX_EOK) {
1545         DFINDER_LOGE(TAG, "start usb init delayed");
1546         if (g_usbServerInitDeferredTimer == NULL) {
1547             return;
1548         }
1549 
1550         /* if CoapUsbServerInit failed, update the g_p2pIp */
1551         SetUsbIp(&ip);
1552 
1553         TimerSetTimeout(g_usbServerInitDeferredTimer, g_serverInitRetryBackoffList[0], NSTACKX_FALSE);
1554         g_usbRetryCount++;
1555         return;
1556     }
1557     DFINDER_LOGI(TAG, "start usb init success");
1558 }
1559 
1560 int32_t UpdateLocalNetworkInterfaceUsbMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType)
1561 {
1562     struct in_addr newIp;
1563 
1564     if (interfaceInfo == NULL) {
1565         return NSTACKX_EINVAL;
1566     }
1567 
1568 #ifdef SUPPORT_SMARTGENIUS
1569     if (nlmsgType == RTM_DELADDR) {
1570         DFINDER_LOGD(TAG, "usb delete address, call CoapUsbServerDestroy()");
1571         CoapUsbServerDestroy();
1572         StopUsbServerInitRetryTimer();
1573         (void)memset_s(&g_usbIp, sizeof(g_usbIp), 0, sizeof(g_usbIp));
1574         return NSTACKX_EOK;
1575     }
1576 #else
1577     (void)nlmsgType;
1578 #endif /* SUPPORT_SMARTGENIUS */
1579 
1580     /* usb new ip does not write to g_interfaceList */
1581     if (NetworkInterfaceNamePrefixCmp(interfaceInfo->name, g_interfaceList[NSTACKX_USB_INDEX].name)) {
1582         if (memcpy_s(&newIp, sizeof(struct in_addr), &interfaceInfo->ip, sizeof(struct in_addr)) != EOK) {
1583             DFINDER_LOGE(TAG, "newIp memcpy_s failed");
1584             return NSTACKX_EFAILED;
1585         }
1586     } else {
1587         return NSTACKX_EINVAL;
1588     }
1589     TryToInitUsbCoapServer(newIp);
1590     return NSTACKX_EOK;
1591 }
1592 #endif /* END OF (!DFINDER_SUPPORT_MULTI_NIF) && (!DFINDER_USE_MINI_NSTACKX) */
1593 
1594 void SetModeInfo(uint8_t mode)
1595 {
1596     g_localDeviceInfo.mode = mode;
1597 }
1598 
1599 uint8_t GetModeInfo(void)
1600 {
1601     return g_localDeviceInfo.mode;
1602 }
1603 
1604 int32_t GetNetworkName(char *name, int32_t len)
1605 {
1606 #ifdef NSTACKX_WITH_LITEOS_M
1607     if (name == NULL) {
1608         LOGE(TAG, "input invalid para!");
1609         return NSTACKX_EFAILED;
1610     }
1611     if (strcpy_s(name, len, g_localDeviceInfo.networkName) != EOK) {
1612         LOGE(TAG, "get network name copy error!");
1613         return NSTACKX_EFAILED;
1614     }
1615 #else
1616     (void)name;
1617     (void)len;
1618 #endif
1619     return NSTACKX_EOK;
1620 }
1621 
1622 void SetDeviceHash(uint64_t deviceHash)
1623 {
1624     (void)memset_s(g_localDeviceInfo.deviceHash, sizeof(g_localDeviceInfo.deviceHash),
1625         0, sizeof(g_localDeviceInfo.deviceHash));
1626     if (sprintf_s(g_localDeviceInfo.deviceHash, DEVICE_HASH_LEN,
1627         "%ju", deviceHash) == -1) {
1628         DFINDER_LOGE(TAG, "set device hash error");
1629     }
1630 }
1631 
1632 #ifdef DFINDER_SUPPORT_MULTI_NIF
1633 static void UpdateLocalMultiNifState(const NSTACKX_LocalDeviceInfo *devInfo)
1634 {
1635     struct in_addr ipAddr;
1636     uint32_t i;
1637     for (i = 0; i < NSTACKX_MAX_LISTENED_NIF_NUM; ++i) {
1638         CoapServerDestroyWithIdx(i);
1639         g_localDeviceInfo.ifState[i] = IF_STATE_INIT;
1640     }
1641     for (i = 0; i < devInfo->ifNums && i < NSTACKX_MAX_LISTENED_NIF_NUM; ++i) {
1642         (void)inet_pton(AF_INET, devInfo->localIfInfo[i].networkIpAddr, &ipAddr);
1643         if (strcpy_s(g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkName,
1644             sizeof(g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkName),
1645             devInfo->localIfInfo[i].networkName) != EOK) {
1646             DFINDER_LOGE(TAG, "Failed to copy network name for index %u", i);
1647             return;
1648         }
1649         if (strcpy_s(g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkIpAddr,
1650             sizeof(g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkIpAddr),
1651             devInfo->localIfInfo[i].networkIpAddr) != EOK) {
1652             DFINDER_LOGE(TAG, "Failed to copy network address for index %u", i);
1653             return;
1654         }
1655         g_localDeviceInfo.ifState[i] = IF_STATE_UPDATED;
1656     }
1657     g_localDeviceInfo.ifNums = devInfo->ifNums;
1658 }
1659 #endif
1660 
1661 int32_t ConfigureLocalDeviceInfo(const NSTACKX_LocalDeviceInfo *devInfo)
1662 {
1663     char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
1664     struct in_addr ipAddr;
1665     NetworkInterfaceInfo interfaceInfo;
1666 
1667     (void)memset_s(&interfaceInfo, sizeof(interfaceInfo), 0, sizeof(interfaceInfo));
1668     /* Backup device id */
1669     (void)memcpy_s(deviceId, sizeof(deviceId), g_localDeviceInfo.deviceId, sizeof(deviceId));
1670     if (strcpy_s(g_localDeviceInfo.deviceId, sizeof(g_localDeviceInfo.deviceId), devInfo->deviceId) != EOK) {
1671         DFINDER_LOGE(TAG, "Invalid device id!");
1672         /* Restore device id if some error happens */
1673         if (memcpy_s(g_localDeviceInfo.deviceId, sizeof(g_localDeviceInfo.deviceId),
1674             deviceId, sizeof(deviceId)) != EOK) {
1675             DFINDER_LOGE(TAG, "deviceId copy error and can't restore device id!");
1676         }
1677         return NSTACKX_EINVAL;
1678     }
1679 #ifdef DFINDER_SUPPORT_MULTI_NIF
1680     UpdateLocalMultiNifState(devInfo);
1681     UpdateLocalNetworkInterface();
1682     (void)ipAddr;
1683 #else
1684     if ((strnlen(devInfo->networkIpAddr, NSTACKX_MAX_IP_STRING_LEN) < NSTACKX_MAX_IP_STRING_LEN) &&
1685         (inet_pton(AF_INET, devInfo->networkIpAddr, &ipAddr) == 1) &&
1686 #ifdef NSTACKX_WITH_LITEOS_M
1687         ((strcpy_s(interfaceInfo.name, sizeof(interfaceInfo.name), devInfo->networkName) == EOK) &&
1688         (strcpy_s(g_localDeviceInfo.networkName, sizeof(g_localDeviceInfo.networkName),
1689             devInfo->networkName) == EOK))) {
1690 #else
1691         (strcpy_s(interfaceInfo.name, sizeof(interfaceInfo.name), devInfo->networkName) == EOK)) {
1692 #endif /* END OF NSTACKX_WITH_LITEOS_M */
1693         interfaceInfo.ip = ipAddr;
1694         UpdateLocalNetworkInterface(&interfaceInfo);
1695     } else {
1696         DFINDER_LOGD(TAG, "Invalid if name or ip address. Ignore");
1697     }
1698 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
1699     if (strnlen(devInfo->name, NSTACKX_MAX_DEVICE_NAME_LEN) == 0 || (strncpy_s(g_localDeviceInfo.deviceName,
1700         sizeof(g_localDeviceInfo.deviceName), devInfo->name, NSTACKX_MAX_DEVICE_NAME_LEN - 1) != EOK)) {
1701         DFINDER_LOGW(TAG, "Invalid device name. Will use default name");
1702         (void)strcpy_s(g_localDeviceInfo.deviceName, sizeof(g_localDeviceInfo.deviceName), NSTACKX_DEFAULT_DEVICE_NAME);
1703     }
1704 
1705     if (strcpy_s(g_localDeviceInfo.version, sizeof(g_localDeviceInfo.version), devInfo->version) != EOK) {
1706         DFINDER_LOGE(TAG, "Invalid version!");
1707         return NSTACKX_EINVAL;
1708     }
1709 
1710     g_localDeviceInfo.deviceType = devInfo->deviceType;
1711     g_localDeviceInfo.businessType = devInfo->businessType;
1712     return NSTACKX_EOK;
1713 }
1714 
1715 void ConfigureLocalDeviceName(const char *localDeviceName)
1716 {
1717     char backupDevName[NSTACKX_MAX_DEVICE_NAME_LEN] = {0};
1718     if (memcpy_s(backupDevName, sizeof(backupDevName), g_localDeviceInfo.deviceName,
1719         sizeof(g_localDeviceInfo.deviceName)) != EOK) {
1720         DFINDER_LOGE(TAG, "backup local device name failed!");
1721         return;
1722     }
1723     if (strncpy_s(g_localDeviceInfo.deviceName, NSTACKX_MAX_DEVICE_NAME_LEN,
1724         localDeviceName, NSTACKX_MAX_DEVICE_NAME_LEN - 1) != EOK) {
1725         DFINDER_LOGW(TAG, "copy local device failed, will use current name");
1726         if (strcpy_s(g_localDeviceInfo.deviceName, NSTACKX_MAX_DEVICE_NAME_LEN, backupDevName) != EOK) {
1727             DFINDER_LOGE(TAG, "config device name failed and cannot restore!");
1728         }
1729     }
1730 }
1731 
1732 static CoapBroadcastType CheckAdvertiseInfo(const uint32_t advertiseCount, const uint32_t advertiseDuration)
1733 {
1734     if ((advertiseCount == 0) && (advertiseDuration == 0)) {
1735         return COAP_BROADCAST_TYPE_DEFAULT;
1736     }
1737     return COAP_BROADCAST_TYPE_USER;
1738 }
1739 
1740 void ConfigureDiscoverySettings(const NSTACKX_DiscoverySettings *discoverySettings)
1741 {
1742     if (discoverySettings->businessData == NULL) {
1743         DFINDER_LOGE(TAG, "businessData null");
1744         return;
1745     }
1746 
1747     SetModeInfo(discoverySettings->discoveryMode);
1748     if (strncpy_s(g_localDeviceInfo.businessData.businessDataBroadcast, NSTACKX_MAX_BUSINESS_DATA_LEN,
1749         discoverySettings->businessData, discoverySettings->length) != EOK) {
1750         DFINDER_LOGE(TAG, "businessData copy error");
1751         return;
1752     }
1753     uint32_t advertiseCount = discoverySettings->advertiseCount;
1754     uint32_t advertiseDuration = discoverySettings->advertiseDuration;
1755     CoapBroadcastType ret = CheckAdvertiseInfo(advertiseCount, advertiseDuration);
1756     if (ret == COAP_BROADCAST_TYPE_DEFAULT) {
1757         SetCoapDiscoverType(COAP_BROADCAST_TYPE_DEFAULT);
1758     } else if (ret == COAP_BROADCAST_TYPE_USER) {
1759         SetCoapDiscoverType(COAP_BROADCAST_TYPE_USER);
1760         SetCoapUserDiscoverInfo(advertiseCount, advertiseDuration);
1761     }
1762     g_localDeviceInfo.businessType = discoverySettings->businessType;
1763 
1764     return;
1765 }
1766 
1767 const DeviceInfo *GetLocalDeviceInfoPtr(void)
1768 {
1769     return &g_localDeviceInfo;
1770 }
1771 
1772 #ifdef DFINDER_SUPPORT_MULTI_NIF
1773 uint8_t IsApConnected(void)
1774 {
1775     struct in_addr ipAddr;
1776     for (uint32_t i = 0; i < NSTACKX_MAX_LISTENED_NIF_NUM; ++i) {
1777         if (inet_pton(AF_INET, g_localDeviceInfo.localIfInfoAll[i].localIfInfo.networkIpAddr, &ipAddr) == 1 &&
1778             (ipAddr.s_addr != 0)) {
1779             return NSTACKX_TRUE;
1780         }
1781     }
1782     DFINDER_LOGD(TAG, "all ap are not connected");
1783     return NSTACKX_FALSE;
1784 }
1785 
1786 uint8_t IsApConnectedWithIdx(uint32_t idx)
1787 {
1788     struct in_addr ipAddr;
1789     if (inet_pton(AF_INET, g_localDeviceInfo.localIfInfoAll[idx].localIfInfo.networkIpAddr, &ipAddr) == 1 &&
1790         (ipAddr.s_addr != 0)) {
1791         DFINDER_LOGE(TAG, "inet_pton success");
1792         return NSTACKX_TRUE;
1793     }
1794     return NSTACKX_EFAILED;
1795 }
1796 #else
1797 uint8_t IsWifiApConnected(void)
1798 {
1799     struct in_addr ip;
1800     GetLocalIp(&ip);
1801     if (ip.s_addr != 0) {
1802         return NSTACKX_TRUE;
1803     } else {
1804         return NSTACKX_FALSE;
1805     }
1806 }
1807 
1808 int32_t GetLocalIpString(char *ipString, size_t length)
1809 {
1810     struct in_addr ip;
1811     GetLocalIp(&ip);
1812     if (ip.s_addr == 0) {
1813         return NSTACKX_EFAILED;
1814     }
1815     if (inet_ntop(AF_INET, &ip, ipString, length) == NULL) {
1816         return NSTACKX_EFAILED;
1817     }
1818     return NSTACKX_EOK;
1819 }
1820 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
1821 
1822 #ifdef DFINDER_SUPPORT_MULTI_NIF
1823 int32_t GetLocalIpStringWithIdx(char *ipString, size_t length, uint32_t idx)
1824 {
1825     struct in_addr ip;
1826     GetLocalNifIpWithIdx(&ip, idx);
1827     if (ip.s_addr == 0) {
1828         DFINDER_LOGE(TAG, "ip.s_addr is 0");
1829         return NSTACKX_EFAILED;
1830     }
1831     if (inet_ntop(AF_INET, &ip, ipString, length) == NULL) {
1832         DFINDER_LOGE(TAG, "inet_pton failed");
1833         return NSTACKX_EFAILED;
1834     }
1835     return NSTACKX_EOK;
1836 }
1837 #endif
1838 
1839 #if !defined(DFINDER_SUPPORT_MULTI_NIF) && !defined(DFINDER_USE_MINI_NSTACKX)
1840 int32_t GetP2pIpString(char *ipString, size_t length)
1841 {
1842     if (ipString == NULL || length == 0) {
1843         return NSTACKX_EFAILED;
1844     }
1845     if (inet_ntop(AF_INET, &g_p2pIp, ipString, length) == NULL) {
1846         return NSTACKX_EFAILED;
1847     }
1848     return NSTACKX_EOK;
1849 }
1850 
1851 int32_t GetUsbIpString(char *ipString, size_t length)
1852 {
1853     if (ipString == NULL || length == 0) {
1854         return NSTACKX_EFAILED;
1855     }
1856     if (inet_ntop(AF_INET, &g_usbIp, ipString, length) == NULL) {
1857         return NSTACKX_EFAILED;
1858     }
1859     return NSTACKX_EOK;
1860 }
1861 #endif /* END OF (!DFINDER_SUPPORT_MULTI_NIF) && (!DFINDER_USE_MINI_NSTACKX) */
1862 
1863 #ifdef DFINDER_SUPPORT_MULTI_NIF
1864 int32_t GetLocalInterfaceName(char *ifName, size_t ifNameLength)
1865 {
1866     const char *ifInfo = GetLocalNifName();
1867     if (ifInfo == NULL) {
1868         return NSTACKX_EFAILED;
1869     }
1870     if (strcpy_s(ifName, ifNameLength, ifInfo) != EOK) {
1871         return NSTACKX_EFAILED;
1872     }
1873     return NSTACKX_EOK;
1874 }
1875 
1876 int32_t GetLocalInterfaceNameWithIdx(char *ifName, size_t ifNameLen, uint32_t idx)
1877 {
1878     const char *ifInfo = GetLocalNifNameWithIdx(idx);
1879     if (ifInfo == NULL) {
1880         DFINDER_LOGE(TAG, "get local nif name with idx-%u failed, it is NULL", idx);
1881         return NSTACKX_EFAILED;
1882     }
1883     if (strcpy_s(ifName, ifNameLen, ifInfo) != EOK) {
1884         DFINDER_LOGE(TAG, "strcpy_s copy ifInfo failed");
1885         return NSTACKX_EFAILED;
1886     }
1887     return NSTACKX_EOK;
1888 }
1889 #else
1890 int32_t GetLocalInterfaceName(char *ifName, size_t ifNameLength)
1891 {
1892     const NetworkInterfaceInfo *ifInfo = GetLocalInterface();
1893     if (ifInfo == NULL || ifName == NULL) {
1894         return NSTACKX_EFAILED;
1895     }
1896 
1897     if (strcpy_s(ifName, ifNameLength, ifInfo->name) != EOK) {
1898         return NSTACKX_EFAILED;
1899     }
1900 
1901     return NSTACKX_EOK;
1902 }
1903 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
1904 
1905 #ifndef DFINDER_USE_MINI_NSTACKX
1906 uint8_t FilterNetworkInterface(const char *ifName)
1907 {
1908     uint32_t i;
1909     if (ifName == NULL) {
1910         return NSTACKX_FALSE;
1911     }
1912 
1913     for (i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
1914         if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[i].name) ||
1915             NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[i].alias)) {
1916             return NSTACKX_TRUE;
1917         }
1918     }
1919     return NSTACKX_FALSE;
1920 }
1921 
1922 #ifdef _WIN32
1923 uint8_t IsWlanIpAddr(const struct in_addr *ifAddr)
1924 {
1925     if (ifAddr == NULL) {
1926         return NSTACKX_FALSE;
1927     }
1928     if (ifAddr->s_addr == g_interfaceList[NSTACKX_WLAN_INDEX].ip.s_addr) {
1929         DFINDER_LOGE(TAG, "IsWlanIpAddr success");
1930         return NSTACKX_TRUE;
1931     }
1932 
1933     return NSTACKX_FALSE;
1934 }
1935 
1936 uint8_t IsEthIpAddr(const struct in_addr *ifAddr)
1937 {
1938     if (ifAddr == NULL) {
1939         return NSTACKX_FALSE;
1940     }
1941 
1942     if (ifAddr->s_addr == g_interfaceList[NSTACKX_ETH_INDEX].ip.s_addr) {
1943         DFINDER_LOGE(TAG, "IsEthIpAddr success");
1944         return NSTACKX_TRUE;
1945     }
1946 
1947     return NSTACKX_FALSE;
1948 }
1949 
1950 uint8_t IsP2pIpAddr(const struct in_addr *ifAddr)
1951 {
1952     if (ifAddr == NULL) {
1953         return NSTACKX_FALSE;
1954     }
1955 
1956     if (ifAddr->s_addr == g_interfaceList[NSTACKX_P2P_INDEX].ip.s_addr) {
1957         DFINDER_LOGE(TAG, "IsP2pIpAddr success");
1958         return NSTACKX_TRUE;
1959     }
1960 
1961     return NSTACKX_FALSE;
1962 }
1963 
1964 uint8_t IsUsbIpAddr(const struct in_addr *ifAddr)
1965 {
1966     if (ifAddr == NULL) {
1967         return NSTACKX_FALSE;
1968     }
1969 
1970     if (ifAddr->s_addr == g_interfaceList[NSTACKX_USB_INDEX].ip.s_addr) {
1971         DFINDER_LOGE(TAG, "IsUsbIpAddr success");
1972         return NSTACKX_TRUE;
1973     }
1974 
1975     return NSTACKX_FALSE;
1976 }
1977 
1978 #else
1979 uint8_t IsWlanIpAddr(const char *ifName)
1980 {
1981     if (ifName == NULL) {
1982         return NSTACKX_FALSE;
1983     }
1984 
1985     if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_WLAN_INDEX].name)) {
1986         DFINDER_LOGE(TAG, "IsWlanIpAddr success");
1987         return NSTACKX_TRUE;
1988     }
1989 
1990     return NSTACKX_FALSE;
1991 }
1992 
1993 uint8_t IsEthIpAddr(const char *ifName)
1994 {
1995     if (ifName == NULL) {
1996         return NSTACKX_FALSE;
1997     }
1998 
1999     if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_ETH_INDEX].name)) {
2000         DFINDER_LOGE(TAG, "IsEthIpAddr success");
2001         return NSTACKX_TRUE;
2002     }
2003 
2004     return NSTACKX_FALSE;
2005 }
2006 
2007 uint8_t IsP2pIpAddr(const char *ifName)
2008 {
2009     if (ifName == NULL) {
2010         return NSTACKX_FALSE;
2011     }
2012 
2013     if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_P2P_INDEX].name) ||
2014         NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_P2P_INDEX].alias)) {
2015         DFINDER_LOGE(TAG, "IsP2pIpAddr success");
2016         return NSTACKX_TRUE;
2017     }
2018 
2019     return NSTACKX_FALSE;
2020 }
2021 
2022 uint8_t IsUsbIpAddr(const char *ifName)
2023 {
2024     if (ifName == NULL) {
2025         return NSTACKX_FALSE;
2026     }
2027 
2028     if (NetworkInterfaceNamePrefixCmp(ifName, g_interfaceList[NSTACKX_USB_INDEX].name)) {
2029         DFINDER_LOGE(TAG, "IsUsbIpAddr success");
2030         return NSTACKX_TRUE;
2031     }
2032 
2033     return NSTACKX_FALSE;
2034 }
2035 #endif
2036 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
2037 
2038 int32_t RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
2039 {
2040     (void)memset_s(g_localDeviceInfo.capabilityBitmap, sizeof(g_localDeviceInfo.capabilityBitmap),
2041         0, sizeof(g_localDeviceInfo.capabilityBitmap));
2042     if (capabilityBitmapNum) {
2043         if (memcpy_s(g_localDeviceInfo.capabilityBitmap, sizeof(g_localDeviceInfo.capabilityBitmap),
2044             capabilityBitmap, sizeof(uint32_t) * capabilityBitmapNum) != EOK) {
2045             DFINDER_LOGE(TAG, "capabilityBitmap copy error");
2046             return NSTACKX_EFAILED;
2047         }
2048     }
2049     g_localDeviceInfo.capabilityBitmapNum = capabilityBitmapNum;
2050     return NSTACKX_EOK;
2051 }
2052 
2053 int32_t SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
2054 {
2055     (void)memset_s(g_filterCapabilityBitmap, sizeof(g_filterCapabilityBitmap),
2056         0, sizeof(g_filterCapabilityBitmap));
2057     if (capabilityBitmapNum) {
2058         if (memcpy_s(g_filterCapabilityBitmap, sizeof(g_filterCapabilityBitmap),
2059             capabilityBitmap, sizeof(uint32_t) * capabilityBitmapNum) != EOK) {
2060             DFINDER_LOGE(TAG, "FilterCapabilityBitmap copy error");
2061             return NSTACKX_EFAILED;
2062         }
2063     }
2064     g_filterCapabilityBitmapNum = capabilityBitmapNum;
2065     return NSTACKX_EOK;
2066 }
2067 
2068 int32_t RegisterServiceData(const char *serviceData)
2069 {
2070     if (serviceData == NULL) {
2071         DFINDER_LOGE(TAG, "device db init failed");
2072         return NSTACKX_EINVAL;
2073     }
2074 
2075     if (strncpy_s(g_localDeviceInfo.serviceData, NSTACKX_MAX_SERVICE_DATA_LEN,
2076                   serviceData, strlen(serviceData)) != EOK) {
2077         DFINDER_LOGE(TAG, "serviceData copy error");
2078         return NSTACKX_EFAILED;
2079     }
2080     return NSTACKX_EOK;
2081 }
2082 
2083 #ifndef DFINDER_USE_MINI_NSTACKX
2084 int32_t RegisterExtendServiceData(const char *extendServiceData)
2085 {
2086     if (extendServiceData == NULL) {
2087         DFINDER_LOGE(TAG, "device db init failed");
2088         return NSTACKX_EINVAL;
2089     }
2090 
2091     if (strcpy_s(g_localDeviceInfo.extendServiceData, NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN, extendServiceData) != EOK) {
2092         DFINDER_LOGE(TAG, "extendServiceData copy error");
2093         return NSTACKX_EFAILED;
2094     }
2095     return NSTACKX_EOK;
2096 }
2097 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
2098 
2099 void DeviceModuleClean(void)
2100 {
2101     if (g_deviceInited == NSTACKX_FALSE) {
2102         return;
2103     }
2104 
2105     TimerDelete(g_offlineDeferredTimer);
2106     g_offlineDeferredTimer = NULL;
2107 
2108 #ifdef DFINDER_SAVE_DEVICE_LIST
2109     if (g_deviceList != NULL) {
2110         ClearDevices(g_deviceList);
2111         DFINDER_LOGW(TAG, "clear device list");
2112         DatabaseClean(g_deviceList);
2113         g_deviceList = NULL;
2114     }
2115     if (g_deviceListBackup != NULL) {
2116         ClearDevices(g_deviceListBackup);
2117         DFINDER_LOGW(TAG, "clear device list backup");
2118         DatabaseClean(g_deviceListBackup);
2119         g_deviceListBackup = NULL;
2120     }
2121 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
2122 
2123     g_deviceInited = NSTACKX_FALSE;
2124     return;
2125 }
2126 
2127 #ifndef DFINDER_SUPPORT_MULTI_NIF
2128 static void GlobalInterfaceListInit(void)
2129 {
2130     (void)memset_s(g_interfaceList, sizeof(g_interfaceList), 0, sizeof(g_interfaceList));
2131     (void)strcpy_s(g_interfaceList[NSTACKX_WLAN_INDEX].name,
2132         sizeof(g_interfaceList[NSTACKX_WLAN_INDEX].name), NSTACKX_WLAN_INTERFACE_NAME_PREFIX);
2133     (void)strcpy_s(g_interfaceList[NSTACKX_ETH_INDEX].name,
2134         sizeof(g_interfaceList[NSTACKX_ETH_INDEX].name), NSTACKX_ETH_INTERFACE_NAME_PREFIX);
2135     (void)strcpy_s(g_interfaceList[NSTACKX_P2P_INDEX].name,
2136         sizeof(g_interfaceList[NSTACKX_P2P_INDEX].name), NSTACKX_P2P_INTERFACE_NAME_PREFIX);
2137     (void)strcpy_s(g_interfaceList[NSTACKX_P2P_INDEX].alias,
2138         sizeof(g_interfaceList[NSTACKX_P2P_INDEX].alias), NSTACKX_P2P_WLAN_INTERFACE_NAME_PREFIX);
2139     (void)strcpy_s(g_interfaceList[NSTACKX_USB_INDEX].name,
2140         sizeof(g_interfaceList[NSTACKX_USB_INDEX].name), NSTACKX_USB_INTERFACE_NAME_PREFIX);
2141     g_deviceInited = NSTACKX_TRUE;
2142 }
2143 #endif
2144 
2145 static void SetMaxDeviceNum(uint32_t maxDeviceNum)
2146 {
2147 #ifdef DFINDER_SAVE_DEVICE_LIST
2148     if (maxDeviceNum < NSTACKX_MIN_DEVICE_NUM || maxDeviceNum > NSTACKX_MAX_DEVICE_NUM) {
2149         DFINDER_LOGE(TAG, "illegal device num passed in, set device num to default value");
2150         maxDeviceNum = NSTACKX_DEFAULT_DEVICE_NUM;
2151     }
2152 #else
2153     maxDeviceNum = NSTACKX_MAX_DEVICE_NUM;
2154 #endif
2155     g_maxDeviceNum = maxDeviceNum;
2156 }
2157 
2158 int32_t DeviceModuleInit(EpollDesc epollfd, uint32_t maxDeviceNum)
2159 {
2160     if (g_deviceInited) {
2161         return NSTACKX_EOK;
2162     }
2163     SetMaxDeviceNum(maxDeviceNum);
2164     (void)memset_s(&g_localDeviceInfo, sizeof(g_localDeviceInfo), 0, sizeof(g_localDeviceInfo));
2165 #ifndef DFINDER_SUPPORT_MULTI_NIF
2166     (void)memset_s(g_networkType, sizeof(g_networkType), 0, sizeof(g_networkType));
2167 #endif
2168 
2169 #ifdef DFINDER_SAVE_DEVICE_LIST
2170     int32_t ret = NSTACKX_EFAILED;
2171     g_deviceList = DatabaseInit(g_maxDeviceNum, sizeof(DeviceInfo), IsSameDevice);
2172     if (g_deviceList == NULL) {
2173         DFINDER_LOGE(TAG, "device db init failed");
2174         return NSTACKX_ENOMEM;
2175     }
2176     g_deviceListBackup = DatabaseInit(g_maxDeviceNum, sizeof(DeviceInfo), IsSameDevice);
2177     if (g_deviceListBackup == NULL) {
2178         DFINDER_LOGE(TAG, "device db backup init failed");
2179         ret = NSTACKX_ENOMEM;
2180         goto L_ERR_DEVICE_DB_BACKUP_LIST;
2181     }
2182 #endif
2183     g_offlineDeferredTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, LocalDeviceOffline, NULL);
2184     if (g_offlineDeferredTimer == NULL) {
2185         DFINDER_LOGE(TAG, "device offline deferred timer start failed");
2186 #ifdef DFINDER_SAVE_DEVICE_LIST
2187         goto L_ERR_DEFERRED_TIMER;
2188 #else
2189         return NSTACKX_EFAILED;
2190 #endif
2191     }
2192 #ifndef DFINDER_SUPPORT_MULTI_NIF
2193     GlobalInterfaceListInit();
2194 #endif
2195     return NSTACKX_EOK;
2196 
2197 #ifdef DFINDER_SAVE_DEVICE_LIST
2198 /* Call TimerDelete(g_offlineDeferredTimer) when add module. */
2199 L_ERR_DEFERRED_TIMER:
2200     DatabaseClean(g_deviceListBackup);
2201     g_deviceListBackup = NULL;
2202 L_ERR_DEVICE_DB_BACKUP_LIST:
2203     DatabaseClean(g_deviceList);
2204     g_deviceList = NULL;
2205     return ret;
2206 #endif
2207 }
2208 
2209 #ifdef DFINDER_SAVE_DEVICE_LIST
2210 static int32_t BackupDeviceDBEx(void)
2211 {
2212     void *db = g_deviceList;
2213     void *backupDB = g_deviceListBackup;
2214     int64_t idx = -1;
2215     DeviceInfo *deviceInfo = NULL;
2216 
2217     if (db == NULL || backupDB == NULL) {
2218         return NSTACKX_EFAILED;
2219     }
2220     uint8_t result = ClearDevices(backupDB);
2221     if (result == NSTACKX_FALSE) {
2222         DFINDER_LOGE(TAG, "clear backupDB error");
2223     }
2224 
2225     for (uint32_t i = 0; i < g_maxDeviceNum; i++) {
2226         deviceInfo = DatabaseGetNextRecord(db, &idx);
2227         if (deviceInfo == NULL) {
2228             break;
2229         }
2230 
2231         DeviceInfo *newDeviceInfo = DatabaseAllocRecord(backupDB);
2232         if (newDeviceInfo == NULL) {
2233             DFINDER_LOGE(TAG, "allocate device info failure");
2234             return NSTACKX_EFAILED;
2235         }
2236         if (memcpy_s(newDeviceInfo, sizeof(DeviceInfo), deviceInfo, sizeof(DeviceInfo)) != EOK) {
2237             DFINDER_LOGE(TAG, "memcpy failure");
2238             return NSTACKX_EFAILED;
2239         }
2240     }
2241     return NSTACKX_EOK;
2242 }
2243 
2244 int32_t BackupDeviceDB(void)
2245 {
2246     int32_t ret = BackupDeviceDBEx();
2247     if (ret != NSTACKX_EOK) {
2248         IncStatistics(STATS_BACKUP_DEVICE_DB_FAILED);
2249     }
2250     return ret;
2251 }
2252 
2253 void *GetDeviceDB(void)
2254 {
2255     return g_deviceList;
2256 }
2257 
2258 void *GetDeviceDBBackup(void)
2259 {
2260     return g_deviceListBackup;
2261 }
2262 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
2263 
2264 #ifndef DFINDER_SUPPORT_MULTI_NIF
2265 #ifndef DFINDER_USE_MINI_NSTACKX
2266 void UpdateAllNetworkInterfaceNameIfNeed(const NetworkInterfaceInfo *interfaceInfo)
2267 {
2268     if (interfaceInfo == NULL) {
2269         DFINDER_LOGE(TAG, "NetworkInterfaceInfo is Null");
2270         return;
2271     }
2272     for (int i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
2273         if (strlen(g_interfaceList[i].name) != 0 &&
2274             strncmp(interfaceInfo->name, g_interfaceList[i].name, strlen(g_interfaceList[i].name)) == 0) {
2275             return;
2276         }
2277     }
2278     for (int i = 0; i < NSTACKX_MAX_INTERFACE_NUM; i++) {
2279         for (int j = 0; j < INTERFACE_NAME_POSSIBLE; j++) {
2280             if (!(strlen(g_interfacePrefixList[i].name[j]) != 0 &&
2281                 strncmp(interfaceInfo->name, g_interfacePrefixList[i].name[j],
2282                         strlen(g_interfacePrefixList[i].name[j])) == 0)) {
2283                 continue;
2284             }
2285             if (strncpy_s(g_interfaceList[i].name, sizeof(g_interfaceList[i].name),
2286                 g_interfacePrefixList[i].name[j], strlen(g_interfacePrefixList[i].name[j])) != EOK) {
2287                 DFINDER_LOGE(TAG, "interface update failed");
2288             }
2289             return;
2290         }
2291     }
2292 }
2293 
2294 static void PadNetworkInterfaceInfo(NetworkInterfaceInfo *intInfo, const struct in_addr *addr, const char *name)
2295 {
2296     if (intInfo == NULL || addr == NULL || name == NULL) {
2297         return;
2298     }
2299     (void)memset_s(intInfo, sizeof(NetworkInterfaceInfo), 0, sizeof(NetworkInterfaceInfo));
2300     (void)memcpy_s(&intInfo->ip, sizeof(struct in_addr), addr, sizeof(struct in_addr));
2301     if (strcpy_s(intInfo->name, sizeof(intInfo->name), name) != EOK) {
2302         DFINDER_LOGE(TAG, "interface name copy failed");
2303     }
2304 }
2305 
2306 #ifndef _WIN32
2307 static void UpdateInterface(struct ifreq *buf, uint8_t *isUpdated, NetworkInterfaceInfo *ethIntInfo,
2308                             NetworkInterfaceInfo *wlanIntInfo)
2309 {
2310     struct sockaddr_in *sa = (struct sockaddr_in *)&(buf->ifr_addr);
2311     if (IsEthIpAddr(buf->ifr_name) && !isUpdated[NSTACKX_ETH_INDEX]) {
2312         PadNetworkInterfaceInfo(ethIntInfo, &sa->sin_addr, buf->ifr_name);
2313         isUpdated[NSTACKX_ETH_INDEX] = NSTACKX_TRUE;
2314         return;
2315     }
2316     if (IsWlanIpAddr(buf->ifr_name) && !isUpdated[NSTACKX_WLAN_INDEX]) {
2317         PadNetworkInterfaceInfo(wlanIntInfo, &sa->sin_addr, buf->ifr_name);
2318         isUpdated[NSTACKX_WLAN_INDEX] = NSTACKX_TRUE;
2319         return;
2320     }
2321 
2322     /* p2p or usb new ip does not write to g_interfaceList */
2323     if (IsP2pIpAddr(buf->ifr_name) && !isUpdated[NSTACKX_P2P_INDEX]) {
2324         TryToInitP2pCoapServer(sa->sin_addr);
2325         isUpdated[NSTACKX_P2P_INDEX] = NSTACKX_TRUE;
2326         return;
2327     }
2328     if (IsUsbIpAddr(buf->ifr_name) && !isUpdated[NSTACKX_USB_INDEX]) {
2329         TryToInitUsbCoapServer(sa->sin_addr);
2330         isUpdated[NSTACKX_USB_INDEX] = NSTACKX_TRUE;
2331         return;
2332     }
2333 }
2334 
2335 void GetLocalNetworkInterface(void *arg)
2336 {
2337     struct ifreq buf[INTERFACE_MAX];
2338     struct ifconf ifc;
2339     uint8_t isUpdated[NSTACKX_MAX_INTERFACE_NUM] = {0};
2340     NetworkInterfaceInfo wlanIntInfo, ethIntInfo;
2341     (void)arg;
2342     int fd = GetInterfaceList(&ifc, buf, sizeof(buf));
2343     if (fd < 0) {
2344         return;
2345     }
2346 
2347     int interfaceNum = ifc.ifc_len / sizeof(struct ifreq);
2348     for (int i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) {
2349         /* get IP of this interface */
2350         int state = GetInterfaceIP(fd, &buf[i]);
2351         if (state == NSTACKX_EFAILED) {
2352             close(fd);
2353             return;
2354         } else if (state == NSTACKX_EINVAL) {
2355             continue;
2356         }
2357         UpdateInterface(&buf[i], isUpdated, &ethIntInfo, &wlanIntInfo);
2358     }
2359     close(fd);
2360     if (isUpdated[NSTACKX_ETH_INDEX] && UpdateLocalNetworkInterface(&ethIntInfo) != NSTACKX_EOK) {
2361         DFINDER_LOGE(TAG, "Update eth interface failed");
2362     }
2363     if (!isUpdated[NSTACKX_ETH_INDEX] && isUpdated[NSTACKX_WLAN_INDEX] &&
2364         UpdateLocalNetworkInterface(&wlanIntInfo) != NSTACKX_EOK) {
2365         DFINDER_LOGE(TAG, "Update wlan interface failed");
2366     }
2367 }
2368 #else
2369 static void UpdateInterface(InterfaceInfo *buf, uint8_t *isUpdated, NetworkInterfaceInfo *ethIntInfo,
2370                             NetworkInterfaceInfo *wlanIntInfo)
2371 {
2372     struct in_addr *sa = (struct in_addr *)&(buf->ipAddr);
2373     if (IsEthIpAddr(sa) && !isUpdated[NSTACKX_ETH_INDEX]) {
2374         PadNetworkInterfaceInfo(ethIntInfo, sa, buf->name);
2375         isUpdated[NSTACKX_ETH_INDEX] = NSTACKX_TRUE;
2376         return;
2377     }
2378     if (IsWlanIpAddr(sa) && !isUpdated[NSTACKX_WLAN_INDEX]) {
2379         PadNetworkInterfaceInfo(wlanIntInfo, sa, buf->name);
2380         isUpdated[NSTACKX_WLAN_INDEX] = NSTACKX_TRUE;
2381         return;
2382     }
2383 
2384     /* p2p or usb new ip does not write to g_interfaceList */
2385     if (IsP2pIpAddr(sa) && !isUpdated[NSTACKX_P2P_INDEX]) {
2386         TryToInitP2pCoapServer(*sa);
2387         isUpdated[NSTACKX_P2P_INDEX] = NSTACKX_TRUE;
2388         return;
2389     }
2390     if (IsUsbIpAddr(sa) && !isUpdated[NSTACKX_USB_INDEX]) {
2391         TryToInitUsbCoapServer(*sa);
2392         isUpdated[NSTACKX_USB_INDEX] = NSTACKX_TRUE;
2393         return;
2394     }
2395 }
2396 
2397 void GetLocalNetworkInterface(void *arg)
2398 {
2399     uint8_t isUpdated[NSTACKX_MAX_INTERFACE_NUM] = {0};
2400     NetworkInterfaceInfo wlanIntInfo, ethIntInfo;
2401     (void)arg;
2402 
2403     InterfaceInfo interfaceList[INTERFACE_MAX];
2404     int interfaceInfoSize = 0;
2405     if (GetInterfaceList(interfaceList, &interfaceInfoSize) == NSTACKX_EFAILED) {
2406         DFINDER_LOGE(TAG, "GetInterfaceList failed");
2407         return NSTACKX_EFAILED;
2408     }
2409 
2410     for (int i = 0; i < interfaceInfoSize; i++) {
2411         UpdateInterface(&interfaceList[i], isUpdated, &ethIntInfo, &wlanIntInfo);
2412     }
2413 
2414     if (isUpdated[NSTACKX_ETH_INDEX] && UpdateLocalNetworkInterface(&ethIntInfo) != NSTACKX_EOK) {
2415         DFINDER_LOGE(TAG, "Update eth interface failed");
2416     }
2417     if (!isUpdated[NSTACKX_ETH_INDEX] && isUpdated[NSTACKX_WLAN_INDEX] &&
2418         UpdateLocalNetworkInterface(&wlanIntInfo) != NSTACKX_EOK) {
2419         DFINDER_LOGE(TAG, "Update wlan interface failed");
2420     }
2421 }
2422 #endif
2423 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
2424 #endif /* END OF DFINDER_SUPPORT_MULTI_NIF */
2425 
2426 void ResetDeviceTaskCount(uint8_t isBusy)
2427 {
2428     if (g_offlineDeferredTimer != NULL) {
2429         if (isBusy) {
2430             DFINDER_LOGI(TAG, "in this busy interval: g_offlineDeferredTimer task count %llu",
2431                          g_offlineDeferredTimer->task.count);
2432         }
2433         g_offlineDeferredTimer->task.count = 0;
2434     }
2435 #if !defined(DFINDER_SUPPORT_MULTI_NIF) && !defined(DFINDER_USE_MINI_NSTACK)
2436     if (g_p2pServerInitDeferredTimer != NULL) {
2437         if (isBusy) {
2438             DFINDER_LOGI(TAG, "in this busy interval: g_p2pServerInitDeferredTimer task count %llu",
2439                          g_p2pServerInitDeferredTimer->task.count);
2440         }
2441         g_p2pServerInitDeferredTimer->task.count = 0;
2442     }
2443 
2444     if (g_usbServerInitDeferredTimer != NULL) {
2445         if (isBusy) {
2446             DFINDER_LOGI(TAG, "in this busy interval: g_usbServerInitDeferredTimer task count %llu",
2447                          g_usbServerInitDeferredTimer->task.count);
2448         }
2449         g_usbServerInitDeferredTimer->task.count = 0;
2450     }
2451 #endif /* END OF (!DFINDER_SUPPORT_MULTI_NIF) && (!DFINDER_USE_MINI_NSTACKX) */
2452 }
2453 
2454 int32_t SetLocalDeviceBusinessDataUnicast(const char* businessData, uint32_t length)
2455 {
2456     if (strncpy_s(g_localDeviceInfo.businessData.businessDataUnicast, NSTACKX_MAX_BUSINESS_DATA_LEN,
2457         businessData, length) != EOK)  {
2458         DFINDER_LOGE(TAG, "businessData copy error");
2459         return NSTACKX_EFAILED;
2460     }
2461     return NSTACKX_EOK;
2462 }
2463