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(¬ifyDevice, sizeof(notifyDevice), 0, sizeof(notifyDevice));
824 if (GetNotifyDeviceInfo(¬ifyDevice, deviceInfo) != NSTACKX_EOK) {
825 DFINDER_LOGE(TAG, "GetNotifyDeviceInfo failed");
826 return NSTACKX_EFAILED;
827 }
828 NotifyDeviceListChanged(¬ifyDevice, NSTACKX_MAX_DEVICE_NUM);
829 if (CoapDiscoverRequestOngoing()) {
830 NotifyDeviceFound(¬ifyDevice, 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, ðIntInfo, &wlanIntInfo);
2358 }
2359 close(fd);
2360 if (isUpdated[NSTACKX_ETH_INDEX] && UpdateLocalNetworkInterface(ðIntInfo) != 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, ðIntInfo, &wlanIntInfo);
2412 }
2413
2414 if (isUpdated[NSTACKX_ETH_INDEX] && UpdateLocalNetworkInterface(ðIntInfo) != 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