1 /*
2 * Copyright (C) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "nstackx_common.h"
17
18 #include <securec.h>
19 #ifndef _WIN32
20 #include <pthread.h>
21 #include <semaphore.h>
22 #include <stdatomic.h>
23 #include <unistd.h>
24 #endif
25 #include "cJSON.h"
26
27 #ifndef DFINDER_USE_MINI_NSTACKX
28 #include <coap3/coap.h>
29 #endif
30
31 #include "coap_app.h"
32 #include "coap_discover.h"
33 #include "nstackx.h"
34 #include "nstackx_device.h"
35 #include "nstackx_epoll.h"
36 #include "nstackx_error.h"
37 #include "nstackx_event.h"
38 #include "nstackx_dfinder_log.h"
39 #include "nstackx_smartgenius.h"
40 #include "nstackx_timer.h"
41 #include "nstackx_util.h"
42 #include "json_payload.h"
43 #include "nstackx_statistics.h"
44 #include "nstackx_dfinder_hidump.h"
45 #include "nstackx_dfinder_hievent.h"
46 #include "nstackx_device_local.h"
47 #include "nstackx_device_remote.h"
48
49 #ifdef DFINDER_USE_MINI_NSTACKX
50 #include "cmsis_os2.h"
51 #include "ohos_init.h"
52 #define DFINDER_THREAD_STACK_SIZE (1024 * 32)
53 #endif
54
55 #define TAG "nStackXDFinder"
56 #define DFINDER_THREAD_NAME TAG
57
58 enum {
59 NSTACKX_INIT_STATE_START = 0,
60 NSTACKX_INIT_STATE_ONGOING,
61 NSTACKX_INIT_STATE_DONE,
62 };
63
64 #ifdef DFINDER_USE_MINI_NSTACKX
65 static osThreadId_t g_threadId;
66 #else
67 static pthread_t g_tid;
68 #endif
69
70 static EpollDesc g_epollfd = INVALID_EPOLL_DESC;
71 static List g_eventNodeChain = {&(g_eventNodeChain), &(g_eventNodeChain)};
72
73 static uint8_t g_validTidFlag = NSTACKX_FALSE;
74 static uint8_t g_terminateFlag = NSTACKX_FALSE;
75
76 static pthread_mutex_t g_threadInitLock = PTHREAD_MUTEX_INITIALIZER;
77 static NSTACKX_Parameter g_parameter;
78 static atomic_uint_fast8_t g_nstackInitState = NSTACKX_INIT_STATE_START;
79 static atomic_uint_fast8_t g_nstackThreadInitState = NSTACKX_INIT_STATE_START;
80 static bool g_isNotifyPerDevice;
81
82 #define EVENT_COUNT_RATE_INTERVAL 2000 /* 2 SECONDS */
83 #define MAX_EVENT_PROCESS_NUM_PER_INTERVAL 700
84 #define MAX_CONTINUOUS_BUSY_INTERVAL_NUM 20
85
86 typedef struct {
87 uint32_t epollWaitTimeoutCount;
88 uint32_t epollWaitEventCount;
89 struct timespec measureBefore;
90 } EventProcessRatePara;
91 static EventProcessRatePara g_processRatePara;
92 static uint32_t g_continuousBusyIntervals;
93
94 static int32_t CheckDiscoverySettings(const NSTACKX_DiscoverySettings *discoverySettings);
95 static int32_t RegisterDeviceWithType(const NSTACKX_LocalDeviceInfoV2 *localDeviceInfo, int registerType);
96
GetIsNotifyPerDevice(void)97 bool GetIsNotifyPerDevice(void)
98 {
99 return g_isNotifyPerDevice;
100 }
101
102 #ifdef DFINDER_SUPPORT_COVERITY_TAINTED_SET
Coverity_Tainted_Set(void * buf)103 void Coverity_Tainted_Set(void *buf)
104 {
105 (void)buf;
106 }
107 #endif
108
GetEventNodeChain(void)109 List *GetEventNodeChain(void)
110 {
111 return &g_eventNodeChain;
112 }
113
GetEpollFD(void)114 EpollDesc GetEpollFD(void)
115 {
116 return g_epollfd;
117 }
118
NotifyDFinderMsgRecver(DFinderMsgType msgType)119 void NotifyDFinderMsgRecver(DFinderMsgType msgType)
120 {
121 if (g_parameter.onDFinderMsgReceived != NULL) {
122 g_parameter.onDFinderMsgReceived(msgType);
123 }
124 }
125
ShouldAutoReplyUnicast(uint8_t businessType)126 int32_t ShouldAutoReplyUnicast(uint8_t businessType)
127 {
128 switch (businessType) {
129 case NSTACKX_BUSINESS_TYPE_SOFTBUS:
130 case NSTACKX_BUSINESS_TYPE_AUTONET:
131 case NSTACKX_BUSINESS_TYPE_STRATEGY:
132 return NSTACKX_FALSE;
133 case NSTACKX_BUSINESS_TYPE_NULL:
134 case NSTACKX_BUSINESS_TYPE_HICOM:
135 case NSTACKX_BUSINESS_TYPE_NEARBY:
136 default:
137 return NSTACKX_TRUE;
138 }
139 }
140
GetDefaultDiscoverInterval(uint32_t discoverCount)141 uint32_t GetDefaultDiscoverInterval(uint32_t discoverCount)
142 {
143 if (discoverCount < COAP_FIRST_DISCOVER_COUNT_RANGE) {
144 return COAP_FIRST_DISCOVER_INTERVAL;
145 } else if (discoverCount < COAP_SECOND_DISCOVER_COUNT_RANGE) {
146 return COAP_SECOND_DISCOVER_INTERVAL;
147 } else {
148 return COAP_LAST_DISCOVER_INTERVAL;
149 }
150 }
151
GetServiceDiscoverInfo(const uint8_t * buf,size_t size,struct DeviceInfo * deviceInfo,char ** remoteUrlPtr)152 int32_t GetServiceDiscoverInfo(const uint8_t *buf, size_t size, struct DeviceInfo *deviceInfo, char **remoteUrlPtr)
153 {
154 uint8_t *newBuf = NULL;
155 if (size <= 0) {
156 DFINDER_LOGE(TAG, "buf size <= 0");
157 return NSTACKX_EFAILED;
158 }
159 if (buf[size - 1] != '\0') {
160 newBuf = (uint8_t *)calloc(size + 1, 1U);
161 if (newBuf == NULL) {
162 DFINDER_LOGE(TAG, "data is not end with 0 and new buf calloc error");
163 return NSTACKX_ENOMEM;
164 }
165 if (memcpy_s(newBuf, size + 1, buf, size) != EOK) {
166 DFINDER_LOGE(TAG, "data is not end with 0 and memcpy data error");
167 goto L_COAP_ERR;
168 }
169 DFINDER_LOGI(TAG, "data is not end with 0");
170 buf = newBuf;
171 }
172 if (ParseServiceDiscover(buf, deviceInfo, remoteUrlPtr) != NSTACKX_EOK) {
173 DFINDER_LOGE(TAG, "parse service discover error");
174 goto L_COAP_ERR;
175 }
176
177 if (newBuf != NULL) {
178 free(newBuf);
179 }
180
181 return NSTACKX_EOK;
182 L_COAP_ERR:
183 if (newBuf != NULL) {
184 free(newBuf);
185 }
186 return NSTACKX_EFAILED;
187 }
188
GetServiceNotificationInfo(const uint8_t * buf,size_t size,NSTACKX_NotificationConfig * notification)189 int32_t GetServiceNotificationInfo(const uint8_t *buf, size_t size, NSTACKX_NotificationConfig *notification)
190 {
191 uint8_t *newBuf = NULL;
192 if (buf[size - 1] != '\0') {
193 newBuf = (uint8_t *)calloc(size + 1, 1U);
194 if (newBuf == NULL) {
195 DFINDER_LOGE(TAG, "data is not end with 0 and new buf calloc error");
196 return NSTACKX_ENOMEM;
197 }
198 if (memcpy_s(newBuf, size + 1, buf, size) != EOK) {
199 DFINDER_LOGE(TAG, "data is not end with 0 and memcpy data error");
200 goto L_COAP_ERR;
201 }
202 DFINDER_LOGI(TAG, "data is not end with 0");
203 buf = newBuf;
204 }
205 if (ParseServiceNotification(buf, notification) != NSTACKX_EOK) {
206 DFINDER_LOGE(TAG, "parse service notification error");
207 goto L_COAP_ERR;
208 }
209
210 if (newBuf != NULL) {
211 free(newBuf);
212 }
213
214 return NSTACKX_EOK;
215 L_COAP_ERR:
216 if (newBuf != NULL) {
217 free(newBuf);
218 }
219 return NSTACKX_EFAILED;
220 }
221
ResetMainEpollTaskCount(uint8_t isBusy)222 static void ResetMainEpollTaskCount(uint8_t isBusy)
223 {
224 EpollTask *task = GetEpollTask(&g_eventNodeChain, g_epollfd);
225 if (task == NULL) {
226 return;
227 }
228 if (isBusy) {
229 DFINDER_LOGI(TAG, "in this busy interval: main epoll task count %llu", task->count);
230 }
231 task->count = 0;
232 }
233
IsBusyInterval(uint32_t eventCount,uint32_t timeMs)234 static uint8_t IsBusyInterval(uint32_t eventCount, uint32_t timeMs)
235 {
236 uint8_t retFlag = NSTACKX_TRUE;
237 if ((uint64_t)eventCount * EVENT_COUNT_RATE_INTERVAL <
238 MAX_EVENT_PROCESS_NUM_PER_INTERVAL * (uint64_t)timeMs) {
239 retFlag = NSTACKX_FALSE;
240 }
241
242 ResetMainEpollTaskCount(retFlag);
243 ResetCoapSocketTaskCount(retFlag);
244 ResetCoapDiscoverTaskCount(retFlag);
245 ResetDeviceTaskCount(retFlag);
246 #ifndef DFINDER_USE_MINI_NSTACKX
247 ResetSmartGeniusTaskCount(retFlag);
248 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
249
250 return retFlag;
251 }
252
CalculateEventProcessRate(void)253 static void CalculateEventProcessRate(void)
254 {
255 struct timespec now;
256 ClockGetTime(CLOCK_MONOTONIC, &now);
257 uint32_t measureElapse = GetTimeDiffMs(&now, &g_processRatePara.measureBefore);
258 if (measureElapse <= EVENT_COUNT_RATE_INTERVAL) {
259 return;
260 }
261 uint32_t totalCount = g_processRatePara.epollWaitEventCount + g_processRatePara.epollWaitTimeoutCount;
262 if (!IsBusyInterval(totalCount, measureElapse)) {
263 g_continuousBusyIntervals = 0;
264 } else {
265 DFINDER_LOGI(TAG, "main loop seems to be busy in the past interval. Timeout count %u, event count %u",
266 g_processRatePara.epollWaitTimeoutCount, g_processRatePara.epollWaitEventCount);
267 g_continuousBusyIntervals++;
268 if (g_continuousBusyIntervals >= MAX_CONTINUOUS_BUSY_INTERVAL_NUM) {
269 DFINDER_LOGE(TAG, "main loop seems to be busy in the past %u intervals. notify user to restart",
270 g_continuousBusyIntervals);
271 NotifyDFinderMsgRecver(DFINDER_ON_TOO_BUSY);
272 g_continuousBusyIntervals = 0;
273 }
274 }
275 g_processRatePara.epollWaitTimeoutCount = 0;
276 g_processRatePara.epollWaitEventCount = 0;
277 ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore);
278 }
279
NstackMainLoop(void * arg)280 static void *NstackMainLoop(void *arg)
281 {
282 int32_t ret;
283 (void)arg;
284 (void)memset_s(&g_processRatePara, sizeof(g_processRatePara), 0, sizeof(g_processRatePara));
285 g_continuousBusyIntervals = 0;
286 ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore);
287 #ifndef DFINDER_USE_MINI_NSTACKX
288 SetThreadName(DFINDER_THREAD_NAME);
289 #endif
290 while (g_terminateFlag == NSTACKX_FALSE) {
291 #ifndef DFINDER_USE_MINI_NSTACKX
292 uint32_t timeout = RegisterCoAPEpollTask(g_epollfd);
293 ret = EpollLoop(g_epollfd, timeout);
294 #else
295 ret = EpollLoop(g_epollfd, -1);
296 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
297 if (ret == NSTACKX_EFAILED) {
298 IncStatistics(STATS_EPOLL_ERROR);
299 DFINDER_LOGE(TAG, "epoll loop failed");
300 #ifndef DFINDER_USE_MINI_NSTACKX
301 DeRegisterCoAPEpollTask();
302 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
303 break;
304 } else if (ret == NSTACKX_ETIMEOUT) {
305 g_processRatePara.epollWaitTimeoutCount++;
306 } else if (ret > 0) {
307 g_processRatePara.epollWaitEventCount++;
308 } else {
309 /* do nothing */
310 }
311 CalculateEventProcessRate();
312 #ifndef DFINDER_USE_MINI_NSTACKX
313 DeRegisterCoAPEpollTask();
314 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
315 }
316 return NULL;
317 }
318
GetMainLoopEpollFd(void)319 EpollDesc GetMainLoopEpollFd(void)
320 {
321 return g_epollfd;
322 }
323
GetMainLoopEvendChain(void)324 List *GetMainLoopEvendChain(void)
325 {
326 return &g_eventNodeChain;
327 }
328
InternalInit(EpollDesc epollfd,uint32_t maxDeviceNum)329 static int32_t InternalInit(EpollDesc epollfd, uint32_t maxDeviceNum)
330 {
331 int32_t ret = EventModuleInit(&g_eventNodeChain, g_epollfd);
332 if (ret != NSTACKX_EOK) {
333 return ret;
334 }
335
336 ret = DeviceModuleInit(epollfd, maxDeviceNum);
337 if (ret != NSTACKX_EOK) {
338 return ret;
339 }
340
341 #ifdef _WIN32
342 ret = CoapThreadInit();
343 if (ret != NSTACKX_EOK) {
344 return ret;
345 }
346 #endif
347
348 ret = CoapDiscoverInit(epollfd);
349 if (ret != NSTACKX_EOK) {
350 return ret;
351 }
352
353 #ifndef DFINDER_USE_MINI_NSTACKX
354 ret = SmartGeniusInit(epollfd);
355 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
356 return ret;
357 }
358
359 #ifdef DFINDER_USE_MINI_NSTACKX
ReportMainLoopStopInner(void * argument)360 static void ReportMainLoopStopInner(void *argument)
361 {
362 (void)argument;
363 DFINDER_LOGI(TAG, "receive message to stop main loop");
364 }
365
ReportMainLoopStop(void)366 static void ReportMainLoopStop(void)
367 {
368 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
369 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
370 return;
371 }
372 if (PostEvent(&g_eventNodeChain, g_epollfd, ReportMainLoopStopInner, NULL) != NSTACKX_EOK) {
373 DFINDER_LOGE(TAG, "Failed to report mainloop stop!");
374 }
375 }
376 #endif
377
NSTACKX_ThreadInit(void)378 int32_t NSTACKX_ThreadInit(void)
379 {
380 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
381 DFINDER_LOGE(TAG, "nstack is not initiated foundation yet");
382 return NSTACKX_EFAILED;
383 }
384 if (PthreadMutexLock(&g_threadInitLock) != 0) {
385 DFINDER_LOGE(TAG, "Failed to lock");
386 return NSTACKX_EFAILED;
387 }
388 DFINDER_LOGI(TAG, "nstack begin init thread");
389 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_START) {
390 (void)PthreadMutexUnlock(&g_threadInitLock);
391 return NSTACKX_EOK;
392 }
393 g_nstackThreadInitState = NSTACKX_INIT_STATE_ONGOING;
394 g_terminateFlag = NSTACKX_FALSE;
395 g_validTidFlag = NSTACKX_FALSE;
396 #ifndef DFINDER_USE_MINI_NSTACKX
397 int32_t ret = PthreadCreate(&g_tid, NULL, NstackMainLoop, NULL);
398 if (ret != 0) {
399 DFINDER_LOGE(TAG, "thread create failed");
400 g_terminateFlag = NSTACKX_TRUE;
401 (void)PthreadMutexUnlock(&g_threadInitLock);
402 return ret;
403 }
404 #else
405 osThreadAttr_t attr = {0};
406 attr.name = DFINDER_THREAD_NAME;
407 attr.stack_size = DFINDER_THREAD_STACK_SIZE;
408 // osPriorityNormal equals 24
409 attr.priority = osPriorityNormal;
410 g_threadId = osThreadNew((osThreadFunc_t)NstackMainLoop, NULL, &attr);
411 if (g_threadId == NULL) {
412 DFINDER_LOGE(TAG, "thread create failed with attribute settings");
413 g_terminateFlag = NSTACKX_TRUE;
414 (void)PthreadMutexUnlock(&g_threadInitLock);
415 return NSTACKX_EFAILED;
416 }
417 #endif
418 g_validTidFlag = NSTACKX_TRUE;
419 g_nstackThreadInitState = NSTACKX_INIT_STATE_DONE;
420 (void)PthreadMutexUnlock(&g_threadInitLock);
421 return NSTACKX_EOK;
422 }
423
NSTACKX_ThreadDeinit(void)424 void NSTACKX_ThreadDeinit(void)
425 {
426 if (g_nstackThreadInitState == NSTACKX_INIT_STATE_START) {
427 return;
428 }
429 DFINDER_LOGI(TAG, "nstack begin deinit thread");
430 if (PthreadMutexLock(&g_threadInitLock) != 0) {
431 DFINDER_LOGE(TAG, "Failed to lock");
432 return;
433 }
434 if (g_validTidFlag) {
435 g_terminateFlag = NSTACKX_TRUE;
436 #ifndef DFINDER_USE_MINI_NSTACKX
437 PthreadJoin(g_tid, NULL);
438 #else
439 ReportMainLoopStop();
440 if (osThreadTerminate(g_threadId) != osOK) {
441 DFINDER_LOGE(TAG, "os thread terminate failed");
442 }
443 #endif
444 g_validTidFlag = NSTACKX_FALSE;
445 }
446 g_nstackThreadInitState = NSTACKX_INIT_STATE_START;
447 (void)PthreadMutexUnlock(&g_threadInitLock);
448 }
449
450 #if !defined(DFINDER_USE_MINI_NSTACKX) && !defined(DFINDER_ENABLE_COAP_LOG)
CoapLogHandler(coap_log_t level,const char * message)451 static void CoapLogHandler(coap_log_t level, const char *message)
452 {
453 (void)level;
454 (void)message;
455 }
456 #endif
457
InitLogLevel(void)458 static void InitLogLevel(void)
459 {
460 // default log
461 SetLogLevel(NSTACKX_LOG_LEVEL_DEBUG);
462
463 // user defined log
464 #ifdef ENABLE_USER_LOG
465 SetDFinderLogLevel(DFINDER_LOG_LEVEL_DEBUG);
466 #endif
467
468 #ifndef DFINDER_USE_MINI_NSTACKX
469 // opensource libcoap log
470 #ifdef DFINDER_ENABLE_COAP_LOG
471 coap_set_log_level(COAP_LOG_DEBUG);
472 #else
473 coap_set_log_handler(CoapLogHandler);
474 #endif
475 #endif
476 }
477
NstackxInitEx(const NSTACKX_Parameter * parameter,bool isNotifyPerDevice)478 static int32_t NstackxInitEx(const NSTACKX_Parameter *parameter, bool isNotifyPerDevice)
479 {
480 Coverity_Tainted_Set((void *)parameter);
481
482 int32_t ret;
483
484 if (g_nstackInitState != NSTACKX_INIT_STATE_START) {
485 return NSTACKX_EOK;
486 }
487
488 g_nstackInitState = NSTACKX_INIT_STATE_ONGOING;
489 cJSON_InitHooks(NULL);
490
491 InitLogLevel();
492
493 #ifdef NSTACKX_WITH_LITEOS
494 EpollEventPtrInit(); /* init g_epollEventPtrMutex g_epollEventPtrArray */
495 #endif
496
497 g_epollfd = CreateEpollDesc();
498 if (!IsEpollDescValid(g_epollfd)) {
499 DFINDER_LOGE(TAG, "epoll creat fail! errno: %d", errno);
500 g_nstackInitState = NSTACKX_INIT_STATE_START;
501 return NSTACKX_EFAILED;
502 }
503
504 DFINDER_LOGD(TAG, "nstack ctrl creat epollfd %d", REPRESENT_EPOLL_DESC(g_epollfd));
505 #ifdef DFINDER_SAVE_DEVICE_LIST
506 ret = InternalInit(g_epollfd, parameter != NULL ? parameter->maxDeviceNum : NSTACKX_DEFAULT_DEVICE_NUM);
507 #else
508 ret = InternalInit(g_epollfd, parameter != NULL ? parameter->maxDeviceNum : NSTACKX_MAX_DEVICE_NUM);
509 #endif
510 if (ret != NSTACKX_EOK) {
511 DFINDER_LOGE(TAG, "internal init failed, ret=%d", ret);
512 goto L_ERR_INIT;
513 }
514 (void)memset_s(&g_parameter, sizeof(g_parameter), 0, sizeof(g_parameter));
515 if (parameter != NULL) {
516 (void)memcpy_s(&g_parameter, sizeof(g_parameter), parameter, sizeof(NSTACKX_Parameter));
517 }
518
519 #ifndef DFINDER_USE_MINI_NSTACKX
520 CoapInitSubscribeModuleInner(); /* initialize subscribe module number */
521 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
522 g_isNotifyPerDevice = isNotifyPerDevice;
523 g_nstackInitState = NSTACKX_INIT_STATE_DONE;
524 DFINDER_LOGI(TAG, "DFinder init successfully");
525 return NSTACKX_EOK;
526
527 L_ERR_INIT:
528 NSTACKX_Deinit();
529 return ret;
530 }
531
NSTACKX_Init(const NSTACKX_Parameter * parameter)532 int32_t NSTACKX_Init(const NSTACKX_Parameter *parameter)
533 {
534 return NstackxInitEx(parameter, false);
535 }
536
NSTACKX_InitV2(const NSTACKX_Parameter * parameter,bool isNotifyPerDevice)537 int32_t NSTACKX_InitV2(const NSTACKX_Parameter *parameter, bool isNotifyPerDevice)
538 {
539 return NstackxInitEx(parameter, isNotifyPerDevice);
540 }
541
NSTACKX_Deinit(void)542 void NSTACKX_Deinit(void)
543 {
544 if (g_nstackInitState == NSTACKX_INIT_STATE_START) {
545 return;
546 }
547 NSTACKX_ThreadDeinit();
548 #ifndef DFINDER_USE_MINI_NSTACKX
549 SmartGeniusClean();
550 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
551 CoapDiscoverDeinit();
552
553 #ifdef _WIN32
554 CoapThreadDestroy();
555 #endif
556 DeviceModuleClean();
557 EventNodeChainClean(&g_eventNodeChain);
558 if (IsEpollDescValid(g_epollfd)) {
559 CloseEpollDesc(g_epollfd);
560 g_epollfd = INVALID_EPOLL_DESC;
561 }
562 ResetStatistics();
563 ResetEventFunc();
564 ResetSequenceNumber();
565 g_nstackInitState = NSTACKX_INIT_STATE_START;
566 DFINDER_LOGI(TAG, "deinit successfully");
567 }
568
DeviceDiscoverInner(void * argument)569 static void DeviceDiscoverInner(void *argument)
570 {
571 if (!IsCoapContextReady()) {
572 DFINDER_LOGE(TAG, "no iface is ready, notify user with empty list");
573 NotifyDeviceFound(NULL, 0);
574 return;
575 }
576
577 (void)argument;
578 SetCoapDiscoverType(COAP_BROADCAST_TYPE_DEFAULT);
579 SetLocalDeviceBusinessType(NSTACKX_BUSINESS_TYPE_NULL);
580 CoapServiceDiscoverInner(INNER_DISCOVERY);
581 }
582
DeviceDiscoverInnerAn(void * argument)583 static void DeviceDiscoverInnerAn(void *argument)
584 {
585 (void)argument;
586 SetCoapDiscoverType(COAP_BROADCAST_TYPE_DEFAULT);
587 SetLocalDeviceBusinessType(NSTACKX_BUSINESS_TYPE_NULL);
588 CoapServiceDiscoverInnerAn(INNER_DISCOVERY);
589 }
590
DeviceDiscoverInnerConfigurable(void * argument)591 static void DeviceDiscoverInnerConfigurable(void *argument)
592 {
593 NSTACKX_DiscoverySettings *discoverySettings = argument;
594 int32_t configResult = ConfigureDiscoverySettings(discoverySettings);
595 free(discoverySettings->businessData);
596 free(discoverySettings);
597 if (configResult != NSTACKX_EOK) {
598 DFINDER_LOGE(TAG, "config discovery settings failed");
599 return;
600 }
601 CoapServiceDiscoverInnerConfigurable(INNER_DISCOVERY);
602 }
603
DiscConfig(void * argument)604 static void DiscConfig(void *argument)
605 {
606 DFinderDiscConfig *discConfig = argument;
607 uint8_t businessTypeLocal = GetLocalDeviceBusinessType();
608 if (discConfig->businessType != businessTypeLocal) {
609 DFINDER_LOGE(TAG, "business type is different, config: %hhu, local: %hhu",
610 discConfig->businessType, businessTypeLocal);
611 free(discConfig->businessData);
612 free(discConfig->bcastInterval);
613 free(discConfig);
614 return;
615 }
616 int32_t configResult = DiscConfigInner(discConfig);
617 free(discConfig->businessData);
618 free(discConfig->bcastInterval);
619 free(discConfig);
620 if (configResult != NSTACKX_EOK) {
621 DFINDER_LOGE(TAG, "config for discover failed");
622 return;
623 }
624 CoapServiceDiscoverInnerConfigurable(INNER_DISCOVERY);
625 }
626
DeviceDiscoverStopInner(void * argument)627 static void DeviceDiscoverStopInner(void *argument)
628 {
629 (void)argument;
630 CoapServiceDiscoverStopInner();
631 NotifyStatisticsEvent();
632 }
633
NSTACKX_StartDeviceFind(void)634 int32_t NSTACKX_StartDeviceFind(void)
635 {
636 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
637 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
638 return NSTACKX_EFAILED;
639 }
640 if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInner, NULL) != NSTACKX_EOK) {
641 DFINDER_LOGE(TAG, "Failed to start device discover!");
642 return NSTACKX_EFAILED;
643 }
644 return NSTACKX_EOK;
645 }
646
NSTACKX_StartDeviceFindAn(uint8_t mode)647 int32_t NSTACKX_StartDeviceFindAn(uint8_t mode)
648 {
649 Coverity_Tainted_Set((void *)&mode);
650 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
651 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
652 return NSTACKX_EFAILED;
653 }
654 SetModeInfo(mode);
655 if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerAn, NULL) != NSTACKX_EOK) {
656 DFINDER_LOGE(TAG, "Failed to start device discover!");
657 return NSTACKX_EFAILED;
658 }
659 return NSTACKX_EOK;
660 }
661
NSTACKX_StopDeviceFind(void)662 int32_t NSTACKX_StopDeviceFind(void)
663 {
664 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
665 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
666 return NSTACKX_EFAILED;
667 }
668 if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverStopInner, NULL) != NSTACKX_EOK) {
669 DFINDER_LOGE(TAG, "Failed to stop device discover!");
670 return NSTACKX_EFAILED;
671 }
672 return NSTACKX_EOK;
673 }
674
CopyDiscoverySettings(NSTACKX_DiscoverySettings * dupDiscoverySettings,const NSTACKX_DiscoverySettings * discoverySettings)675 static int32_t CopyDiscoverySettings(NSTACKX_DiscoverySettings *dupDiscoverySettings,
676 const NSTACKX_DiscoverySettings *discoverySettings)
677 {
678 dupDiscoverySettings->businessType = discoverySettings->businessType;
679 dupDiscoverySettings->discoveryMode = discoverySettings->discoveryMode;
680 dupDiscoverySettings->length = discoverySettings->length;
681 if (discoverySettings->businessData != NULL) {
682 if (strncpy_s(dupDiscoverySettings->businessData, (dupDiscoverySettings->length + 1),
683 discoverySettings->businessData, discoverySettings->length) != EOK) {
684 DFINDER_LOGE(TAG, "businessData strncpy failed");
685 return NSTACKX_EINVAL;
686 }
687 }
688 dupDiscoverySettings->advertiseCount = discoverySettings->advertiseCount;
689 dupDiscoverySettings->advertiseDuration = discoverySettings->advertiseDuration;
690 return NSTACKX_EOK;
691 }
692
CheckDiscoverySettings(const NSTACKX_DiscoverySettings * discoverySettings)693 static int32_t CheckDiscoverySettings(const NSTACKX_DiscoverySettings *discoverySettings)
694 {
695 if (discoverySettings == NULL) {
696 DFINDER_LOGE(TAG, "Invalid discoverySettings info");
697 return NSTACKX_EINVAL;
698 }
699 if ((discoverySettings->businessData == NULL) && (discoverySettings->length != 0)) {
700 DFINDER_LOGE(TAG, "Invalid discoverySettings bData info");
701 return NSTACKX_EINVAL;
702 }
703 if (discoverySettings->length >= NSTACKX_MAX_BUSINESS_DATA_LEN) {
704 DFINDER_LOGE(TAG, "businessData length is too long");
705 return NSTACKX_EINVAL;
706 }
707 uint32_t advertiseCount = discoverySettings->advertiseCount;
708 uint32_t advertiseDuration = discoverySettings->advertiseDuration;
709 if ((advertiseCount == 0) && (advertiseDuration == 0)) {
710 return NSTACKX_EOK;
711 }
712 if ((advertiseCount < NSTACKX_MIN_ADVERTISE_COUNT) || (advertiseCount > NSTACKX_MAX_ADVERTISE_COUNT) ||
713 (advertiseDuration < NSTACKX_MIN_ADVERTISE_DURATION) || (advertiseDuration > NSTACKX_MAX_ADVERTISE_DURATION)) {
714 DFINDER_LOGE(TAG, "Invalid discoverySettings advertise info");
715 return NSTACKX_EINVAL;
716 }
717 return NSTACKX_EOK;
718 }
719
NSTACKX_StartDeviceDiscovery(const NSTACKX_DiscoverySettings * discoverySettings)720 int32_t NSTACKX_StartDeviceDiscovery(const NSTACKX_DiscoverySettings *discoverySettings)
721 {
722 DFINDER_LOGI(TAG, "begin to NSTACKX_StartDeviceDiscovery!");
723 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
724 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
725 return NSTACKX_EFAILED;
726 }
727 if (CheckDiscoverySettings(discoverySettings) != NSTACKX_EOK) {
728 return NSTACKX_EINVAL;
729 }
730
731 NSTACKX_DiscoverySettings *dupDiscoverySettings = malloc(sizeof(NSTACKX_DiscoverySettings));
732 if (dupDiscoverySettings == NULL) {
733 DFINDER_LOGE(TAG, "malloc failed");
734 return NSTACKX_ENOMEM;
735 }
736 dupDiscoverySettings->businessData = (char *)calloc((discoverySettings->length + 1), sizeof(char));
737 if (dupDiscoverySettings->businessData == NULL) {
738 DFINDER_LOGE(TAG, "businessData calloc fail");
739 free(dupDiscoverySettings);
740 return NSTACKX_ENOMEM;
741 }
742 if (CopyDiscoverySettings(dupDiscoverySettings, discoverySettings) != NSTACKX_EOK) {
743 free(dupDiscoverySettings->businessData);
744 free(dupDiscoverySettings);
745 return NSTACKX_EINVAL;
746 }
747
748 if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerConfigurable, dupDiscoverySettings) != NSTACKX_EOK) {
749 DFINDER_LOGE(TAG, "Failed to start device discover!");
750 free(dupDiscoverySettings->businessData);
751 free(dupDiscoverySettings);
752 return NSTACKX_EFAILED;
753 }
754 return NSTACKX_EOK;
755 }
756
CopyDiscConfig(const DFinderDiscConfig * src,DFinderDiscConfig * dst)757 static int32_t CopyDiscConfig(const DFinderDiscConfig *src, DFinderDiscConfig *dst)
758 {
759 dst->businessType = src->businessType;
760 dst->discoveryMode = src->discoveryMode;
761 dst->intervalArrLen = src->intervalArrLen;
762 for (size_t idx = 0; idx < dst->intervalArrLen; ++idx) {
763 (dst->bcastInterval)[idx] = (src->bcastInterval)[idx];
764 }
765 if (src->businessData != NULL) {
766 if (strncpy_s(dst->businessData, dst->businessDataLen, src->businessData, src->businessDataLen) != EOK) {
767 DFINDER_LOGE(TAG, "copy business data failed");
768 return NSTACKX_EFAILED;
769 }
770 }
771 return NSTACKX_EOK;
772 }
773
CheckDiscInterval(uint32_t * intervalArr,uint32_t arrLen)774 static int32_t CheckDiscInterval(uint32_t *intervalArr, uint32_t arrLen)
775 {
776 if (intervalArr == NULL || arrLen == 0) {
777 DFINDER_LOGE(TAG, "illegal param, arrlen: %ld", arrLen);
778 return NSTACKX_EINVAL;
779 }
780 // check interval values one by one
781 for (size_t i = 0; i < arrLen; ++i) {
782 if (intervalArr[i] < NSTACKX_MIN_ADVERTISE_INTERVAL || intervalArr[i] > NSTACKX_MAX_ADVERTISE_INTERVAL) {
783 DFINDER_LOGE(TAG, "invalid interval");
784 return NSTACKX_EINVAL;
785 }
786 }
787 return NSTACKX_EOK;
788 }
789
CheckDiscConfig(const DFinderDiscConfig * discConfig)790 static int32_t CheckDiscConfig(const DFinderDiscConfig *discConfig)
791 {
792 if (discConfig == NULL) {
793 DFINDER_LOGE(TAG, "disc config passed in is null");
794 return NSTACKX_EINVAL;
795 }
796 // minus one for the first broadcast without interval
797 if (discConfig->bcastInterval == NULL || discConfig->intervalArrLen > (NSTACKX_MAX_ADVERTISE_COUNT - 1) ||
798 discConfig->intervalArrLen == 0) {
799 DFINDER_LOGE(TAG, "invalid broadcast interval params");
800 return NSTACKX_EINVAL;
801 }
802 if (CheckDiscInterval(discConfig->bcastInterval, discConfig->intervalArrLen) != NSTACKX_EOK) {
803 return NSTACKX_EINVAL;
804 }
805 if ((discConfig->businessData == NULL) && (discConfig->businessDataLen != 0)) {
806 DFINDER_LOGE(TAG, "invalid business data params");
807 return NSTACKX_EINVAL;
808 }
809 if (discConfig->businessDataLen >= NSTACKX_MAX_BUSINESS_DATA_LEN) {
810 DFINDER_LOGE(TAG, "business data is too long");
811 return NSTACKX_EINVAL;
812 }
813 return NSTACKX_EOK;
814 }
815
NSTACKX_StartDeviceDiscoveryWithConfig(const DFinderDiscConfig * discConfig)816 int32_t NSTACKX_StartDeviceDiscoveryWithConfig(const DFinderDiscConfig *discConfig)
817 {
818 DFINDER_LOGI(TAG, "dfinder start disc with config");
819 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
820 DFINDER_LOGE(TAG, "nstackx ctrl is not initialed yet");
821 return NSTACKX_EFAILED;
822 }
823 if (CheckDiscConfig(discConfig) != NSTACKX_EOK) {
824 return NSTACKX_EINVAL;
825 }
826 DFinderDiscConfig *dupDiscConfig = (DFinderDiscConfig *)malloc(sizeof(DFinderDiscConfig));
827 if (dupDiscConfig == NULL) {
828 DFINDER_LOGE(TAG, "malloc for duplicate disc config failed");
829 return NSTACKX_ENOMEM;
830 }
831 dupDiscConfig->bcastInterval = (uint32_t *)malloc(sizeof(uint32_t) * (discConfig->intervalArrLen));
832 if (dupDiscConfig->bcastInterval == NULL) {
833 DFINDER_LOGE(TAG, "malloc for duplicate broadcast interval failed");
834 free(dupDiscConfig);
835 return NSTACKX_ENOMEM;
836 }
837 dupDiscConfig->businessData = (char *)calloc((discConfig->businessDataLen + 1), sizeof(char));
838 if (dupDiscConfig->businessData == NULL) {
839 DFINDER_LOGE(TAG, "malloc for duplicate business data failed");
840 free(dupDiscConfig->bcastInterval);
841 free(dupDiscConfig);
842 return NSTACKX_ENOMEM;
843 }
844 // 1 to store the terminator
845 dupDiscConfig->businessDataLen = discConfig->businessDataLen + 1;
846 if (CopyDiscConfig(discConfig, dupDiscConfig) != NSTACKX_EOK) {
847 free(dupDiscConfig->businessData);
848 free(dupDiscConfig->bcastInterval);
849 free(dupDiscConfig);
850 return NSTACKX_EFAILED;
851 }
852 if (PostEvent(&g_eventNodeChain, g_epollfd, DiscConfig, dupDiscConfig) != NSTACKX_EOK) {
853 free(dupDiscConfig->businessData);
854 free(dupDiscConfig->bcastInterval);
855 free(dupDiscConfig);
856 return NSTACKX_EFAILED;
857 }
858 return NSTACKX_EOK;
859 }
860
861 #ifndef DFINDER_USE_MINI_NSTACKX
NSTACKX_SubscribeModule(void)862 int32_t NSTACKX_SubscribeModule(void)
863 {
864 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
865 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
866 return NSTACKX_EFAILED;
867 }
868 CoapSubscribeModuleInner(INNER_DISCOVERY);
869 return NSTACKX_EOK;
870 }
871
NSTACKX_UnsubscribeModule(void)872 int32_t NSTACKX_UnsubscribeModule(void)
873 {
874 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
875 return NSTACKX_EFAILED;
876 }
877 CoapUnsubscribeModuleInner(INNER_DISCOVERY);
878 return NSTACKX_EOK;
879 }
880 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
881
IsNetworkNameValid(const char * networkName,size_t len)882 static bool IsNetworkNameValid(const char *networkName, size_t len)
883 {
884 if (!StringHasEOF(networkName, len)) {
885 DFINDER_LOGE(TAG, "network name is not ended");
886 return NSTACKX_FALSE;
887 }
888
889 return NSTACKX_TRUE;
890 }
891
IsIpAddressValid(const char * ipStr,size_t len)892 static bool IsIpAddressValid(const char *ipStr, size_t len)
893 {
894 if (!StringHasEOF(ipStr, len)) {
895 DFINDER_LOGE(TAG, "ip addr is not ended");
896 return NSTACKX_FALSE;
897 }
898
899 struct in_addr ipAddr;
900 if (len != 0 && ipStr[0] != '\0' && inet_pton(AF_INET, ipStr, &ipAddr) != 1) {
901 DFINDER_LOGE(TAG, "invalid ip address");
902 return NSTACKX_FALSE;
903 }
904
905 return NSTACKX_TRUE;
906 }
907
CheckInterfaceInfo(const NSTACKX_InterfaceInfo * ifaces,uint32_t count)908 static int32_t CheckInterfaceInfo(const NSTACKX_InterfaceInfo *ifaces, uint32_t count)
909 {
910 for (uint32_t i = 0; i < count; ++i) {
911 if (!IsNetworkNameValid(ifaces[i].networkName, sizeof(ifaces[i].networkName)) ||
912 !IsIpAddressValid(ifaces[i].networkIpAddr, sizeof(ifaces[i].networkIpAddr))) {
913 DFINDER_LOGE(TAG, "invalid network name or ip address of No.%u local iface", i);
914 return NSTACKX_EINVAL;
915 }
916 }
917
918 return NSTACKX_EOK;
919 }
920
CheckLocalDeviceInfo(const NSTACKX_LocalDeviceInfo * localDeviceInfo)921 static int CheckLocalDeviceInfo(const NSTACKX_LocalDeviceInfo *localDeviceInfo)
922 {
923 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
924 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
925 return NSTACKX_EFAILED;
926 }
927
928 if (localDeviceInfo == NULL) {
929 DFINDER_LOGE(TAG, "Invalid local device info");
930 return NSTACKX_EINVAL;
931 }
932
933 if (!StringHasEOF(localDeviceInfo->deviceId, sizeof(localDeviceInfo->deviceId)) ||
934 !StringHasEOF(localDeviceInfo->name, sizeof(localDeviceInfo->name))) {
935 DFINDER_LOGE(TAG, "device id or device name is not ended");
936 return NSTACKX_EINVAL;
937 }
938
939 if (localDeviceInfo->ifNums > NSTACKX_MAX_LISTENED_NIF_NUM) {
940 DFINDER_LOGE(TAG, "invalid iface number %u", localDeviceInfo->ifNums);
941 return NSTACKX_EINVAL;
942 } else if (localDeviceInfo->ifNums == 0) {
943 if (!IsNetworkNameValid(localDeviceInfo->networkName, sizeof(localDeviceInfo->networkName)) ||
944 !IsIpAddressValid(localDeviceInfo->networkIpAddr, sizeof(localDeviceInfo->networkIpAddr))) {
945 DFINDER_LOGE(TAG, "invalid network name or ip address when iface number is 0");
946 return NSTACKX_EINVAL;
947 }
948 }
949
950 return NSTACKX_EOK;
951 }
952
DeviceInfoV2Init(NSTACKX_LocalDeviceInfoV2 * v2,const NSTACKX_LocalDeviceInfo * localDeviceInfo,bool hasDeviceHash,uint64_t deviceHash)953 static void DeviceInfoV2Init(NSTACKX_LocalDeviceInfoV2 *v2,
954 const NSTACKX_LocalDeviceInfo *localDeviceInfo, bool hasDeviceHash, uint64_t deviceHash)
955 {
956 v2->name = localDeviceInfo->name;
957 v2->deviceId = localDeviceInfo->deviceId;
958 v2->deviceType = localDeviceInfo->deviceType;
959 v2->businessType = localDeviceInfo->businessType;
960 v2->hasDeviceHash = hasDeviceHash;
961 v2->deviceHash = deviceHash;
962 }
963
RegisterDeviceWithDeviceHash(const NSTACKX_LocalDeviceInfo * localDeviceInfo,bool hasDeviceHash,uint64_t deviceHash)964 static int32_t RegisterDeviceWithDeviceHash(const NSTACKX_LocalDeviceInfo *localDeviceInfo,
965 bool hasDeviceHash, uint64_t deviceHash)
966 {
967 int ret = CheckLocalDeviceInfo(localDeviceInfo);
968 if (ret != NSTACKX_EOK) {
969 return ret;
970 }
971
972 NSTACKX_LocalDeviceInfoV2 v2;
973 DeviceInfoV2Init(&v2, localDeviceInfo, hasDeviceHash, deviceHash);
974
975 NSTACKX_InterfaceInfo ifaceInfo = { {0}, {0} };
976 if (localDeviceInfo->ifNums == 0) {
977 if (strcpy_s(ifaceInfo.networkName, sizeof(ifaceInfo.networkName), localDeviceInfo->networkName) != EOK ||
978 strcpy_s(ifaceInfo.networkIpAddr, sizeof(ifaceInfo.networkIpAddr),
979 localDeviceInfo->networkIpAddr) != EOK) {
980 DFINDER_LOGE(TAG, "copy network name or ip addr failed");
981 return NSTACKX_EINVAL;
982 }
983 v2.localIfInfo = &ifaceInfo;
984 v2.ifNums = 1;
985 } else {
986 v2.localIfInfo = &localDeviceInfo->localIfInfo[0];
987 v2.ifNums = localDeviceInfo->ifNums;
988 }
989
990 return RegisterDeviceWithType(&v2, hasDeviceHash ? REGISTER_TYPE_UPDATE_SPECIFIED : REGISTER_TYPE_UPDATE_ALL);
991 }
992
NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo * localDeviceInfo)993 int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo)
994 {
995 Coverity_Tainted_Set((void *)localDeviceInfo);
996 DFINDER_LOGI(TAG, "begin to NSTACKX_RegisterDevice!");
997
998 return RegisterDeviceWithDeviceHash(localDeviceInfo, NSTACKX_FALSE, 0);
999 }
1000
ConfigureLocalDeviceNameInner(void * argument)1001 static void ConfigureLocalDeviceNameInner(void *argument)
1002 {
1003 char *localDevName = (char *)argument;
1004
1005 ConfigureLocalDeviceName(localDevName);
1006 free(localDevName);
1007 }
1008
NSTACKX_RegisterDeviceName(const char * devName)1009 int32_t NSTACKX_RegisterDeviceName(const char *devName)
1010 {
1011 if (devName == NULL || devName[0] == '\0') {
1012 DFINDER_LOGE(TAG, "register local device name is invalid");
1013 return NSTACKX_EINVAL;
1014 }
1015 char *dupDevName = (char *)malloc(sizeof(char) * NSTACKX_MAX_DEVICE_NAME_LEN);
1016 if (dupDevName == NULL) {
1017 return NSTACKX_ENOMEM;
1018 }
1019 if (strncpy_s(dupDevName, NSTACKX_MAX_DEVICE_NAME_LEN, devName, strlen(devName)) != EOK) {
1020 DFINDER_LOGE(TAG, "strncpy dupDevName failed");
1021 free(dupDevName);
1022 return NSTACKX_EFAILED;
1023 }
1024 if (PostEvent(&g_eventNodeChain, g_epollfd, ConfigureLocalDeviceNameInner, dupDevName) != NSTACKX_EOK) {
1025 DFINDER_LOGE(TAG, "Failed to configure local device name!");
1026 free(dupDevName);
1027 return NSTACKX_EFAILED;
1028 }
1029 return NSTACKX_EOK;
1030 }
1031
NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo * localDeviceInfo,uint64_t deviceHash)1032 int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash)
1033 {
1034 Coverity_Tainted_Set((void *)localDeviceInfo);
1035 Coverity_Tainted_Set((void *)&deviceHash);
1036
1037 DFINDER_LOGI(TAG, "begin to NSTACKX_RegisterDeviceAn!");
1038 return RegisterDeviceWithDeviceHash(localDeviceInfo, NSTACKX_TRUE, deviceHash);
1039 }
1040
1041 struct RegDeviceInfo {
1042 const NSTACKX_LocalDeviceInfoV2 *info;
1043 int registerType;
1044 int32_t err;
1045 sem_t wait;
1046 };
1047
RegisterDeviceV2(void * arg)1048 static void RegisterDeviceV2(void *arg)
1049 {
1050 struct RegDeviceInfo *regInfo = (struct RegDeviceInfo *)arg;
1051 regInfo->err = RegisterLocalDeviceV2(regInfo->info, regInfo->registerType);
1052 SemPost(®Info->wait);
1053 }
1054
1055 #define NSTACKX_MAX_LOCAL_IFACE_NUM 10
1056
RegisterDeviceWithType(const NSTACKX_LocalDeviceInfoV2 * localDeviceInfo,int registerType)1057 static int32_t RegisterDeviceWithType(const NSTACKX_LocalDeviceInfoV2 *localDeviceInfo, int registerType)
1058 {
1059 if (localDeviceInfo == NULL || localDeviceInfo->name == NULL ||
1060 localDeviceInfo->deviceId == NULL || localDeviceInfo->ifNums > NSTACKX_MAX_LOCAL_IFACE_NUM ||
1061 (localDeviceInfo->ifNums != 0 && localDeviceInfo->localIfInfo == NULL) ||
1062 CheckInterfaceInfo(localDeviceInfo->localIfInfo, localDeviceInfo->ifNums) != NSTACKX_EOK) {
1063 DFINDER_LOGE(TAG, "invalid args");
1064 return NSTACKX_EINVAL;
1065 }
1066
1067 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1068 return (int32_t)RegisterLocalDeviceV2(localDeviceInfo, registerType);
1069 }
1070
1071 struct RegDeviceInfo regInfo;
1072 if (SemInit(®Info.wait, 0, 0)) {
1073 DFINDER_LOGE(TAG, "sem init fail");
1074 return NSTACKX_EBUSY;
1075 }
1076
1077 regInfo.info = localDeviceInfo;
1078 regInfo.registerType = registerType;
1079 regInfo.err = NSTACKX_EOK;
1080
1081 if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterDeviceV2, ®Info) != NSTACKX_EOK) {
1082 DFINDER_LOGE(TAG, "Failed to configure local device info!");
1083 SemDestroy(®Info.wait);
1084 return NSTACKX_EBUSY;
1085 }
1086
1087 SemWait(®Info.wait);
1088 SemDestroy(®Info.wait);
1089 return regInfo.err;
1090 }
1091
NSTACKX_RegisterDeviceV2(const NSTACKX_LocalDeviceInfoV2 * localDeviceInfo)1092 int32_t NSTACKX_RegisterDeviceV2(const NSTACKX_LocalDeviceInfoV2 *localDeviceInfo)
1093 {
1094 Coverity_Tainted_Set((void *)localDeviceInfo);
1095
1096 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1097 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1098 return NSTACKX_EFAILED;
1099 }
1100
1101 return RegisterDeviceWithType(localDeviceInfo, REGISTER_TYPE_UPDATE_ALL);
1102 }
1103
1104 typedef struct {
1105 uint32_t capabilityBitmapNum;
1106 uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM];
1107 } CapabilityProcessData;
1108
RegisterCapabilityInner(void * argument)1109 static void RegisterCapabilityInner(void *argument)
1110 {
1111 CapabilityProcessData *capabilityData = argument;
1112
1113 (void)SetLocalDeviceCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap);
1114 free(capabilityData);
1115 }
1116
SetFilterCapabilityInner(void * argument)1117 static void SetFilterCapabilityInner(void *argument)
1118 {
1119 CapabilityProcessData *capabilityData = argument;
1120
1121 (void)SetFilterCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap);
1122 free(capabilityData);
1123 }
1124
NSTACKX_CapabilityHandle(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[],EventHandle handle)1125 static int32_t NSTACKX_CapabilityHandle(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[], EventHandle handle)
1126 {
1127 Coverity_Tainted_Set((void *)&capabilityBitmapNum);
1128 Coverity_Tainted_Set((void *)capabilityBitmap);
1129
1130 CapabilityProcessData *capabilityData = NULL;
1131
1132 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1133 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1134 return NSTACKX_EFAILED;
1135 }
1136
1137 if (capabilityBitmapNum != 0 && capabilityBitmap == NULL) {
1138 DFINDER_LOGE(TAG, "bitmap array is null");
1139 return NSTACKX_EFAILED;
1140 }
1141
1142 if (capabilityBitmapNum > NSTACKX_MAX_CAPABILITY_NUM) {
1143 DFINDER_LOGE(TAG, "capabilityBitmapNum (%u) exceed max number", capabilityBitmapNum);
1144 return NSTACKX_EINVAL;
1145 }
1146
1147 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1148 if (handle == RegisterCapabilityInner) {
1149 return (int32_t)SetLocalDeviceCapability(capabilityBitmapNum, capabilityBitmap);
1150 }
1151 if (handle == SetFilterCapabilityInner) {
1152 return SetFilterCapability(capabilityBitmapNum, capabilityBitmap);
1153 }
1154 }
1155
1156 capabilityData = calloc(1U, sizeof(CapabilityProcessData));
1157 if (capabilityData == NULL) {
1158 return NSTACKX_ENOMEM;
1159 }
1160
1161 if ((capabilityBitmapNum != 0) && memcpy_s(capabilityData->capabilityBitmap,
1162 sizeof(capabilityData->capabilityBitmap), capabilityBitmap, capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
1163 free(capabilityData);
1164 return NSTACKX_EINVAL;
1165 }
1166 capabilityData->capabilityBitmapNum = capabilityBitmapNum;
1167
1168 if (PostEvent(&g_eventNodeChain, g_epollfd, handle, capabilityData) != NSTACKX_EOK) {
1169 DFINDER_LOGE(TAG, "Failed to register capability!");
1170 free(capabilityData);
1171 return NSTACKX_EFAILED;
1172 }
1173 return NSTACKX_EOK;
1174 }
1175
NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[])1176 int32_t NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
1177 {
1178 DFINDER_LOGD(TAG, "begin to call NSTACKX_RegisterCapability");
1179 return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, RegisterCapabilityInner);
1180 }
1181
NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[])1182 int32_t NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
1183 {
1184 DFINDER_LOGI(TAG, "Set Filter Capability");
1185 return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, SetFilterCapabilityInner);
1186 }
1187 typedef struct {
1188 uint32_t maxDeviceNum;
1189 sem_t wait;
1190 } SetMaxDeviceNumMsg;
1191
SetMaxDeviceNumInner(void * argument)1192 static void SetMaxDeviceNumInner(void *argument)
1193 {
1194 SetMaxDeviceNumMsg *msg = (SetMaxDeviceNumMsg *)argument;
1195 SetMaxDeviceNum(msg->maxDeviceNum);
1196 SemPost(&msg->wait);
1197 }
1198
NSTACKX_SetMaxDeviceNum(uint32_t maxDeviceNum)1199 int32_t NSTACKX_SetMaxDeviceNum(uint32_t maxDeviceNum)
1200 {
1201 SetMaxDeviceNumMsg msg = {
1202 .maxDeviceNum = maxDeviceNum,
1203 };
1204 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1205 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1206 return NSTACKX_EFAILED;
1207 }
1208 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1209 SetMaxDeviceNum(maxDeviceNum);
1210 return NSTACKX_EOK;
1211 }
1212 if (SemInit(&msg.wait, 0, 0)) {
1213 DFINDER_LOGE(TAG, "Failed to init sem!");
1214 return NSTACKX_EFAILED;
1215 }
1216 if (PostEvent(&g_eventNodeChain, g_epollfd, SetMaxDeviceNumInner, &msg) != NSTACKX_EOK) {
1217 DFINDER_LOGE(TAG, "Failed to set max device num!");
1218 SemDestroy(&msg.wait);
1219 return NSTACKX_EFAILED;
1220 }
1221 SemWait(&msg.wait);
1222 SemDestroy(&msg.wait);
1223 return NSTACKX_EOK;
1224 }
1225
1226 #ifdef DFINDER_SAVE_DEVICE_LIST
NSTACKX_SetDeviceListAgingTime(uint32_t agingTime)1227 int32_t NSTACKX_SetDeviceListAgingTime(uint32_t agingTime)
1228 {
1229 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1230 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1231 return NSTACKX_EFAILED;
1232 }
1233 SetDeviceListAgingTime(agingTime);
1234 return NSTACKX_EOK;
1235 }
1236 #else
NSTACKX_SetDeviceListAgingTime(uint32_t agingTime)1237 int32_t NSTACKX_SetDeviceListAgingTime(uint32_t agingTime)
1238 {
1239 (void)agingTime;
1240 DFINDER_LOGE(TAG, "device list not supported");
1241 return NSTACKX_EFAILED;
1242 }
1243 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
1244
NSTACKX_ScreenStatusChange(bool isScreenOn)1245 int32_t NSTACKX_ScreenStatusChange(bool isScreenOn)
1246 {
1247 #ifdef DFINDER_SUPPORT_SET_SCREEN_STATUS
1248 SetScreenStatus(isScreenOn);
1249 #else
1250 (void)isScreenOn;
1251 DFINDER_LOGI(TAG, "do not support set screen status");
1252 #endif
1253 return NSTACKX_EOK;
1254 }
1255
RegisterServiceDataInner(void * argument)1256 static void RegisterServiceDataInner(void *argument)
1257 {
1258 char *serviceData = argument;
1259 if (SetLocalDeviceServiceData(serviceData) != NSTACKX_EOK) {
1260 DFINDER_LOGE(TAG, "RegisterServiceData failed");
1261 }
1262 free(serviceData);
1263 }
1264
NSTACKX_RegisterServiceData(const char * serviceData)1265 int32_t NSTACKX_RegisterServiceData(const char *serviceData)
1266 {
1267 Coverity_Tainted_Set((void *)serviceData);
1268
1269 DFINDER_LOGD(TAG, "begin to call NSTACKX_RegisterServiceData");
1270 char *serviceDataTmp = NULL;
1271
1272 if (serviceData == NULL) {
1273 DFINDER_LOGE(TAG, "serviceData is null");
1274 return NSTACKX_EINVAL;
1275 }
1276 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1277 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1278 return NSTACKX_EFAILED;
1279 }
1280 if (strlen(serviceData) >= NSTACKX_MAX_SERVICE_DATA_LEN) {
1281 DFINDER_LOGE(TAG, "serviceData (%u) exceed max number", strlen(serviceData));
1282 return NSTACKX_EINVAL;
1283 }
1284 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1285 return SetLocalDeviceServiceData(serviceData);
1286 }
1287
1288 serviceDataTmp = calloc(1U, NSTACKX_MAX_SERVICE_DATA_LEN);
1289 if (serviceDataTmp == NULL) {
1290 return NSTACKX_ENOMEM;
1291 }
1292 if (strncpy_s(serviceDataTmp, NSTACKX_MAX_SERVICE_DATA_LEN, serviceData, strlen(serviceData)) != EOK) {
1293 DFINDER_LOGE(TAG, "Failed to copy serviceData");
1294 free(serviceDataTmp);
1295 return NSTACKX_EINVAL;
1296 }
1297 if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterServiceDataInner, serviceDataTmp) != NSTACKX_EOK) {
1298 DFINDER_LOGE(TAG, "Failed to register serviceData!");
1299 free(serviceDataTmp);
1300 return NSTACKX_EFAILED;
1301 }
1302
1303 return NSTACKX_EOK;
1304 }
1305
RegisterBusinessDataInner(void * argument)1306 static void RegisterBusinessDataInner(void *argument)
1307 {
1308 DFINDER_LOGI(TAG, "Register Business Data Inner");
1309 char *businessData = argument;
1310 if (SetLocalDeviceBusinessData(businessData, NSTACKX_TRUE) != NSTACKX_EOK) {
1311 DFINDER_LOGE(TAG, "RegisterBusinessData failed");
1312 }
1313 free(businessData);
1314 }
1315
NSTACKX_RegisterBusinessData(const char * businessData)1316 int32_t NSTACKX_RegisterBusinessData(const char *businessData)
1317 {
1318 DFINDER_LOGI(TAG, "begin to call NSTACKX_RegisterBusinessData");
1319
1320 char *businessDataTmp = NULL;
1321 if (businessData == NULL) {
1322 DFINDER_LOGE(TAG, "businessData is null");
1323 return NSTACKX_EINVAL;
1324 }
1325 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1326 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1327 return NSTACKX_EFAILED;
1328 }
1329 if (strlen(businessData) >= NSTACKX_MAX_BUSINESS_DATA_LEN) {
1330 DFINDER_LOGE(TAG, "businessData (%u) exceed max data len", strlen(businessData));
1331 return NSTACKX_EINVAL;
1332 }
1333 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1334 return (int32_t)SetLocalDeviceBusinessData(businessData, NSTACKX_TRUE);
1335 }
1336
1337 businessDataTmp = calloc(1, NSTACKX_MAX_BUSINESS_DATA_LEN);
1338 if (businessDataTmp == NULL) {
1339 DFINDER_LOGE(TAG, "businessDataTmp is null");
1340 return NSTACKX_ENOMEM;
1341 }
1342 if (strncpy_s(businessDataTmp, NSTACKX_MAX_BUSINESS_DATA_LEN, businessData,
1343 strlen(businessData)) != EOK) {
1344 DFINDER_LOGE(TAG, "Failed to copy businessData");
1345 free(businessDataTmp);
1346 return NSTACKX_EFAILED;
1347 }
1348 if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterBusinessDataInner, businessDataTmp) != NSTACKX_EOK) {
1349 DFINDER_LOGE(TAG, "Failed to register businessData!");
1350 free(businessDataTmp);
1351 return NSTACKX_EFAILED;
1352 }
1353
1354 return NSTACKX_EOK;
1355 }
1356
1357 #ifndef DFINDER_USE_MINI_NSTACKX
RegisterExtendServiceDataInner(void * argument)1358 static void RegisterExtendServiceDataInner(void *argument)
1359 {
1360 char *extendServiceData = argument;
1361 if (SetLocalDeviceExtendServiceData(extendServiceData) != NSTACKX_EOK) {
1362 DFINDER_LOGE(TAG, "RegisterExtendServiceData failed");
1363 }
1364 free(extendServiceData);
1365 }
1366 #endif
1367
NSTACKX_RegisterExtendServiceData(const char * extendServiceData)1368 int32_t NSTACKX_RegisterExtendServiceData(const char *extendServiceData)
1369 {
1370 #ifndef DFINDER_USE_MINI_NSTACKX
1371 char *extendServiceDataTmp = NULL;
1372
1373 if (extendServiceData == NULL) {
1374 DFINDER_LOGE(TAG, "extendServiceData is null");
1375 return NSTACKX_EINVAL;
1376 }
1377 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1378 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1379 return NSTACKX_EFAILED;
1380 }
1381 if (strlen(extendServiceData) >= NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN) {
1382 DFINDER_LOGE(TAG, "extendServiceData (%u) exceed max number", strlen(extendServiceData));
1383 return NSTACKX_EINVAL;
1384 }
1385 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1386 return SetLocalDeviceExtendServiceData(extendServiceData);
1387 }
1388
1389 extendServiceDataTmp = calloc(1, NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN);
1390 if (extendServiceDataTmp == NULL) {
1391 return NSTACKX_ENOMEM;
1392 }
1393 if (strncpy_s(extendServiceDataTmp, NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN, extendServiceData,
1394 strlen(extendServiceData)) != EOK) {
1395 DFINDER_LOGE(TAG, "Failed to copy extendServiceData");
1396 free(extendServiceDataTmp);
1397 return NSTACKX_EINVAL;
1398 }
1399 if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterExtendServiceDataInner, extendServiceDataTmp) != NSTACKX_EOK) {
1400 DFINDER_LOGE(TAG, "Failed to register extendServiceData!");
1401 free(extendServiceDataTmp);
1402 return NSTACKX_EFAILED;
1403 }
1404 return NSTACKX_EOK;
1405 #else
1406 (void)extendServiceData;
1407 DFINDER_LOGI(TAG, "NSTACKX_RegisterExtendServiceData not supported");
1408 return NSTACKX_EOK;
1409 #endif
1410 }
1411
1412 #ifndef DFINDER_USE_MINI_NSTACKX
1413 struct DirectMsgCtx {
1414 MsgCtx msg;
1415 const char *ipStr;
1416 struct in_addr ip;
1417 };
1418
SendMsgDirectInner(void * arg)1419 static void SendMsgDirectInner(void *arg)
1420 {
1421 struct DirectMsgCtx *msg = arg;
1422 DFINDER_LOGD(TAG, "Enter WifiDirect send");
1423 msg->msg.err = CoapSendServiceMsg(&msg->msg, msg->ipStr, &msg->ip);
1424 SemPost(&msg->msg.wait);
1425 }
1426
NSTACKX_SendMsgParamCheck(const char * moduleName,const char * deviceId,const uint8_t * data,uint32_t len)1427 static int32_t NSTACKX_SendMsgParamCheck(const char *moduleName, const char *deviceId, const uint8_t *data,
1428 uint32_t len)
1429 {
1430 if (moduleName == NULL || strlen(moduleName) > NSTACKX_MAX_MODULE_NAME_LEN) {
1431 DFINDER_LOGE(TAG, "Invalid module name");
1432 return NSTACKX_EINVAL;
1433 }
1434
1435 if (deviceId == NULL || strlen(deviceId) > NSTACKX_MAX_DEVICE_ID_LEN) {
1436 DFINDER_LOGE(TAG, "Invalid device id");
1437 return NSTACKX_EINVAL;
1438 }
1439
1440 if (data == NULL || len == 0 || len > NSTACKX_MAX_SENDMSG_DATA_LEN) {
1441 DFINDER_LOGE(TAG, "Null data to send");
1442 return NSTACKX_EINVAL;
1443 }
1444 return NSTACKX_EOK;
1445 }
1446
MsgCtxInit(MsgCtx * msg,const char * moduleName,const char * deviceId,const uint8_t * data,uint32_t len)1447 static int MsgCtxInit(MsgCtx *msg, const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len)
1448 {
1449 if (SemInit(&msg->wait, 0, 0)) {
1450 DFINDER_LOGE(TAG, "sem init fail");
1451 return NSTACKX_EFAILED;
1452 }
1453
1454 msg->deviceId = deviceId;
1455 msg->moduleName = moduleName;
1456 msg->data = data;
1457 msg->len = len;
1458 msg->err = NSTACKX_EOK;
1459
1460 return NSTACKX_EOK;
1461 }
1462 #endif
1463
NSTACKX_SendMsgDirect(const char * moduleName,const char * deviceId,const uint8_t * data,uint32_t len,const char * ipaddr,uint8_t type)1464 int32_t NSTACKX_SendMsgDirect(const char *moduleName, const char *deviceId, const uint8_t *data,
1465 uint32_t len, const char *ipaddr, uint8_t type)
1466 {
1467 #ifndef DFINDER_USE_MINI_NSTACKX
1468 int32_t ret = NSTACKX_EOK;
1469 DFINDER_LOGD(TAG, "NSTACKX_SendMsgDirect");
1470 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1471 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1472 return NSTACKX_EFAILED;
1473 }
1474 if (ipaddr == NULL) {
1475 DFINDER_LOGE(TAG, "ipaddr needed");
1476 return NSTACKX_EINVAL;
1477 }
1478
1479 if (type > SERVER_TYPE_USB) {
1480 DFINDER_LOGE(TAG, "invalid type %hhu", type);
1481 return NSTACKX_EINVAL;
1482 }
1483
1484 if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) {
1485 return NSTACKX_EINVAL;
1486 }
1487
1488 struct DirectMsgCtx directMsg;
1489 if (inet_pton(AF_INET, ipaddr, &directMsg.ip) != 1 || directMsg.ip.s_addr == 0) {
1490 DFINDER_LOGE(TAG, "invalid ip addr");
1491 return NSTACKX_EINVAL;
1492 }
1493 directMsg.ipStr = ipaddr;
1494 directMsg.msg.type = type;
1495 if (MsgCtxInit(&directMsg.msg, moduleName, deviceId, data, len) != NSTACKX_EOK) {
1496 return NSTACKX_EFAILED;
1497 }
1498
1499 if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgDirectInner, &directMsg) != NSTACKX_EOK) {
1500 DFINDER_LOGE(TAG, "Failed to send msg");
1501 ret = NSTACKX_EFAILED;
1502 }
1503 if (ret == NSTACKX_EOK) {
1504 SemWait(&directMsg.msg.wait);
1505 ret = directMsg.msg.err;
1506 }
1507 SemDestroy(&directMsg.msg.wait);
1508 return ret;
1509 #else
1510 (void)moduleName;
1511 (void)deviceId;
1512 (void)data;
1513 (void)len;
1514 (void)ipaddr;
1515 (void)type;
1516 DFINDER_LOGI(TAG, "NSTACKX_SendMsgDirect not supported");
1517 return NSTACKX_EFAILED;
1518 #endif
1519 }
1520
1521 #if defined(DFINDER_SAVE_DEVICE_LIST) && !defined(DFINDER_USE_MINI_NSTACKX)
SendMsgInner(void * arg)1522 static void SendMsgInner(void *arg)
1523 {
1524 MsgCtx *msg = arg;
1525 const struct in_addr *remoteIp = GetRemoteDeviceIp(msg->deviceId);
1526 if (remoteIp == NULL) {
1527 DFINDER_LOGE(TAG, "no device found");
1528 msg->err = NSTACKX_EINVAL;
1529 } else {
1530 char ipStr[INET_ADDRSTRLEN] = {0};
1531 if (inet_ntop(AF_INET, remoteIp, ipStr, sizeof(ipStr)) != NULL) {
1532 msg->err = CoapSendServiceMsg(msg, ipStr, remoteIp);
1533 } else {
1534 DFINDER_LOGE(TAG, "ip format failed");
1535 }
1536 }
1537
1538 SemPost(&msg->wait);
1539 }
1540 #endif
1541
NSTACKX_SendMsg(const char * moduleName,const char * deviceId,const uint8_t * data,uint32_t len)1542 int32_t NSTACKX_SendMsg(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len)
1543 {
1544 Coverity_Tainted_Set((void *)moduleName);
1545 Coverity_Tainted_Set((void *)deviceId);
1546 Coverity_Tainted_Set((void *)data);
1547 Coverity_Tainted_Set((void *)&len);
1548 #if defined(DFINDER_SAVE_DEVICE_LIST) && !defined(DFINDER_USE_MINI_NSTACKX)
1549 int32_t ret = NSTACKX_EOK;
1550 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1551 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1552 return NSTACKX_EFAILED;
1553 }
1554 if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) {
1555 return NSTACKX_EINVAL;
1556 }
1557
1558 MsgCtx msg;
1559 msg.type = INVALID_TYPE;
1560 if (MsgCtxInit(&msg, moduleName, deviceId, data, len) != NSTACKX_EOK) {
1561 return NSTACKX_EFAILED;
1562 }
1563
1564 if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgInner, &msg) != NSTACKX_EOK) {
1565 DFINDER_LOGE(TAG, "failed to send msg");
1566 ret = NSTACKX_EFAILED;
1567 }
1568 if (ret == NSTACKX_EOK) {
1569 SemWait(&msg.wait);
1570 ret = msg.err;
1571 }
1572 SemDestroy(&msg.wait);
1573 return ret;
1574 #else
1575 (void)moduleName;
1576 (void)deviceId;
1577 (void)data;
1578 (void)len;
1579 DFINDER_LOGI(TAG, "SendMsg not supported");
1580 return NSTACKX_EFAILED;
1581 #endif
1582 }
1583
SendDiscoveryRspInner(void * arg)1584 static void SendDiscoveryRspInner(void *arg)
1585 {
1586 NSTACKX_ResponseSettings *responseSettings = arg;
1587 SendDiscoveryRsp(responseSettings);
1588 free(responseSettings->businessData);
1589 free(responseSettings);
1590 }
1591
CopyResponseSettings(NSTACKX_ResponseSettings * dupResponseSettings,const NSTACKX_ResponseSettings * responseSettings)1592 static int32_t CopyResponseSettings(NSTACKX_ResponseSettings *dupResponseSettings,
1593 const NSTACKX_ResponseSettings *responseSettings)
1594 {
1595 dupResponseSettings->businessType = responseSettings->businessType;
1596 dupResponseSettings->length = responseSettings->length;
1597 if (responseSettings->businessData != NULL) {
1598 if (strncpy_s(dupResponseSettings->businessData, (dupResponseSettings->length + 1),
1599 responseSettings->businessData, responseSettings->length) != EOK) {
1600 DFINDER_LOGE(TAG, "businessData strncpy failed");
1601 return NSTACKX_EINVAL;
1602 }
1603 }
1604 if (strncpy_s(dupResponseSettings->localNetworkName, NSTACKX_MAX_INTERFACE_NAME_LEN,
1605 responseSettings->localNetworkName, strlen(responseSettings->localNetworkName)) != EOK) {
1606 DFINDER_LOGE(TAG, "localNetworkName strncpy failed");
1607 return NSTACKX_EINVAL;
1608 }
1609 if (strncpy_s(dupResponseSettings->remoteIp, NSTACKX_MAX_IP_STRING_LEN,
1610 responseSettings->remoteIp, strlen(responseSettings->remoteIp)) != EOK) {
1611 DFINDER_LOGE(TAG, "remoteIp strncpy failed");
1612 return NSTACKX_EINVAL;
1613 }
1614 return NSTACKX_EOK;
1615 }
1616
CheckResponseSettings(const NSTACKX_ResponseSettings * responseSettings)1617 static int32_t CheckResponseSettings(const NSTACKX_ResponseSettings *responseSettings)
1618 {
1619 if (responseSettings == NULL) {
1620 DFINDER_LOGE(TAG, "Invalid responseSettings info");
1621 return NSTACKX_EINVAL;
1622 }
1623 if ((responseSettings->businessData == NULL) && (responseSettings->length != 0)) {
1624 DFINDER_LOGE(TAG, "Invalid responseSettings bData info");
1625 return NSTACKX_EINVAL;
1626 }
1627 if (responseSettings->length >= NSTACKX_MAX_BUSINESS_DATA_LEN) {
1628 DFINDER_LOGE(TAG, "businessData length is too long");
1629 return NSTACKX_EINVAL;
1630 }
1631 return NSTACKX_EOK;
1632 }
1633
NSTACKX_SendDiscoveryRsp(const NSTACKX_ResponseSettings * responseSettings)1634 int32_t NSTACKX_SendDiscoveryRsp(const NSTACKX_ResponseSettings *responseSettings)
1635 {
1636 DFINDER_LOGI(TAG, "begin to NSTACKX_SendDiscoveryRsp!");
1637 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1638 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1639 return NSTACKX_EFAILED;
1640 }
1641 if (CheckResponseSettings(responseSettings) != NSTACKX_EOK) {
1642 return NSTACKX_EINVAL;
1643 }
1644
1645 DFINDER_LOGI(TAG, "response settings, business type: %hu, local network name: %s",
1646 responseSettings->businessType, responseSettings->localNetworkName);
1647
1648 NSTACKX_ResponseSettings *dupResponseSettings = malloc(sizeof(NSTACKX_ResponseSettings));
1649 if (dupResponseSettings == NULL) {
1650 DFINDER_LOGE(TAG, "malloc failed");
1651 return NSTACKX_ENOMEM;
1652 }
1653 dupResponseSettings->businessData = (char *)calloc((responseSettings->length + 1), sizeof(char));
1654 if (dupResponseSettings->businessData == NULL) {
1655 DFINDER_LOGE(TAG, "businessData calloc failed");
1656 free(dupResponseSettings);
1657 return NSTACKX_ENOMEM;
1658 }
1659 if (CopyResponseSettings(dupResponseSettings, responseSettings) != NSTACKX_EOK) {
1660 free(dupResponseSettings->businessData);
1661 free(dupResponseSettings);
1662 return NSTACKX_EINVAL;
1663 }
1664
1665 if (PostEvent(&g_eventNodeChain, g_epollfd, SendDiscoveryRspInner, dupResponseSettings) != NSTACKX_EOK) {
1666 DFINDER_LOGE(TAG, "Failed to send responseSettings info!");
1667 free(dupResponseSettings->businessData);
1668 free(dupResponseSettings);
1669 return NSTACKX_EFAILED;
1670 }
1671 return NSTACKX_EOK;
1672 }
1673
1674 #ifdef DFINDER_SAVE_DEVICE_LIST
GetDeviceListInner(void * argument)1675 static void GetDeviceListInner(void *argument)
1676 {
1677 GetDeviceListMessage *message = argument;
1678
1679 GetDeviceList(message->deviceList, message->deviceCountPtr, true);
1680 SemPost(&message->wait);
1681 }
1682 #endif
1683
NSTACKX_GetDeviceList(NSTACKX_DeviceInfo * deviceList,uint32_t * deviceCountPtr)1684 int32_t NSTACKX_GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr)
1685 {
1686 #ifdef DFINDER_SAVE_DEVICE_LIST
1687 GetDeviceListMessage message = {
1688 .deviceList = deviceList,
1689 .deviceCountPtr = deviceCountPtr,
1690 };
1691 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1692 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1693 return NSTACKX_EFAILED;
1694 }
1695 if (deviceList == NULL || deviceCountPtr == NULL) {
1696 DFINDER_LOGE(TAG, "Device list or count pointer is NULL");
1697 return NSTACKX_EINVAL;
1698 }
1699 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1700 GetDeviceList(deviceList, deviceCountPtr, true);
1701 return NSTACKX_EOK;
1702 }
1703 if (SemInit(&message.wait, 0, 0)) {
1704 return NSTACKX_EFAILED;
1705 }
1706 if (PostEvent(&g_eventNodeChain, g_epollfd, GetDeviceListInner, &message) != NSTACKX_EOK) {
1707 DFINDER_LOGE(TAG, "Failed to get device list");
1708 SemDestroy(&message.wait);
1709 return NSTACKX_EFAILED;
1710 }
1711 SemWait(&message.wait);
1712 SemDestroy(&message.wait);
1713 return NSTACKX_EOK;
1714 #else
1715 (void)deviceList;
1716 (void)deviceCountPtr;
1717
1718 DFINDER_LOGE(TAG, "device list not supported");
1719
1720 return NSTACKX_EFAILED;
1721 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
1722 }
1723
NotifyDeviceListChanged(const NSTACKX_DeviceInfo * deviceList,uint32_t deviceCount)1724 void NotifyDeviceListChanged(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
1725 {
1726 if (g_parameter.onDeviceListChanged != NULL) {
1727 DFINDER_LOGI(TAG, "notify callback: device list changed");
1728 g_parameter.onDeviceListChanged(deviceList, deviceCount);
1729 DFINDER_LOGI(TAG, "finish to notify device list changed");
1730 } else {
1731 DFINDER_LOGI(TAG, "notify callback: device list changed callback is null");
1732 }
1733 }
1734
NotifyDeviceFound(const NSTACKX_DeviceInfo * deviceList,uint32_t deviceCount)1735 void NotifyDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
1736 {
1737 if (g_parameter.onDeviceFound != NULL) {
1738 DFINDER_LOGI(TAG, "notify callback: device found");
1739 g_parameter.onDeviceFound(deviceList, deviceCount);
1740 DFINDER_LOGI(TAG, "finish to notify device found");
1741 } else {
1742 DFINDER_LOGI(TAG, "notify callback: device found callback is null");
1743 }
1744 }
1745
NotificationReceived(const NSTACKX_NotificationConfig * notification)1746 void NotificationReceived(const NSTACKX_NotificationConfig *notification)
1747 {
1748 if (g_parameter.onNotificationReceived != NULL) {
1749 DFINDER_LOGI(TAG, "notify callback: notification received");
1750 g_parameter.onNotificationReceived(notification);
1751 DFINDER_LOGI(TAG, "finish to notify notification received");
1752 } else {
1753 DFINDER_LOGI(TAG, "notify callback: notification received callback is null");
1754 }
1755 }
1756
1757 #ifndef DFINDER_USE_MINI_NSTACKX
NotifyMsgReceived(const char * moduleName,const char * deviceId,const uint8_t * data,uint32_t len,const char * srcIp)1758 void NotifyMsgReceived(const char *moduleName, const char *deviceId, const uint8_t *data,
1759 uint32_t len, const char *srcIp)
1760 {
1761 if (g_parameter.onMsgReceived != NULL) {
1762 DFINDER_LOGI(TAG, "notify callback: message received, data length %u", len);
1763 g_parameter.onMsgReceived(moduleName, deviceId, data, len, srcIp);
1764 DFINDER_LOGI(TAG, "finish to notify msg received");
1765 } else {
1766 DFINDER_LOGI(TAG, "notify callback: message received callback is null");
1767 }
1768 }
1769
NSTACKX_InitRestart(const NSTACKX_Parameter * parameter)1770 int32_t NSTACKX_InitRestart(const NSTACKX_Parameter *parameter)
1771 {
1772 Coverity_Tainted_Set((void *)parameter);
1773
1774 #if defined(_WIN32) || defined(DFINDER_USE_MINI_NSTACKX)
1775 DFINDER_LOGE(TAG, "do not support init restart");
1776 (void)parameter;
1777 return NSTACKX_EFAILED;
1778 #else
1779 DFINDER_LOGI(TAG, "NSTACKX_InitRestart");
1780 int32_t ret = NSTACKX_Init(parameter);
1781 if (ret == NSTACKX_EOK) {
1782 if (PostEvent(&g_eventNodeChain, g_epollfd, DetectLocalIface, NULL) != NSTACKX_EOK) {
1783 DFINDER_LOGE(TAG, "Failed to GetLocalNetworkInterface");
1784 }
1785 }
1786 return ret;
1787 #endif
1788 }
1789
DeviceDiscoverInnerRestart(void * argument)1790 static void DeviceDiscoverInnerRestart(void *argument)
1791 {
1792 (void)argument;
1793 CoapServiceDiscoverInner(NSTACKX_FALSE);
1794 }
1795
NSTACKX_StartDeviceFindRestart(void)1796 void NSTACKX_StartDeviceFindRestart(void)
1797 {
1798 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1799 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1800 return;
1801 }
1802 DFINDER_LOGI(TAG, "start device find for restart");
1803 if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerRestart, NULL) != NSTACKX_EOK) {
1804 DFINDER_LOGE(TAG, "Failed to start device discover!");
1805 return;
1806 }
1807 return;
1808 }
1809 #endif /* END OF DFINDER_USE_MINI_NSTACKX */
1810
1811 #ifdef ENABLE_USER_LOG
NSTACKX_DFinderRegisterLog(DFinderLogCallback userLogCallback)1812 int32_t NSTACKX_DFinderRegisterLog(DFinderLogCallback userLogCallback)
1813 {
1814 if (userLogCallback == NULL) {
1815 DFINDER_LOGE(TAG, "logImpl null");
1816 return NSTACKX_EFAILED;
1817 }
1818 int32_t ret = SetLogCallback(userLogCallback);
1819 return ret;
1820 }
1821 #endif
1822
1823 #ifdef NSTACKX_DFINDER_HIDUMP
1824 #define MAX_DUMP_ARGC 10
NSTACKX_DFinderDump(const char ** argv,uint32_t argc,void * softObj,DFinderDumpFunc dump)1825 int NSTACKX_DFinderDump(const char **argv, uint32_t argc, void *softObj, DFinderDumpFunc dump)
1826 {
1827 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1828 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1829 return NSTACKX_EFAILED;
1830 }
1831
1832 if (dump == NULL) {
1833 DFINDER_LOGE(TAG, "dump is null");
1834 return NSTACKX_EINVAL;
1835 }
1836
1837 if (argc == 0 || argc > MAX_DUMP_ARGC) {
1838 DFINDER_LOGE(TAG, "argc is invalid %u", argc);
1839 return NSTACKX_EINVAL;
1840 }
1841
1842 if (argv == NULL) {
1843 DFINDER_LOGE(TAG, "argv is null");
1844 return NSTACKX_EINVAL;
1845 }
1846
1847 uint32_t i;
1848 for (i = 0; i < argc; i++) {
1849 if (argv[i] == NULL) {
1850 DFINDER_LOGE(TAG, "argv[%u] is null", i);
1851 return NSTACKX_EINVAL;
1852 }
1853 }
1854
1855 return DFinderDump(argv, argc, softObj, dump);
1856 }
1857 #else
NSTACKX_DFinderDump(const char ** argv,uint32_t argc,void * softObj,DFinderDumpFunc dump)1858 int NSTACKX_DFinderDump(const char **argv, uint32_t argc, void *softObj, DFinderDumpFunc dump)
1859 {
1860 (void)argv;
1861 (void)argc;
1862 (void)softObj;
1863 (void)dump;
1864 DFINDER_LOGE(TAG, "unsupport dfinder dump");
1865 return NSTACKX_NOTSUPPORT;
1866 }
1867 #endif
1868
NSTACKX_DFinderSetEventFunc(void * softobj,DFinderEventFunc func)1869 int NSTACKX_DFinderSetEventFunc(void *softobj, DFinderEventFunc func)
1870 {
1871 if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
1872 DFINDER_LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
1873 return NSTACKX_EFAILED;
1874 }
1875 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1876 return SetEventFuncDirectly(softobj, func);
1877 }
1878
1879 return SetEventFunc(softobj, func);
1880 }
1881
CheckNotificationConfig(const NSTACKX_NotificationConfig * config)1882 static int32_t CheckNotificationConfig(const NSTACKX_NotificationConfig *config)
1883 {
1884 if (config == NULL) {
1885 DFINDER_LOGE(TAG, "notification config passed in is null");
1886 return NSTACKX_EINVAL;
1887 }
1888 if (config->businessType >= NSTACKX_BUSINESS_TYPE_MAX) {
1889 DFINDER_LOGE(TAG, "invalid business type %hhu in notification config", config->businessType);
1890 return NSTACKX_EINVAL;
1891 }
1892 if (config->msg == NULL) {
1893 DFINDER_LOGE(TAG, "msg in notification config is null");
1894 return NSTACKX_EINVAL;
1895 }
1896 if (strlen(config->msg) != config->msgLen || config->msgLen == 0 ||
1897 config->msgLen >= NSTACKX_MAX_NOTIFICATION_DATA_LEN) {
1898 DFINDER_LOGE(TAG, "actual msg len %zu, msg len %zu in config", strlen(config->msg), config->msgLen);
1899 return NSTACKX_EINVAL;
1900 }
1901 // advertise count: [0, 100], first interval in intervalMs should be 0
1902 if (config->intervalLen == 0 || config->intervalLen > NSTACKX_MAX_ADVERTISE_COUNT) {
1903 DFINDER_LOGE(TAG, "invalid interval len %hhu in notification config, max support %d",
1904 config->intervalLen, NSTACKX_MAX_ADVERTISE_COUNT);
1905 return NSTACKX_EINVAL;
1906 }
1907 if (config->intervalsMs == NULL) {
1908 DFINDER_LOGE(TAG, "broadcast intervals in notification config is null");
1909 return NSTACKX_EINVAL;
1910 }
1911 // interval: [0 ms, 10000 ms]
1912 if (config->intervalsMs[0] != 0) {
1913 DFINDER_LOGE(TAG, "first interval should be 0 to indicate send notification immediately");
1914 return NSTACKX_EINVAL;
1915 }
1916 for (size_t i = 1; i < config->intervalLen; ++i) {
1917 if (config->intervalsMs[i] < NSTACKX_MIN_ADVERTISE_INTERVAL ||
1918 config->intervalsMs[i] > NSTACKX_MAX_ADVERTISE_INTERVAL) {
1919 DFINDER_LOGE(TAG, "invalid interval[%zu] = %hu, support max: %d min: %d",
1920 i, config->intervalsMs[i], NSTACKX_MAX_ADVERTISE_INTERVAL, NSTACKX_MIN_ADVERTISE_INTERVAL);
1921 return NSTACKX_EINVAL;
1922 }
1923 }
1924 return NSTACKX_EOK;
1925 }
1926
CopyNotificationConfig(NSTACKX_NotificationConfig * dst,const NSTACKX_NotificationConfig * src)1927 static int32_t CopyNotificationConfig(NSTACKX_NotificationConfig *dst, const NSTACKX_NotificationConfig *src)
1928 {
1929 dst->businessType = src->businessType;
1930 if (strncpy_s(dst->msg, src->msgLen + 1, src->msg, src->msgLen) != EOK) {
1931 DFINDER_LOGE(TAG, "copy notification msg to duplicated one fail");
1932 return NSTACKX_EFAILED;
1933 }
1934 dst->msgLen = src->msgLen;
1935 for (size_t i = 0; i < src->intervalLen; ++i) {
1936 (dst->intervalsMs)[i] = (src->intervalsMs)[i];
1937 }
1938 dst->intervalLen = src->intervalLen;
1939 return NSTACKX_EOK;
1940 }
1941
NotificationInner(void * argument)1942 static void NotificationInner(void *argument)
1943 {
1944 NSTACKX_NotificationConfig *config = (NSTACKX_NotificationConfig *)argument;
1945 int32_t retMsg = LocalizeNotificationMsg(config->msg);
1946 int32_t retInterval = LocalizeNotificationInterval(config->intervalsMs, config->intervalLen);
1947 free(config->intervalsMs);
1948 free(config->msg);
1949 free(config);
1950 if (retMsg != NSTACKX_EOK || retInterval != NSTACKX_EOK) {
1951 DFINDER_LOGE(TAG, "stop running service notification cause localize config fail");
1952 return;
1953 }
1954 CoapServiceNotification();
1955 }
1956
NSTACKX_SendNotification(const NSTACKX_NotificationConfig * config)1957 int32_t NSTACKX_SendNotification(const NSTACKX_NotificationConfig *config)
1958 {
1959 DFINDER_LOGI(TAG, "begin to call NSTACKX_SendNotification");
1960
1961 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
1962 DFINDER_LOGE(TAG, "dfinder not inited");
1963 return NSTACKX_EFAILED;
1964 }
1965 if (CheckNotificationConfig(config) != NSTACKX_EOK) {
1966 return NSTACKX_EINVAL;
1967 }
1968 NSTACKX_NotificationConfig *dupConfig = (NSTACKX_NotificationConfig *)calloc(1, sizeof(NSTACKX_NotificationConfig));
1969 if (dupConfig == NULL) {
1970 DFINDER_LOGE(TAG, "calloc for notification config fail, size wanted: %zu", sizeof(NSTACKX_NotificationConfig));
1971 return NSTACKX_ENOMEM;
1972 }
1973 dupConfig->msg = (char *)calloc((config->msgLen + 1), sizeof(char));
1974 if (dupConfig->msg == NULL) {
1975 DFINDER_LOGE(TAG, "calloc for msg in notification fail, size wanted: %zu", config->msgLen + 1);
1976 free(dupConfig);
1977 return NSTACKX_ENOMEM;
1978 }
1979 dupConfig->intervalsMs = (uint16_t *)calloc(config->intervalLen, sizeof(uint16_t));
1980 if (dupConfig->intervalsMs == NULL) {
1981 DFINDER_LOGE(TAG, "calloc for intervals fail, size wanted: %zu", sizeof(uint16_t) * (config->intervalLen));
1982 free(dupConfig->msg);
1983 free(dupConfig);
1984 return NSTACKX_ENOMEM;
1985 }
1986 if (CopyNotificationConfig(dupConfig, config) != NSTACKX_EOK) {
1987 free(dupConfig->intervalsMs);
1988 free(dupConfig->msg);
1989 free(dupConfig);
1990 return NSTACKX_EFAILED;
1991 }
1992 if (PostEvent(&g_eventNodeChain, g_epollfd, NotificationInner, dupConfig) != NSTACKX_EOK) {
1993 DFINDER_LOGE(TAG, "post event failed to run notification inner");
1994 free(dupConfig->intervalsMs);
1995 free(dupConfig->msg);
1996 free(dupConfig);
1997 return NSTACKX_EFAILED;
1998 }
1999 return NSTACKX_EOK;
2000 }
2001
NotificationStop(void * argument)2002 static void NotificationStop(void *argument)
2003 {
2004 (void)argument;
2005 CoapServiceNotificationStop();
2006 }
2007
NSTACKX_StopSendNotification(uint8_t businessType)2008 int32_t NSTACKX_StopSendNotification(uint8_t businessType)
2009 {
2010 DFINDER_LOGI(TAG, "begin to call NSTACKX_StopSendNotification, business type: %hhu", businessType);
2011
2012 if (g_nstackThreadInitState != NSTACKX_INIT_STATE_DONE) {
2013 DFINDER_LOGE(TAG, "dfinder not inited");
2014 return NSTACKX_EFAILED;
2015 }
2016 if (businessType >= NSTACKX_BUSINESS_TYPE_MAX) {
2017 DFINDER_LOGE(TAG, "invalid business type %hhu to stop send notification", businessType);
2018 return NSTACKX_EINVAL;
2019 }
2020 if (PostEvent(&g_eventNodeChain, g_epollfd, NotificationStop, NULL) != NSTACKX_EOK) {
2021 DFINDER_LOGE(TAG, "post event failed to run stop device discover");
2022 return NSTACKX_EFAILED;
2023 }
2024 return NSTACKX_EOK;
2025 }
2026