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 "coap_discover.h"
17
18 #include <errno.h>
19 #include <string.h>
20
21 #include "coap_adapter.h"
22 #include "coap_app.h"
23 #include "json_payload.h"
24 #include "lwip/sockets.h"
25 #include "nstackx_device.h"
26 #include "nstackx_error.h"
27 #include "nstackx_dfinder_log.h"
28 #include "nstackx_timer.h"
29 #include "securec.h"
30 #include "nstackx_statistics.h"
31 #include "nstackx_device_local.h"
32 #include "nstackx_device_remote.h"
33
34 #define TAG "nStackXCoAP"
35
36 #define COAP_URI_BUFFER_LENGTH 64 /* the size of the buffer or variable used to save uri. */
37
38 /*
39 * 1st discover interval: 100ms
40 * 2nd ~ 3rd discover interval: 200ms
41 * Remaining discover interval (9 times): 500ms
42 */
43 #define COAP_DEFAULT_DISCOVER_COUNT 12
44 #define COAP_FIRST_DISCOVER_COUNT_RANGE 1
45 #define COAP_SECOND_DISCOVER_COUNT_RANGE 3
46 #define COAP_FIRST_DISCOVER_INTERVAL 100
47 #define COAP_SECOND_DISCOVER_INTERVAL 200
48 #define COAP_LAST_DISCOVER_INTERVAL 500
49
50 static Timer *g_discoverTimer = NULL;
51 static uint32_t g_discoverCount;
52 static uint32_t g_coapMaxDiscoverCount = COAP_DEFAULT_DISCOVER_COUNT;
53 static uint32_t g_coapDiscoverType = COAP_BROADCAST_TYPE_DEFAULT;
54 static uint32_t g_coapUserMaxDiscoverCount;
55 static uint32_t g_coapUserDiscoverInterval;
56 static uint32_t *g_coapIntervalArr = NULL;
57 static uint32_t g_coapDiscoverTargetCount;
58 static uint8_t g_userRequest;
59 static uint8_t g_forceUpdate;
60
HndPostServiceDiscoverInner(const uint8_t * buf,size_t size,char ** remoteUrl,DeviceInfo * deviceInfo)61 static int32_t HndPostServiceDiscoverInner(const uint8_t *buf, size_t size, char **remoteUrl, DeviceInfo *deviceInfo)
62 {
63 if (GetServiceDiscoverInfo(buf, size, deviceInfo, remoteUrl) != NSTACKX_EOK) {
64 return NSTACKX_EFAILED;
65 }
66 /* receive coap broadcast, set peer device's discovery type to passive,
67 * to identify the local device is in passive discovery
68 */
69 deviceInfo->discoveryType = (*remoteUrl != NULL) ? NSTACKX_DISCOVERY_TYPE_PASSIVE : NSTACKX_DISCOVERY_TYPE_ACTIVE;
70 if (deviceInfo->mode == PUBLISH_MODE_UPLINE || deviceInfo->mode == PUBLISH_MODE_OFFLINE) {
71 DFINDER_LOGD(TAG, "peer is not DISCOVER_MODE");
72 size_t deviceListLen = sizeof(NSTACKX_DeviceInfo) * PUBLISH_DEVICE_NUM;
73 NSTACKX_DeviceInfo *deviceList = (NSTACKX_DeviceInfo *)malloc(deviceListLen);
74 if (deviceList == NULL) {
75 DFINDER_LOGE(TAG, "malloc device list failed");
76 return NSTACKX_ENOMEM;
77 }
78 (void)memset_s(deviceList, deviceListLen, 0, deviceListLen);
79 if (GetNotifyDeviceInfo(deviceList, deviceInfo) == NSTACKX_EOK) {
80 NotifyDeviceFound(deviceList, PUBLISH_DEVICE_NUM);
81 } else {
82 DFINDER_LOGE(TAG, "GetNotifyDeviceInfo failed");
83 }
84 free(deviceList);
85 return NSTACKX_EFAILED;
86 }
87 return NSTACKX_EOK;
88 }
89
GetBuildCoapParam(const CoapPacket * pkt,const char * remoteUrl,const char * remoteIp,CoapBuildParam * param)90 static void GetBuildCoapParam(const CoapPacket *pkt, const char *remoteUrl, const char *remoteIp, CoapBuildParam *param)
91 {
92 param->remoteIp = remoteIp;
93 param->uriPath = COAP_DEVICE_DISCOVER_URI;
94 if (remoteUrl != NULL) {
95 param->msgType = COAP_TYPE_CON;
96 param->methodType = COAP_METHOD_POST;
97 param->msgId = CoapSoftBusMsgId();
98 } else {
99 param->msgType = COAP_TYPE_ACK;
100 param->methodType = COAP_RESPONSE_201;
101 param->msgId = pkt->header.varSection.msgId;
102 }
103 }
104
105 /* this is a tmp func */
CreateUnicastCoapParam(const char * remoteUrl,const char * remoteIp,CoapBuildParam * param)106 static int32_t CreateUnicastCoapParam(const char *remoteUrl, const char *remoteIp, CoapBuildParam *param)
107 {
108 if ((remoteUrl == NULL) || (remoteIp == NULL)) {
109 return NSTACKX_EFAILED;
110 }
111 param->remoteIp = remoteIp;
112 param->uriPath = COAP_DEVICE_DISCOVER_URI;
113 param->msgType = COAP_TYPE_CON;
114 param->methodType = COAP_METHOD_POST;
115 param->msgId = CoapSoftBusMsgId();
116 return NSTACKX_EOK;
117 }
118
CoapResponseServiceDiscovery(const char * remoteUrl,const CoapPacket * pkt,const struct in_addr * ip,uint8_t businessType)119 static void CoapResponseServiceDiscovery(const char *remoteUrl, const CoapPacket *pkt,
120 const struct in_addr *ip, uint8_t businessType)
121 {
122 char wifiIpAddr[NSTACKX_MAX_IP_STRING_LEN] = {0};
123 CoapBuildParam param = {0};
124 (void)inet_ntop(AF_INET, ip, wifiIpAddr, sizeof(wifiIpAddr));
125 GetBuildCoapParam(pkt, remoteUrl, wifiIpAddr, ¶m);
126 if (remoteUrl != NULL) {
127 if (CheckBusinessTypeReplyUnicast(businessType) == NSTACKX_EOK) {
128 (void)CoapSendMessage(¶m, NSTACKX_FALSE, businessType, false);
129 }
130 } else {
131 (void)CoapSendMessage(¶m, NSTACKX_FALSE, businessType, true);
132 }
133 }
134
HndPostServiceDiscoverEx(const CoapPacket * pkt)135 static int32_t HndPostServiceDiscoverEx(const CoapPacket *pkt)
136 {
137 int32_t ret = NSTACKX_EFAILED;
138 if (pkt == NULL) {
139 return ret;
140 }
141
142 const CoapCtxType *coapCtx = CoapGetCoapCtxType();
143 if (coapCtx == NULL) {
144 DFINDER_LOGE(TAG, "get coap ctx type failed");
145 return ret;
146 }
147
148 char *remoteUrl = NULL;
149 DeviceInfo *deviceInfo = (DeviceInfo *)calloc(1, sizeof(DeviceInfo));
150 if (deviceInfo == NULL) {
151 DFINDER_LOGE(TAG, "malloc device info failed");
152 return ret;
153 }
154
155 if (strcpy_s(deviceInfo->networkName, sizeof(deviceInfo->networkName),
156 GetLocalIfaceName(coapCtx->iface)) != EOK) {
157 DFINDER_LOGE(TAG, "copy network name failed");
158 goto FAIL;
159 }
160
161 if (HndPostServiceDiscoverInner(pkt->payload.buffer, pkt->payload.len, &remoteUrl, deviceInfo) != NSTACKX_EOK) {
162 goto FAIL;
163 }
164 if (GetModeInfo() == PUBLISH_MODE_UPLINE || GetModeInfo() == PUBLISH_MODE_OFFLINE) {
165 DFINDER_LOGD(TAG, "local is not DISCOVER_MODE");
166 goto FAIL;
167 }
168 #ifdef DFINDER_SAVE_DEVICE_LIST
169 uint8_t receiveBcast = (remoteUrl == NULL) ? NSTACKX_FALSE : NSTACKX_TRUE;
170 if (UpdateDeviceDb(coapCtx, deviceInfo, g_forceUpdate, receiveBcast) != NSTACKX_EOK)
171 #else
172 if (DeviceInfoNotify(&deviceInfo) != NSTACKX_EOK)
173 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
174 {
175 goto FAIL;
176 }
177 g_forceUpdate = NSTACKX_FALSE;
178 if (deviceInfo->mode == PUBLISH_MODE_PROACTIVE) {
179 DFINDER_LOGD(TAG, "peer is PUBLISH_MODE_PROACTIVE");
180 goto FAIL;
181 }
182
183 CoapResponseServiceDiscovery(remoteUrl, pkt, &deviceInfo->netChannelInfo.wifiApInfo.ip, deviceInfo->businessType);
184
185 ret = NSTACKX_EOK;
186 FAIL:
187 free(remoteUrl);
188 free(deviceInfo);
189 return ret;
190 }
191
HndPostServiceDiscover(const CoapPacket * pkt)192 void HndPostServiceDiscover(const CoapPacket *pkt)
193 {
194 if (HndPostServiceDiscoverEx(pkt) != NSTACKX_EOK) {
195 IncStatistics(STATS_HANDLE_DEVICE_DISCOVER_MSG_FAILED);
196 }
197 }
198
GetUserDefineInterval(uint32_t discoverCount)199 static uint32_t GetUserDefineInterval(uint32_t discoverCount)
200 {
201 if (discoverCount >= (g_coapMaxDiscoverCount - 1)) {
202 DFINDER_LOGD(TAG, "discover end");
203 return NSTACKX_EOK;
204 }
205 return g_coapIntervalArr[discoverCount];
206 }
207
GetDiscoverInterval(uint32_t discoverCount)208 static uint32_t GetDiscoverInterval(uint32_t discoverCount)
209 {
210 switch (g_coapDiscoverType) {
211 case COAP_BROADCAST_TYPE_USER:
212 return g_coapUserDiscoverInterval;
213 case COAP_BROADCAST_TYPE_USER_DEFINE_INTERVAL:
214 return GetUserDefineInterval(discoverCount);
215 case COAP_BROADCAST_TYPE_DEFAULT:
216 return GetDefaultDiscoverInterval(discoverCount);
217 default:
218 return GetDefaultDiscoverInterval(discoverCount);
219 }
220 }
221
CoapServiceDiscoverStop(void)222 static void CoapServiceDiscoverStop(void)
223 {
224 g_discoverCount = 0;
225 g_forceUpdate = NSTACKX_FALSE;
226 SetModeInfo(DISCOVER_MODE);
227 #ifdef DFINDER_SAVE_DEVICE_LIST
228 ClearRemoteDeviceListBackup();
229 DFINDER_LOGW(TAG, "clear device list backup");
230 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
231 g_coapDiscoverType = COAP_BROADCAST_TYPE_DEFAULT;
232 g_coapMaxDiscoverCount = COAP_DEFAULT_DISCOVER_COUNT;
233 /* Can call PostDeviceFindWrapper() to notify user if needed. */
234 g_userRequest = NSTACKX_FALSE;
235 // release interval array
236 if (g_coapIntervalArr != NULL) {
237 free(g_coapIntervalArr);
238 g_coapIntervalArr = NULL;
239 }
240 }
241
CoapPostServiceDiscoverEx()242 static int32_t CoapPostServiceDiscoverEx()
243 {
244 char ipString[NSTACKX_MAX_IP_STRING_LEN] = {0};
245 char *ifName = CoapGetLocalIfaceName();
246 if (ifName == NULL) {
247 DFINDER_LOGE(TAG, "get ifname failed");
248 return NSTACKX_EFAILED;
249 }
250 struct ifreq ifr;
251 if (strncpy_s(ifr.ifr_name, sizeof(ifr.ifr_name), ifName, strlen(ifName)) != EOK) {
252 DFINDER_LOGE(TAG, "copy netIfName:%s fail", ifName);
253 return NSTACKX_EFAILED;
254 }
255 int32_t fd = socket(AF_INET, SOCK_DGRAM, 0);
256 if (fd < 0) {
257 DFINDER_LOGE(TAG, "create socket fd failed, errno = %d", errno);
258 return NSTACKX_EFAILED;
259 }
260 if (lwip_ioctl(fd, SIOCGIFBRDADDR, (char*)&ifr) < 0) {
261 DFINDER_LOGE(TAG, "ioctl fail, errno = %d", errno);
262 lwip_close(fd);
263 fd = -1;
264 return NSTACKX_EFAILED;
265 }
266 lwip_close(fd);
267 fd = -1;
268 if (inet_ntop(AF_INET, &(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr), ipString, sizeof(ipString)) == NULL) {
269 DFINDER_LOGE(TAG, "convert address from binary to text failed");
270 return NSTACKX_EFAILED;
271 }
272 CoapBuildParam param = {0};
273 param.remoteIp = ipString;
274 param.uriPath = COAP_DEVICE_DISCOVER_URI;
275 param.msgType = COAP_TYPE_NONCON;
276 param.methodType = COAP_METHOD_POST;
277 param.msgId = CoapSoftBusMsgId();
278 if (CoapSendMessage(¶m, NSTACKX_TRUE, GetLocalDeviceBusinessType(), false) != NSTACKX_EOK) {
279 DFINDER_LOGE(TAG, "coap broadcast failed");
280 return NSTACKX_EFAILED;
281 }
282 return NSTACKX_EOK;
283 }
284
CoapPostServiceDiscover(void)285 static int32_t CoapPostServiceDiscover(void)
286 {
287 if (CoapPostServiceDiscoverEx() != NSTACKX_EOK) {
288 DFINDER_LOGE(TAG, "no iface send request");
289 IncStatistics(STATS_POST_SD_REQUEST_FAILED);
290 return NSTACKX_EFAILED;
291 }
292
293 return NSTACKX_EOK;
294 }
295
CoapServiceDiscoverTimerHandle(void * argument)296 static void CoapServiceDiscoverTimerHandle(void *argument)
297 {
298 uint32_t discoverInterval;
299
300 (void)argument;
301
302 if (g_discoverCount >= g_coapDiscoverTargetCount || !IsCoapContextReady()) {
303 /* Discover done, or wifi AP disconnected. */
304 CoapServiceDiscoverStop();
305 return;
306 }
307
308 if (CoapPostServiceDiscover() != NSTACKX_EOK) {
309 DFINDER_LOGE(TAG, "failed to post service discover request");
310 goto L_ERR_SERVICE_DISCOVER;
311 }
312 DFINDER_LOGI(TAG, "the %u times for device discover.", g_discoverCount + 1);
313
314 /* Restart timer */
315 discoverInterval = GetDiscoverInterval(g_discoverCount);
316
317 ++g_discoverCount;
318 if (TimerSetTimeout(g_discoverTimer, discoverInterval, NSTACKX_FALSE) != NSTACKX_EOK) {
319 DFINDER_LOGE(TAG, "failed to set timer for service discover");
320 goto L_ERR_SERVICE_DISCOVER;
321 }
322 return;
323
324 L_ERR_SERVICE_DISCOVER:
325 /* Abort service discover by not starting timer. */
326 DFINDER_LOGE(TAG, "abort service discover, have tried %u request", g_discoverCount);
327 /* Reset g_discoverCount to allow new request from user. */
328 g_discoverCount = 0;
329 }
330
SetCoapMaxDiscoverCount(void)331 static void SetCoapMaxDiscoverCount(void)
332 {
333 switch (g_coapDiscoverType) {
334 case COAP_BROADCAST_TYPE_DEFAULT:
335 g_coapMaxDiscoverCount = COAP_DEFAULT_DISCOVER_COUNT;
336 break;
337 case COAP_BROADCAST_TYPE_USER:
338 case COAP_BROADCAST_TYPE_USER_DEFINE_INTERVAL:
339 g_coapMaxDiscoverCount = g_coapUserMaxDiscoverCount;
340 break;
341 default:
342 g_coapMaxDiscoverCount = COAP_DEFAULT_DISCOVER_COUNT;
343 break;
344 }
345 }
346
CoapServiceDiscoverFirstTime(void)347 static void CoapServiceDiscoverFirstTime(void)
348 {
349 SetCoapMaxDiscoverCount();
350 g_coapDiscoverTargetCount = g_coapMaxDiscoverCount;
351 if (CoapPostServiceDiscover() != NSTACKX_EOK) {
352 DFINDER_LOGE(TAG, "failed to post service discover request");
353 return;
354 }
355
356 uint32_t discoverInterval = GetDiscoverInterval(g_discoverCount);
357 if (TimerSetTimeout(g_discoverTimer, discoverInterval, NSTACKX_FALSE) != NSTACKX_EOK) {
358 DFINDER_LOGE(TAG, "failed to set timer for service discover");
359 return;
360 }
361 ++g_discoverCount;
362 DFINDER_LOGI(TAG, "the first time for device discover.");
363 }
364
CoapServiceDiscoverInner(uint8_t userRequest)365 void CoapServiceDiscoverInner(uint8_t userRequest)
366 {
367 if (!IsCoapContextReady()) {
368 IncStatistics(STATS_START_SD_FAILED);
369 DFINDER_LOGI(TAG, "Network not connected when discovery inner for mini");
370 return;
371 }
372
373 if (userRequest) {
374 DFINDER_LOGD(TAG, "user request for discovery inner");
375 g_userRequest = NSTACKX_TRUE;
376 g_forceUpdate = NSTACKX_TRUE;
377 }
378
379 if (g_coapDiscoverTargetCount > 0 && g_discoverCount >= g_coapDiscoverTargetCount) {
380 g_discoverCount = 0;
381 SetModeInfo(DISCOVER_MODE);
382 #ifdef DFINDER_SAVE_DEVICE_LIST
383 DFINDER_LOGW(TAG, "clear device list backup for mini");
384 ClearRemoteDeviceListBackup();
385 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
386 TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE);
387 }
388
389 if (g_discoverCount) {
390 /* Service discover is ongoing, return. */
391 return;
392 }
393 #ifdef DFINDER_SAVE_DEVICE_LIST
394 /* First discover */
395 BackupRemoteDeviceList();
396 DFINDER_LOGW(TAG, "clear device list");
397 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
398 SetModeInfo(DISCOVER_MODE);
399 CoapServiceDiscoverFirstTime();
400 }
401
CoapServiceDiscoverInnerAn(uint8_t userRequest)402 void CoapServiceDiscoverInnerAn(uint8_t userRequest)
403 {
404 if (!IsCoapContextReady()) {
405 IncStatistics(STATS_START_SD_FAILED);
406 return;
407 }
408
409 if (userRequest) {
410 g_userRequest = NSTACKX_TRUE;
411 }
412
413 if (g_discoverCount != 0) {
414 g_discoverCount = 0;
415 /* Service discover is ongoing, reset. */
416 TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE);
417 }
418 CoapServiceDiscoverFirstTime();
419 }
420
CoapServiceDiscoverInnerConfigurable(uint8_t userRequest)421 void CoapServiceDiscoverInnerConfigurable(uint8_t userRequest)
422 {
423 if (!IsCoapContextReady()) {
424 IncStatistics(STATS_START_SD_FAILED);
425 DFINDER_LOGI(TAG, "Network not connected when discovery inner for configurable");
426 return;
427 }
428
429 if (userRequest) {
430 DFINDER_LOGD(TAG, "user request for discovery configurable");
431 g_userRequest = NSTACKX_TRUE;
432 g_forceUpdate = NSTACKX_TRUE;
433 }
434
435 if (g_coapDiscoverTargetCount > 0 && g_discoverCount >= g_coapDiscoverTargetCount) {
436 g_discoverCount = 0;
437 #ifdef DFINDER_SAVE_DEVICE_LIST
438 ClearRemoteDeviceListBackup();
439 DFINDER_LOGW(TAG, "clear device list backup");
440 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
441 TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE);
442 }
443
444 if (g_discoverCount != 0) {
445 g_discoverCount = 0;
446 /* Service discover is ongoing, return. */
447 TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE);
448 }
449 #ifdef DFINDER_SAVE_DEVICE_LIST
450 /* First discover */
451 BackupRemoteDeviceList();
452 DFINDER_LOGW(TAG, "clear device list");
453 #endif /* END OF DFINDER_SAVE_DEVICE_LIST */
454 CoapServiceDiscoverFirstTime();
455 }
456
CoapServiceDiscoverStopInner(void)457 void CoapServiceDiscoverStopInner(void)
458 {
459 TimerSetTimeout(g_discoverTimer, 0, NSTACKX_FALSE);
460 CoapServiceDiscoverStop();
461 DFINDER_LOGI(TAG, "device discover stopped");
462 }
463
CoapDiscoverRequestOngoing(void)464 uint8_t CoapDiscoverRequestOngoing(void)
465 {
466 return (g_discoverCount > 0 && g_userRequest);
467 }
468
CoapDiscoverInit(EpollDesc epollfd)469 int32_t CoapDiscoverInit(EpollDesc epollfd)
470 {
471 (void)epollfd;
472 if (g_discoverTimer == NULL) {
473 g_discoverTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, CoapServiceDiscoverTimerHandle, NULL);
474 if (g_discoverTimer == NULL) {
475 DFINDER_LOGE(TAG, "failed to start timer for service discover");
476 return NSTACKX_EFAILED;
477 }
478 }
479 CoapSoftBusInitMsgId();
480 g_userRequest = NSTACKX_FALSE;
481 g_forceUpdate = NSTACKX_FALSE;
482 g_discoverCount = 0;
483 return NSTACKX_EOK;
484 }
485
CoapDiscoverDeinit(void)486 void CoapDiscoverDeinit(void)
487 {
488 if (g_discoverTimer != NULL) {
489 TimerDelete(g_discoverTimer);
490 g_discoverTimer = NULL;
491 }
492 if (g_coapIntervalArr != NULL) {
493 free(g_coapIntervalArr);
494 g_coapIntervalArr = NULL;
495 }
496 }
497
ResetCoapDiscoverTaskCount(uint8_t isBusy)498 void ResetCoapDiscoverTaskCount(uint8_t isBusy)
499 {
500 if (g_discoverTimer != NULL) {
501 if (isBusy) {
502 DFINDER_LOGI(TAG, "in this busy interval: g_discoverTimer task count %llu", g_discoverTimer->task.count);
503 }
504 g_discoverTimer->task.count = 0;
505 }
506 }
507
SetCoapDiscoverType(CoapBroadcastType type)508 void SetCoapDiscoverType(CoapBroadcastType type)
509 {
510 g_coapDiscoverType = (uint32_t)type;
511 }
512
SetCoapDiscConfig(const DFinderDiscConfig * discConfig)513 int32_t SetCoapDiscConfig(const DFinderDiscConfig *discConfig)
514 {
515 uint32_t *tmp = (uint32_t *)malloc(discConfig->intervalArrLen * sizeof(uint32_t));
516 if (tmp != NULL) {
517 if (g_coapIntervalArr != NULL) {
518 free(g_coapIntervalArr);
519 }
520 g_coapIntervalArr = tmp;
521 for (size_t i = 0; i < discConfig->intervalArrLen; ++i) {
522 g_coapIntervalArr[i] = (discConfig->bcastInterval)[i];
523 }
524 // add 1: first broadcast starts immediately
525 g_coapUserMaxDiscoverCount = discConfig->intervalArrLen + 1;
526 return NSTACKX_EOK;
527 }
528 DFINDER_LOGE(TAG, "malloc for user define interval array failed");
529 if (g_coapIntervalArr != NULL) {
530 DFINDER_LOGD(TAG, "going to use last interval config");
531 return NSTACKX_EOK;
532 }
533 DFINDER_LOGE(TAG, "failed to use last interval config");
534 return NSTACKX_EFAILED;
535 }
536
SendDiscoveryRspEx(const NSTACKX_ResponseSettings * responseSettings)537 static int32_t SendDiscoveryRspEx(const NSTACKX_ResponseSettings *responseSettings)
538 {
539 if (responseSettings == NULL) {
540 return NSTACKX_EFAILED;
541 }
542
543 if (responseSettings->businessData == NULL) {
544 DFINDER_LOGE(TAG, "businessData is null");
545 return NSTACKX_EFAILED;
546 }
547
548 if (SetLocalDeviceBusinessData(responseSettings->businessData, NSTACKX_TRUE) != NSTACKX_EOK) {
549 return NSTACKX_EFAILED;
550 }
551 char remoteUrl[NSTACKX_MAX_URI_BUFFER_LENGTH] = {0};
552 char host[NSTACKX_MAX_IP_STRING_LEN] = {0};
553 if (strncpy_s(host, sizeof(host), responseSettings->remoteIp,
554 strlen(responseSettings->remoteIp)) != EOK) {
555 DFINDER_LOGE(TAG, "discoveryRsp remoteIp copy error");
556 return NSTACKX_EFAILED;
557 }
558 if (sprintf_s(remoteUrl, sizeof(remoteUrl), "coap://%s/" COAP_DEVICE_DISCOVER_URI, host) < 0) {
559 DFINDER_LOGE(TAG, "failed to get discoveryRsp remoteUrl");
560 return NSTACKX_EFAILED;
561 }
562 CoapBuildParam param;
563 CreateUnicastCoapParam(remoteUrl, host, ¶m);
564 return CoapSendMessage(¶m, NSTACKX_FALSE, responseSettings->businessType, false);
565 }
566
SendDiscoveryRsp(const NSTACKX_ResponseSettings * responseSettings)567 void SendDiscoveryRsp(const NSTACKX_ResponseSettings *responseSettings)
568 {
569 if (SendDiscoveryRspEx(responseSettings) != NSTACKX_EOK) {
570 IncStatistics(STATS_SEND_SD_RESPONSE_FAILED);
571 }
572 }
573
SetCoapUserDiscoverInfo(uint32_t advCount,uint32_t advDuration)574 void SetCoapUserDiscoverInfo(uint32_t advCount, uint32_t advDuration)
575 {
576 g_coapUserMaxDiscoverCount = advCount;
577 if (advCount == 0) {
578 return;
579 }
580 g_coapUserDiscoverInterval = advDuration / advCount;
581 }
582