• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "disc_nstackx_adapter.h"
17 
18 #include <locale.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <wchar.h>
23 
24 #include "nstackx.h"
25 #include "anonymizer.h"
26 #include "bus_center_manager.h"
27 #include "disc_coap_capability_public.h"
28 #include "disc_coap_parser.h"
29 #include "disc_log.h"
30 #include "g_enhance_disc_func_pack.h"
31 #include "lnn_ohos_account.h"
32 #include "locale_config_wrapper.h"
33 #include "securec.h"
34 #include "softbus_adapter_crypto.h"
35 #include "softbus_adapter_mem.h"
36 #include "softbus_adapter_thread.h"
37 #include "softbus_def.h"
38 #include "softbus_error_code.h"
39 #include "softbus_feature_config.h"
40 #include "legacy/softbus_hidumper_disc.h"
41 #include "legacy/softbus_hisysevt_discreporter.h"
42 #include "softbus_json_utils.h"
43 #include "softbus_utils.h"
44 
45 #define WLAN_IFACE_NAME_PREFIX            "wlan"
46 #define NCM_LINK_NAME_PREFIX              "ncm0"
47 #define NCM_HOST_NAME_PREFIX              "wwan0"
48 #define DISC_FREQ_COUNT_MASK              0xFFFF
49 #define DISC_FREQ_DURATION_BIT            16
50 #define DISC_USECOND                      1000
51 #define DEFAULT_MAX_DEVICE_NUM            20
52 #define IPV4_MAX_LEN                      16
53 
54 #define NSTACKX_LOCAL_DEV_INFO            "NstackxLocalDevInfo"
55 #define HYPHEN_ZH                         "的"
56 #define HYPHEN_EXCEPT_ZH                  "-"
57 #define EMPTY_STRING                      ""
58 #define DEFAULT_LINK_IFNAME               "lo"
59 
60 #define IPV4_LOOP_IP                      "127.0.0.1"
61 #define IPV6_LOOP_IP                      "::1"
62 
63 static NSTACKX_LocalDeviceInfoV2 *g_localDeviceInfo = NULL;
64 static DiscInnerCallback *g_discCoapInnerCb = NULL;
65 static SoftBusMutex g_localDeviceInfoLock = {0};
66 static SoftBusMutex g_discCoapInnerCbLock = {0};
67 static int32_t NstackxLocalDevInfoDump(int fd);
68 static int32_t g_currentLinkUpNums = 0;
69 static char g_serviceData[NSTACKX_MAX_SERVICE_DATA_LEN] = {0};
70 
71 typedef struct {
72     char netWorkName[NSTACKX_MAX_INTERFACE_NAME_LEN];
73     LinkStatus status;
74 } DiscLinkInfo;
75 
76 static DiscLinkInfo g_linkInfo[MAX_IF + 1] = {
77     {DEFAULT_LINK_IFNAME, LINK_STATUS_DOWN},
78     {DEFAULT_LINK_IFNAME, LINK_STATUS_DOWN},
79 };
80 
81 #if defined(DSOFTBUS_FEATURE_DISC_LNN_COAP) || defined(DSOFTBUS_FEATURE_DISC_SHARE_COAP)
FillRspSettings(NSTACKX_ResponseSettings * settings,const DeviceInfo * deviceInfo,uint8_t bType)82 static int32_t FillRspSettings(NSTACKX_ResponseSettings *settings, const DeviceInfo *deviceInfo, uint8_t bType)
83 {
84     DISC_CHECK_AND_RETURN_RET_LOGE(settings != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "settings is nullptr");
85     DISC_CHECK_AND_RETURN_RET_LOGE(deviceInfo != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "deviceInfo is nullptr");
86 
87     settings->businessData = NULL;
88     settings->length = 0;
89     settings->businessType = bType;
90 
91     char localNetifName[NSTACKX_MAX_INTERFACE_NAME_LEN] = {0};
92     if (g_linkInfo[USB_IF].status == LINK_STATUS_UP && strlen(deviceInfo->addr[0].info.ip.ip) > IPV4_MAX_LEN) {
93         LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, localNetifName, NSTACKX_MAX_INTERFACE_NAME_LEN, USB_IF);
94     }
95     if (g_linkInfo[WLAN_IF].status == LINK_STATUS_UP && strlen(deviceInfo->addr[0].info.ip.ip) <= IPV4_MAX_LEN) {
96         LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, localNetifName, NSTACKX_MAX_INTERFACE_NAME_LEN, WLAN_IF);
97     }
98     DISC_CHECK_AND_RETURN_RET_LOGE(strlen(localNetifName) != 0, SOFTBUS_INVALID_PARAM, DISC_COAP,
99         "get localNetifName failed");
100     if (strcpy_s(settings->localNetworkName, sizeof(settings->localNetworkName), localNetifName) != EOK) {
101         DISC_LOGE(DISC_COAP, "copy disc response settings network name failed");
102         goto EXIT;
103     }
104     if (strcpy_s(settings->remoteIp, sizeof(settings->remoteIp), deviceInfo->addr[0].info.ip.ip) != EOK) {
105         DISC_LOGE(DISC_COAP, "copy disc response settings remote IP failed");
106         goto EXIT;
107     }
108     return SOFTBUS_OK;
109 EXIT:
110     return SOFTBUS_STRCPY_ERR;
111 }
112 #endif /* DSOFTBUS_FEATURE_DISC_LNN_COAP || DSOFTBUS_FEATURE_DISC_SHARE_COAP */
113 
DiscCoapSendRsp(const DeviceInfo * deviceInfo,uint8_t bType)114 int32_t DiscCoapSendRsp(const DeviceInfo *deviceInfo, uint8_t bType)
115 {
116 #if defined(DSOFTBUS_FEATURE_DISC_LNN_COAP) || defined(DSOFTBUS_FEATURE_DISC_SHARE_COAP)
117     DISC_CHECK_AND_RETURN_RET_LOGE(deviceInfo, SOFTBUS_INVALID_PARAM, DISC_COAP, "DiscRsp devInfo is null");
118     NSTACKX_ResponseSettings *settings = (NSTACKX_ResponseSettings *)SoftBusCalloc(sizeof(NSTACKX_ResponseSettings));
119     DISC_CHECK_AND_RETURN_RET_LOGE(settings, SOFTBUS_MALLOC_ERR, DISC_COAP, "malloc disc response settings failed");
120 
121     int32_t ret = FillRspSettings(settings, deviceInfo, bType);
122     if (ret != SOFTBUS_OK) {
123         DISC_LOGE(DISC_COAP, "fill nstackx response settings failed");
124         SoftBusFree(settings);
125         return ret;
126     }
127 
128     DISC_LOGI(DISC_COAP, "send rsp with bType=%{public}u", bType);
129     ret = NSTACKX_SendDiscoveryRsp(settings);
130     if (ret != SOFTBUS_OK) {
131         DISC_LOGE(DISC_COAP, "disc send response failed, ret=%{public}d", ret);
132     }
133     SoftBusFree(settings);
134     return ret;
135 #else
136     return SOFTBUS_OK;
137 #endif /* DSOFTBUS_FEATURE_DISC_LNN_COAP || DSOFTBUS_FEATURE_DISC_SHARE_COAP */
138 }
139 
ParseReservedInfo(const NSTACKX_DeviceInfo * nstackxDevice,DeviceInfo * device,char * nickName)140 static int32_t ParseReservedInfo(const NSTACKX_DeviceInfo *nstackxDevice, DeviceInfo *device, char *nickName)
141 {
142     DISC_CHECK_AND_RETURN_RET_LOGE(nstackxDevice != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "nstackxDevice is nullptr");
143     DISC_CHECK_AND_RETURN_RET_LOGE(device != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "device is nullptr");
144     DISC_CHECK_AND_RETURN_RET_LOGE(nickName != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "nickName is nullptr");
145 
146     cJSON *reserveInfo = cJSON_Parse(nstackxDevice->reservedInfo);
147     DISC_CHECK_AND_RETURN_RET_LOGE(reserveInfo != NULL, SOFTBUS_PARSE_JSON_ERR, DISC_COAP,
148         "parse reserve data failed.");
149 
150     DiscCoapParseWifiIpAddr(reserveInfo, device);
151     DiscCoapParseHwAccountHash(reserveInfo, device);
152     DiscCoapParseNickname(reserveInfo, nickName, DISC_MAX_NICKNAME_LEN);
153     if (DiscCoapParseServiceData(reserveInfo, device) != SOFTBUS_OK) {
154         DISC_LOGD(DISC_COAP, "parse service data failed");
155     }
156     cJSON_Delete(reserveInfo);
157     return SOFTBUS_OK;
158 }
159 
SpliceCoapDisplayName(char * devName,char * nickName,DeviceInfo * device)160 static int32_t SpliceCoapDisplayName(char *devName, char *nickName, DeviceInfo *device)
161 {
162     DISC_CHECK_AND_RETURN_RET_LOGE(devName != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "devName is nullptr");
163     DISC_CHECK_AND_RETURN_RET_LOGE(device != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "device is nullptr");
164     DISC_CHECK_AND_RETURN_RET_LOGE(nickName != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "nickName is nullptr");
165 
166     char *hyphen = NULL;
167     bool isSameAccount = false;
168     bool isZH = IsZHLanguage();
169     char accountIdStr[MAX_ACCOUNT_HASH_LEN] = { 0 };
170     char accountHash[MAX_ACCOUNT_HASH_LEN] = { 0 };
171     int32_t ret = SOFTBUS_OK;
172 
173     if (!LnnIsDefaultOhosAccount()) {
174         int64_t accountId = 0;
175         ret = LnnGetLocalNum64Info(NUM_KEY_ACCOUNT_LONG, &accountId);
176         DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "get local account failed");
177 
178         ret = sprintf_s(accountIdStr, MAX_ACCOUNT_HASH_LEN, "%ju", (uint64_t)accountId);
179         DISC_CHECK_AND_RETURN_RET_LOGE(ret >= 0, SOFTBUS_STRCPY_ERR, DISC_COAP,
180             "set accountIdStr error, ret=%{public}d", ret);
181         ret = SoftBusGenerateStrHash((const unsigned char *)accountIdStr, strlen(accountIdStr),
182             (unsigned char *)accountHash);
183         DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
184             "generate account hash failed, ret=%{public}d", ret);
185 
186         if (memcmp(device->accountHash, accountHash, MAX_ACCOUNT_HASH_LEN) == 0) {
187             isSameAccount = true;
188         }
189     }
190     if (!isSameAccount && strlen(nickName) > 0) {
191         hyphen = isZH ? (char *)HYPHEN_ZH : (char *)HYPHEN_EXCEPT_ZH;
192     } else {
193         hyphen = (char *)EMPTY_STRING;
194     }
195 
196     ret = sprintf_s(device->devName, DISC_MAX_DEVICE_NAME_LEN, "%s%s%s",
197         isSameAccount ? EMPTY_STRING : nickName, hyphen, devName);
198     DISC_CHECK_AND_RETURN_RET_LOGE(ret >= 0, SOFTBUS_STRCPY_ERR, DISC_COAP,
199         "splice displayname failed, ret=%{public}d", ret);
200 
201     return SOFTBUS_OK;
202 }
203 
ParseDiscDevInfo(const NSTACKX_DeviceInfo * nstackxDevInfo,DeviceInfo * discDevInfo)204 static int32_t ParseDiscDevInfo(const NSTACKX_DeviceInfo *nstackxDevInfo, DeviceInfo *discDevInfo)
205 {
206     DISC_CHECK_AND_RETURN_RET_LOGE(nstackxDevInfo != NULL, SOFTBUS_INVALID_PARAM,
207         DISC_COAP, "nstackxDevInfo is nullptr");
208     DISC_CHECK_AND_RETURN_RET_LOGE(discDevInfo != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "discDevInfo is nullptr");
209 
210     char devName[DISC_MAX_DEVICE_NAME_LEN] = { 0 };
211     char nickName[DISC_MAX_NICKNAME_LEN] = { 0 };
212     if (strcpy_s(devName, DISC_MAX_DEVICE_NAME_LEN, nstackxDevInfo->deviceName) != EOK ||
213         memcpy_s(discDevInfo->capabilityBitmap, sizeof(discDevInfo->capabilityBitmap),
214                  nstackxDevInfo->capabilityBitmap, sizeof(nstackxDevInfo->capabilityBitmap)) != EOK) {
215         DISC_LOGE(DISC_COAP, "strcpy_s devName or memcpy_s capabilityBitmap failed.");
216         return SOFTBUS_MEM_ERR;
217     }
218 
219     discDevInfo->devType = (DeviceType)nstackxDevInfo->deviceType;
220     discDevInfo->capabilityBitmapNum = nstackxDevInfo->capabilityBitmapNum;
221 
222     if (strncmp(nstackxDevInfo->networkName, WLAN_IFACE_NAME_PREFIX, strlen(WLAN_IFACE_NAME_PREFIX)) == 0) {
223         discDevInfo->addr[0].type = CONNECTION_ADDR_WLAN;
224     } else if (strncmp(nstackxDevInfo->networkName, NCM_LINK_NAME_PREFIX, strlen(NCM_LINK_NAME_PREFIX)) == 0 ||
225         strncmp(nstackxDevInfo->networkName, NCM_HOST_NAME_PREFIX, strlen(NCM_HOST_NAME_PREFIX)) == 0) {
226         discDevInfo->addr[0].type = CONNECTION_ADDR_NCM;
227     } else {
228         discDevInfo->addr[0].type = CONNECTION_ADDR_ETH;
229     }
230 
231     int32_t ret = DiscCoapParseDeviceUdid(nstackxDevInfo->deviceId, discDevInfo);
232     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
233         "parse device udid failed, ret=%{public}d", ret);
234 
235     ret = ParseReservedInfo(nstackxDevInfo, discDevInfo, nickName);
236     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
237         "parse reserve information failed, ret=%{public}d", ret);
238 
239     // coap not support range now, just assign -1 as unknown
240     discDevInfo->range = -1;
241     ret = SpliceCoapDisplayName(devName, nickName, discDevInfo);
242     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
243         "parse display name failed, ret=%{public}d", ret);
244 
245     return SOFTBUS_OK;
246 }
247 
OnDeviceFound(const NSTACKX_DeviceInfo * deviceList,uint32_t deviceCount)248 static void OnDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
249 {
250     DISC_CHECK_AND_RETURN_LOGE(deviceList != NULL && deviceCount != 0, DISC_COAP, "invalid param.");
251     DISC_LOGD(DISC_COAP, "Disc device found, count=%{public}u", deviceCount);
252     DeviceInfo *discDeviceInfo = (DeviceInfo *)SoftBusCalloc(sizeof(DeviceInfo));
253     DISC_CHECK_AND_RETURN_LOGE(discDeviceInfo != NULL, DISC_COAP, "malloc device info failed.");
254 
255     int32_t ret;
256     for (uint32_t i = 0; i < deviceCount; i++) {
257         const NSTACKX_DeviceInfo *nstackxDeviceInfo = deviceList + i;
258         if (nstackxDeviceInfo == NULL) {
259             DISC_LOGE(DISC_COAP, "device count from nstackx is invalid");
260             SoftBusFree(discDeviceInfo);
261             return;
262         }
263 
264         if ((nstackxDeviceInfo->update & 0x1) == 0) {
265             char *anonymizedName = NULL;
266             AnonymizeDeviceName(nstackxDeviceInfo->deviceName, &anonymizedName);
267             DISC_LOGI(DISC_COAP, "duplicate device do not need report. deviceName=%{public}s",
268                 AnonymizeWrapper(anonymizedName));
269             AnonymizeFree(anonymizedName);
270             continue;
271         }
272         (void)memset_s(discDeviceInfo, sizeof(DeviceInfo), 0, sizeof(DeviceInfo));
273         ret = ParseDiscDevInfo(nstackxDeviceInfo, discDeviceInfo);
274         if (ret != SOFTBUS_OK) {
275             DISC_LOGW(DISC_COAP, "parse discovery device info failed.");
276             continue;
277         }
278         ret = DiscCoapProcessDeviceInfoPacked(nstackxDeviceInfo, discDeviceInfo, g_discCoapInnerCb,
279             &g_discCoapInnerCbLock);
280         if (ret != SOFTBUS_OK) {
281             DISC_LOGD(DISC_COAP, "DiscRecv: process device info failed, ret=%{public}d", ret);
282         }
283     }
284 
285     SoftBusFree(discDeviceInfo);
286 }
287 
OnNotificationReceived(const NSTACKX_NotificationConfig * notification)288 static void OnNotificationReceived(const NSTACKX_NotificationConfig *notification)
289 {
290     DiscCoapReportNotificationPacked(notification);
291 }
292 
293 static NSTACKX_Parameter g_nstackxCallBack = {
294     .onDeviceListChanged = OnDeviceFound,
295     .onDeviceFound = NULL,
296     .onMsgReceived = NULL,
297     .onDFinderMsgReceived = NULL,
298     .onNotificationReceived = OnNotificationReceived,
299 };
300 
DiscCoapRegisterCb(const DiscInnerCallback * discCoapCb)301 int32_t DiscCoapRegisterCb(const DiscInnerCallback *discCoapCb)
302 {
303     DISC_CHECK_AND_RETURN_RET_LOGE(discCoapCb != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "invalid param");
304     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_discCoapInnerCbLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
305         DISC_COAP, "lock failed");
306     if (g_discCoapInnerCb == NULL) {
307         DISC_LOGE(DISC_COAP, "coap inner callback not init.");
308         (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
309         return SOFTBUS_DISCOVER_COAP_NOT_INIT;
310     }
311     if (memcpy_s(g_discCoapInnerCb, sizeof(DiscInnerCallback), discCoapCb, sizeof(DiscInnerCallback)) != EOK) {
312         DISC_LOGE(DISC_COAP, "memcpy_s failed.");
313         (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
314         return SOFTBUS_MEM_ERR;
315     }
316     (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
317     return SOFTBUS_OK;
318 }
319 
DiscCoapRegisterCapability(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[])320 int32_t DiscCoapRegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
321 {
322     DISC_CHECK_AND_RETURN_RET_LOGE(capabilityBitmapNum != 0, SOFTBUS_INVALID_PARAM,
323         DISC_COAP, "capabilityBitmapNum=0");
324 
325     if (NSTACKX_RegisterCapability(capabilityBitmapNum, capabilityBitmap) != SOFTBUS_OK) {
326         DISC_LOGE(DISC_COAP, "NSTACKX Register Capability failed");
327         return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL;
328     }
329     return SOFTBUS_OK;
330 }
331 
DiscCoapSetFilterCapability(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[])332 int32_t DiscCoapSetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
333 {
334     DISC_CHECK_AND_RETURN_RET_LOGE(capabilityBitmapNum != 0, SOFTBUS_INVALID_PARAM,
335         DISC_COAP, "capabilityBitmapNum=0");
336 
337     if (NSTACKX_SetFilterCapability(capabilityBitmapNum, capabilityBitmap) != SOFTBUS_OK) {
338         DISC_LOGE(DISC_COAP, "NSTACKX SetFilter Capability failed");
339         SoftbusReportDiscFault(SOFTBUS_HISYSEVT_DISC_MEDIUM_COAP, SOFTBUS_HISYSEVT_DISCOVER_COAP_SET_FILTER_CAP_FAIL);
340         return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL;
341     }
342     return SOFTBUS_OK;
343 }
344 
RegisterServiceData()345 static int32_t RegisterServiceData()
346 {
347     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_discCoapInnerCbLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
348         DISC_COAP, "lock failed");
349 
350     if (g_currentLinkUpNums == 0) {
351         DISC_LOGW(DISC_COAP, "no link up, not register service data");
352         (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
353         return SOFTBUS_OK;
354     }
355     (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
356 
357     int32_t ret = 0;
358     int32_t port = 0;
359     char ip[IP_STR_MAX_LEN] = {0};
360     int32_t cnt = 0;
361     struct NSTACKX_ServiceData serviceData[MAX_IF + 1] = {0};
362     for (uint32_t index = 0; index <= MAX_IF; index++) {
363         if (g_linkInfo[index].status == LINK_STATUS_DOWN) {
364             continue;
365         }
366 
367         ret = LnnGetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, &port, index);
368         DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "get local port failed");
369         ret = LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, ip, IP_STR_MAX_LEN, index);
370         DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "get local ip failed");
371 
372         if (strcpy_s(serviceData[cnt].ip, IP_STR_MAX_LEN, ip) != EOK) {
373             DISC_LOGE(DISC_COAP, "strcpy ip error.");
374             return SOFTBUS_STRCPY_ERR;
375         }
376         DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
377             DISC_COAP, "lock failed");
378         if (sprintf_s(serviceData[cnt].serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, "port:%d,%s",
379             port, g_serviceData) < 0) {
380             DISC_LOGE(DISC_COAP, "write service data failed.");
381             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
382             return SOFTBUS_STRCPY_ERR;
383         }
384         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
385         cnt++;
386     }
387     ret = NSTACKX_RegisterServiceDataV2(serviceData, cnt);
388     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "register servicedata to dfinder failed");
389     return SOFTBUS_OK;
390 }
391 
DiscCoapRegisterServiceData(const PublishOption * option,uint32_t allCap)392 int32_t DiscCoapRegisterServiceData(const PublishOption *option, uint32_t allCap)
393 {
394 #ifdef DSOFTBUS_FEATURE_DISC_COAP
395     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
396         DISC_COAP, "lock failed");
397     int32_t ret = DiscCoapFillServiceDataPacked(option, g_serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, allCap);
398     if (ret != SOFTBUS_OK) {
399         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
400         DISC_LOGE(DISC_COAP, "fill castJson failed. ret=%{public}d", ret);
401         return ret;
402     }
403     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
404 #endif /* DSOFTBUS_FEATURE_DISC_COAP */
405     int32_t result = RegisterServiceData();
406     DISC_CHECK_AND_RETURN_RET_LOGE(result == SOFTBUS_OK, result, DISC_COAP,
407         "register service data to nstackx failed. result=%{public}d", result);
408     return SOFTBUS_OK;
409 }
410 
DiscCoapRegisterBusinessData(const unsigned char * capabilityData,uint32_t dataLen)411 int32_t DiscCoapRegisterBusinessData(const unsigned char *capabilityData, uint32_t dataLen)
412 {
413     DISC_CHECK_AND_RETURN_RET_LOGD(capabilityData != NULL && dataLen > 0, SOFTBUS_OK, DISC_COAP,
414         "no capability data, no need to parse and register");
415     char businessData[NSTACKX_MAX_BUSINESS_DATA_LEN] = { 0 };
416     int32_t ret = DiscCoapAssembleBdataPacked(capabilityData, dataLen, businessData, sizeof(businessData));
417     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "assemble bdata failed, ret=%{public}d", ret);
418     ret = NSTACKX_RegisterBusinessData(businessData);
419     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "register bdata failed, ret=%{public}d", ret);
420     return SOFTBUS_OK;
421 }
422 
423 #ifdef DSOFTBUS_FEATURE_DISC_SHARE_COAP
DiscCoapRegisterCapabilityData(const unsigned char * capabilityData,uint32_t dataLen,uint32_t capability)424 int32_t DiscCoapRegisterCapabilityData(const unsigned char *capabilityData, uint32_t dataLen, uint32_t capability)
425 {
426     if (capabilityData == NULL || dataLen == 0) {
427         // no capability data, no need to parse and register
428         return SOFTBUS_OK;
429     }
430     char *registerCapaData = (char *)SoftBusCalloc(MAX_CAPABILITYDATA_LEN);
431     DISC_CHECK_AND_RETURN_RET_LOGE(registerCapaData, SOFTBUS_MALLOC_ERR, DISC_COAP, "malloc capability data failed");
432     int32_t ret = DiscCoapAssembleCapDataPacked(capability, (const char *)capabilityData, dataLen, registerCapaData,
433         DISC_MAX_CUST_DATA_LEN);
434     if (ret == SOFTBUS_FUNC_NOT_SUPPORT) {
435         DISC_LOGI(DISC_COAP, "the capability not support yet. capability=%{public}u", capability);
436         SoftBusFree(registerCapaData);
437         return SOFTBUS_OK;
438     }
439     if (ret != SOFTBUS_OK) {
440         DISC_LOGE(DISC_COAP, "assemble the data of capability failed. capability=%{public}u", capability);
441         SoftBusFree(registerCapaData);
442         return ret;
443     }
444 
445     if (NSTACKX_RegisterExtendServiceData(registerCapaData) != SOFTBUS_OK) {
446         DISC_LOGE(DISC_COAP, "register extend service data to nstackx failed");
447         SoftBusFree(registerCapaData);
448         return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_DATA_FAIL;
449     }
450     DISC_LOGI(DISC_COAP, "register extend service data to nstackx succ.");
451     SoftBusFree(registerCapaData);
452     return SOFTBUS_OK;
453 }
454 #endif /* DSOFTBUS_FEATURE_DISC_SHARE_COAP */
455 
GetDiscFreq(int32_t freq,uint32_t * discFreq)456 static int32_t GetDiscFreq(int32_t freq, uint32_t *discFreq)
457 {
458     DISC_CHECK_AND_RETURN_RET_LOGE(discFreq != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "discFreq is nullptr");
459 
460     uint32_t arrayFreq[FREQ_BUTT] = { 0 };
461     int32_t ret = SoftbusGetConfig(SOFTBUS_INT_DISC_FREQ, (unsigned char *)arrayFreq, sizeof(arrayFreq));
462     if (ret != SOFTBUS_OK) {
463         DISC_LOGE(DISC_COAP, "disc get freq failed");
464         return ret;
465     }
466     *discFreq = arrayFreq[freq];
467     return SOFTBUS_OK;
468 }
469 
ConvertDiscoverySettings(NSTACKX_DiscoverySettings * discSet,const DiscCoapOption * option)470 static int32_t ConvertDiscoverySettings(NSTACKX_DiscoverySettings *discSet, const DiscCoapOption *option)
471 {
472     DISC_CHECK_AND_RETURN_RET_LOGE(discSet != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "discSet is nullptr");
473     DISC_CHECK_AND_RETURN_RET_LOGE(option != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "option is nullptr");
474 
475     if (option->mode == ACTIVE_PUBLISH) {
476         discSet->discoveryMode = PUBLISH_MODE_PROACTIVE;
477     } else {
478         discSet->discoveryMode = DISCOVER_MODE;
479     }
480     uint32_t discFreq;
481     int32_t ret = GetDiscFreq(option->freq, &discFreq);
482     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "get disc freq failed");
483     discSet->advertiseCount = discFreq & DISC_FREQ_COUNT_MASK;
484     discSet->advertiseDuration = (discFreq >> DISC_FREQ_DURATION_BIT) * DISC_USECOND;
485     ret = DiscFillBtypePacked(option->capability, option->allCap, discSet);
486     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "unsupport capability");
487     return SOFTBUS_OK;
488 }
489 
FreeDiscSet(NSTACKX_DiscoverySettings * discSet)490 static void FreeDiscSet(NSTACKX_DiscoverySettings *discSet)
491 {
492     if (discSet != NULL) {
493         SoftBusFree(discSet->businessData);
494         SoftBusFree(discSet);
495     }
496 }
497 
DiscCoapStartDiscovery(DiscCoapOption * option)498 int32_t DiscCoapStartDiscovery(DiscCoapOption *option)
499 {
500     DISC_CHECK_AND_RETURN_RET_LOGE(option != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "option is null.");
501     DISC_CHECK_AND_RETURN_RET_LOGE(option->mode >= ACTIVE_PUBLISH && option->mode <= ACTIVE_DISCOVERY,
502         SOFTBUS_INVALID_PARAM, DISC_COAP, "option->mode is invalid");
503     DISC_CHECK_AND_RETURN_RET_LOGE(LOW <= option->freq && option->freq < FREQ_BUTT, SOFTBUS_INVALID_PARAM,
504         DISC_COAP, "invalid freq. freq=%{public}d", option->freq);
505     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
506         DISC_COAP, "lock failed");
507 
508     if (g_currentLinkUpNums == 0) {
509         DISC_LOGE(DISC_COAP, "netif not works");
510         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
511         return SOFTBUS_NETWORK_NOT_FOUND;
512     }
513     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
514 
515     NSTACKX_DiscoverySettings *discSet = (NSTACKX_DiscoverySettings *)SoftBusCalloc(sizeof(NSTACKX_DiscoverySettings));
516     DISC_CHECK_AND_RETURN_RET_LOGE(discSet != NULL, SOFTBUS_MEM_ERR, DISC_COAP, "malloc disc settings failed");
517 
518     int32_t ret = ConvertDiscoverySettings(discSet, option);
519     if (ret != SOFTBUS_OK) {
520         DISC_LOGE(DISC_COAP, "set discovery settings failed");
521         FreeDiscSet(discSet);
522         return ret;
523     }
524     if (NSTACKX_StartDeviceDiscovery(discSet) != SOFTBUS_OK) {
525         DISC_LOGE(DISC_COAP, "start device discovery failed");
526         FreeDiscSet(discSet);
527         return (option->mode == ACTIVE_PUBLISH) ? SOFTBUS_DISCOVER_COAP_START_PUBLISH_FAIL :
528             SOFTBUS_DISCOVER_COAP_START_DISCOVER_FAIL;
529     }
530     FreeDiscSet(discSet);
531     return SOFTBUS_OK;
532 }
533 
DiscCoapStopDiscovery(void)534 int32_t DiscCoapStopDiscovery(void)
535 {
536     if (NSTACKX_StopDeviceFind() != SOFTBUS_OK) {
537         DISC_LOGE(DISC_COAP, "stop device discovery failed");
538         return SOFTBUS_DISCOVER_COAP_STOP_DISCOVER_FAIL;
539     }
540 
541     return SOFTBUS_OK;
542 }
543 
GetDeviceId(void)544 static char *GetDeviceId(void)
545 {
546     char *formatString = NULL;
547     char udid[UDID_BUF_LEN] = { 0 };
548     int32_t ret = LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, sizeof(udid));
549     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, NULL, DISC_COAP, "get udid failed, ret=%{public}d", ret);
550 
551     cJSON *deviceId = cJSON_CreateObject();
552     DISC_CHECK_AND_RETURN_RET_LOGW(deviceId != NULL, NULL, DISC_COAP, "create json object failed: deviceId=NULL");
553 
554     if (!AddStringToJsonObject(deviceId, DEVICE_UDID, udid)) {
555         DISC_LOGE(DISC_COAP, "add udid to device id json object failed.");
556         goto GET_DEVICE_ID_END;
557     }
558     formatString = cJSON_PrintUnformatted(deviceId);
559     if (formatString == NULL) {
560         DISC_LOGE(DISC_COAP, "format device id json object failed.");
561     }
562 
563 GET_DEVICE_ID_END:
564     cJSON_Delete(deviceId);
565     return formatString;
566 }
567 
SetLocalLinkInfo(LinkStatus status,int32_t ifnameIdx)568 static int32_t SetLocalLinkInfo(LinkStatus status, int32_t ifnameIdx)
569 {
570     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
571         DISC_COAP, "lock failed");
572     if (g_localDeviceInfo == NULL) {
573         DISC_LOGE(DISC_COAP, "disc coap not init");
574         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
575         return SOFTBUS_DISCOVER_COAP_NOT_INIT;
576     }
577 
578     (void)memset_s(g_localDeviceInfo->localIfInfo, sizeof(NSTACKX_InterfaceInfo), 0,
579         sizeof(NSTACKX_InterfaceInfo));
580     if (status == LINK_STATUS_DOWN) {
581         if (strcpy_s(g_localDeviceInfo->localIfInfo->networkName, sizeof(g_localDeviceInfo->localIfInfo->networkName),
582             g_linkInfo[ifnameIdx].netWorkName) != EOK) {
583             DISC_LOGE(DISC_COAP, "strcpy networkname failed.");
584             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
585             return SOFTBUS_STRCPY_ERR;
586         }
587         // Set IpAddr to loop IP assuming the link is down.
588         char *networkIpAddr = (ifnameIdx == WLAN_IF) ? IPV4_LOOP_IP : IPV6_LOOP_IP;
589         if (strcpy_s(g_localDeviceInfo->localIfInfo->networkIpAddr,
590             sizeof(g_localDeviceInfo->localIfInfo->networkIpAddr), networkIpAddr) != EOK) {
591             DISC_LOGE(DISC_COAP, "strcpy networkIpAddr failed.");
592             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
593             return SOFTBUS_STRCPY_ERR;
594         }
595     } else {
596         if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, g_localDeviceInfo->localIfInfo->networkName,
597             sizeof(g_localDeviceInfo->localIfInfo->networkName), ifnameIdx) != SOFTBUS_OK) {
598             DISC_LOGE(DISC_COAP, "get local device info from lnn failed.");
599             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
600             return SOFTBUS_DISCOVER_GET_LOCAL_STR_FAILED;
601         }
602         if (strcpy_s(g_linkInfo[ifnameIdx].netWorkName, sizeof(g_localDeviceInfo->localIfInfo->networkName),
603             g_localDeviceInfo->localIfInfo->networkName) != EOK) {
604             DISC_LOGE(DISC_COAP, "strcpy networkname failed.");
605             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
606             return SOFTBUS_STRCPY_ERR;
607         }
608         if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, g_localDeviceInfo->localIfInfo->networkIpAddr,
609             sizeof(g_localDeviceInfo->localIfInfo->networkIpAddr), ifnameIdx) != SOFTBUS_OK) {
610             DISC_LOGE(DISC_COAP, "get local device info from lnn failed.");
611             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
612             return SOFTBUS_DISCOVER_GET_LOCAL_STR_FAILED;
613         }
614     }
615 
616     g_localDeviceInfo->ifNums = 1;
617     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
618     return SOFTBUS_OK;
619 }
620 
SetLocalDeviceInfo(LinkStatus status,int32_t ifnameIdx)621 static int32_t SetLocalDeviceInfo(LinkStatus status, int32_t ifnameIdx)
622 {
623     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
624         DISC_COAP, "lock failed");
625     if (g_localDeviceInfo == NULL) {
626         DISC_LOGE(DISC_COAP, "disc coap not init");
627         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
628         return SOFTBUS_DISCOVER_COAP_NOT_INIT;
629     }
630 
631     int32_t deviceType = 0;
632     int32_t ret = LnnGetLocalNumInfo(NUM_KEY_DEV_TYPE_ID, &deviceType);
633     if (ret != SOFTBUS_OK) {
634         DISC_LOGE(DISC_COAP, "get local device type failed.");
635         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
636         return ret;
637     }
638     g_localDeviceInfo->name = "";
639     g_localDeviceInfo->deviceType = (uint32_t)deviceType;
640     g_localDeviceInfo->businessType = (uint8_t)NSTACKX_BUSINESS_TYPE_NULL;
641     g_localDeviceInfo->hasDeviceHash = true;
642     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
643 
644     ret = SetLocalLinkInfo(status, ifnameIdx);
645     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
646         "set local linkInfo failed, ret=%{public}d", ret);
647     return SOFTBUS_OK;
648 }
649 
DiscCoapRecordLinkStatus(LinkStatus status,int32_t ifnameIdx)650 void DiscCoapRecordLinkStatus(LinkStatus status, int32_t ifnameIdx)
651 {
652     DISC_CHECK_AND_RETURN_LOGE(status == LINK_STATUS_UP || status == LINK_STATUS_DOWN, DISC_COAP,
653         "invlaid link status, status=%{public}d.", status);
654     DISC_CHECK_AND_RETURN_LOGE(ifnameIdx >= 0 && ifnameIdx <= MAX_IF, DISC_COAP,
655         "invlaid ifnameIdx, ifnameIdx=%{public}d.", ifnameIdx);
656     DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
657 
658     g_linkInfo[ifnameIdx].status = status;
659     int32_t cnt = 0;
660     for (int32_t i = 0; i <= MAX_IF; i++) {
661         if (g_linkInfo[i].status == LINK_STATUS_UP) {
662             cnt++;
663         }
664     }
665     g_currentLinkUpNums = cnt;
666     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
667 }
668 
DiscCoapModifyNstackThread(LinkStatus status,int32_t ifnameIdx)669 void DiscCoapModifyNstackThread(LinkStatus status, int32_t ifnameIdx)
670 {
671     DISC_CHECK_AND_RETURN_LOGE(status == LINK_STATUS_UP || status == LINK_STATUS_DOWN, DISC_COAP,
672         "invlaid link status, status=%{public}d.", status);
673     DISC_CHECK_AND_RETURN_LOGE(ifnameIdx >= 0 && ifnameIdx <= MAX_IF, DISC_COAP,
674         "invlaid ifnameIdx, ifnameIdx=%{public}d.", ifnameIdx);
675     DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
676 
677     if (status == LINK_STATUS_UP && g_currentLinkUpNums == 1) {
678         int32_t ret = NSTACKX_ThreadInit();
679         if (ret != SOFTBUS_OK) {
680             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
681             DISC_LOGE(DISC_COAP, "init nstack thread failed, ret=%{public}d", ret);
682             return;
683         }
684     } else if (status == LINK_STATUS_DOWN && g_currentLinkUpNums == 0) {
685         NSTACKX_ThreadDeinit();
686     }
687     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
688 }
689 
FreeLocalDeviceInfo(NSTACKX_LocalDeviceInfoV2 * info)690 static void FreeLocalDeviceInfo(NSTACKX_LocalDeviceInfoV2 *info)
691 {
692     DISC_CHECK_AND_RETURN_LOGE(info != NULL, DISC_COAP, "info is null");
693     SoftBusFree(info->name);
694     SoftBusFree(info->deviceId);
695     SoftBusFree(info->localIfInfo);
696     SoftBusFree(info);
697 }
698 
DupLocalDeviceInfo(NSTACKX_LocalDeviceInfoV2 * info)699 static NSTACKX_LocalDeviceInfoV2 *DupLocalDeviceInfo(NSTACKX_LocalDeviceInfoV2 *info)
700 {
701     NSTACKX_LocalDeviceInfoV2 *dup = (NSTACKX_LocalDeviceInfoV2 *)SoftBusCalloc(sizeof(NSTACKX_LocalDeviceInfoV2));
702     DISC_CHECK_AND_RETURN_RET_LOGE(dup != NULL, NULL, DISC_COAP, "malloc local device info fail");
703     if (info->name != NULL) {
704         dup->name = strdup(info->name);
705         if (dup->name == NULL) {
706             DISC_LOGE(DISC_COAP, "strdup name fail");
707             FreeLocalDeviceInfo(dup);
708             return NULL;
709         }
710     }
711     if (info->deviceId != NULL) {
712         dup->deviceId = strdup(info->deviceId);
713         if (dup->deviceId == NULL) {
714             DISC_LOGE(DISC_COAP, "strdup deviceId fail");
715             FreeLocalDeviceInfo(dup);
716             return NULL;
717         }
718     }
719     if (info->ifNums == 1) {
720         dup->localIfInfo = (NSTACKX_InterfaceInfo *)SoftBusCalloc(sizeof(NSTACKX_InterfaceInfo));
721         if (dup->localIfInfo == NULL || memcpy_s(dup->localIfInfo, sizeof(NSTACKX_InterfaceInfo),
722             info->localIfInfo, sizeof(NSTACKX_InterfaceInfo)) != EOK) {
723             DISC_LOGE(DISC_COAP, "mem local device info If info failed");
724             FreeLocalDeviceInfo(dup);
725             return NULL;
726         }
727         dup->ifNums = info->ifNums;
728     }
729     dup->deviceType = info->deviceType;
730     dup->deviceHash = info->deviceHash;
731     dup->hasDeviceHash = info->hasDeviceHash;
732     dup->businessType = info->businessType;
733     return dup;
734 }
735 
UpdateLocalIpByLocalNumInfo(int64_t accountId,int32_t port)736 static void UpdateLocalIpByLocalNumInfo(int64_t accountId, int32_t port)
737 {
738     DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
739     char *deviceIdStr = GetDeviceId();
740     if (deviceIdStr == NULL) {
741         DISC_LOGE(DISC_COAP, "get device id failed");
742         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
743         return;
744     }
745 
746     if (g_localDeviceInfo->deviceId != NULL) {
747         DISC_LOGE(DISC_COAP, "g_localDeviceInfo->deviceId is not null");
748         cJSON_free(deviceIdStr);
749         g_localDeviceInfo->deviceId = NULL;
750         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
751         return;
752     }
753     g_localDeviceInfo->deviceId = deviceIdStr;
754     g_localDeviceInfo->deviceHash = (uint64_t)accountId;
755     if (sprintf_s(g_localDeviceInfo->localIfInfo->serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, "port:%d,%s",
756         port, g_serviceData) < 0) {
757         DISC_LOGE(DISC_COAP, "write service data failed.");
758         cJSON_free(deviceIdStr);
759         g_localDeviceInfo->deviceId = NULL;
760         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
761         return;
762     }
763     NSTACKX_LocalDeviceInfoV2 *dupInfo = DupLocalDeviceInfo(g_localDeviceInfo);
764     if (dupInfo == NULL) {
765         DISC_LOGE(DISC_COAP, "dup local device info fail");
766         cJSON_free(deviceIdStr);
767         g_localDeviceInfo->deviceId = NULL;
768         (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
769         return;
770     }
771     cJSON_free(deviceIdStr);
772     g_localDeviceInfo->deviceId = NULL;
773     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
774     int32_t ret = NSTACKX_RegisterDeviceV2(dupInfo);
775     FreeLocalDeviceInfo(dupInfo);
776     DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP,
777         "register local device info to dfinder failed, ret=%{public}d", ret);
778     DiscCoapUpdateDevName();
779 }
780 
DiscCoapUpdateLocalIp(LinkStatus status,int32_t ifnameIdx)781 void DiscCoapUpdateLocalIp(LinkStatus status, int32_t ifnameIdx)
782 {
783     DISC_CHECK_AND_RETURN_LOGE(status == LINK_STATUS_UP || status == LINK_STATUS_DOWN, DISC_COAP,
784         "invlaid link status, status=%{public}d.", status);
785     DISC_CHECK_AND_RETURN_LOGE(ifnameIdx >= 0 && ifnameIdx <= MAX_IF, DISC_COAP,
786         "invlaid ifnameIdx, ifnameIdx=%{public}d.", ifnameIdx);
787 
788     DISC_CHECK_AND_RETURN_LOGE(SetLocalDeviceInfo(status, ifnameIdx) == SOFTBUS_OK, DISC_COAP,
789         "link status change: set local device info failed");
790 
791     int64_t accountId = 0;
792     int32_t port = 0;
793     int32_t ret = LnnGetLocalNum64Info(NUM_KEY_ACCOUNT_LONG, &accountId);
794     DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "get local account failed, err=%{public}d", ret);
795     ret = LnnGetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, &port, ifnameIdx);
796     DISC_CHECK_AND_RETURN_LOGE(ret != SOFTBUS_INVALID_PARAM, DISC_COAP, "get local port failed, err=%{public}d", ret);
797     DISC_LOGI(DISC_COAP, "register ifname=%{public}s. status=%{public}s, port=%{public}d, accountInfo=%{public}s",
798         g_localDeviceInfo->localIfInfo->networkName, status == LINK_STATUS_UP ? "up" : "down", port,
799         accountId == 0 ? "without" : "with");
800     UpdateLocalIpByLocalNumInfo(accountId, port);
801 }
802 
DiscCoapUpdateDevName(void)803 void DiscCoapUpdateDevName(void)
804 {
805     char localDevName[DEVICE_NAME_BUF_LEN] = { 0 };
806     int32_t ret = LnnGetLocalStrInfo(STRING_KEY_DEV_NAME, localDevName, sizeof(localDevName));
807     DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "get local device name failed, ret=%{public}d.", ret);
808 
809     uint32_t truncateLen = 0;
810     if (CalculateMbsTruncateSize((const char *)localDevName, NSTACKX_MAX_DEVICE_NAME_LEN - 1, &truncateLen)
811         != SOFTBUS_OK) {
812         DISC_LOGE(DISC_COAP, "truncate device name failed");
813         return;
814     }
815     localDevName[truncateLen] = '\0';
816     char *anonymizedName = NULL;
817     AnonymizeDeviceName(localDevName, &anonymizedName);
818     DISC_LOGI(DISC_COAP, "register new local device name. localDevName=%{public}s", AnonymizeWrapper(anonymizedName));
819     AnonymizeFree(anonymizedName);
820     ret = NSTACKX_RegisterDeviceName(localDevName);
821     DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "register local device name failed, ret=%{public}d.", ret);
822 }
823 
DiscCoapUpdateAccount(void)824 void DiscCoapUpdateAccount(void)
825 {
826     DISC_LOGI(DISC_COAP, "accountId change, register new local accountId.");
827     int64_t accountId = 0;
828     int32_t ret = LnnGetLocalNum64Info(NUM_KEY_ACCOUNT_LONG, &accountId);
829     DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "get local account failed");
830     NSTACKX_RegisterDeviceHash((uint64_t)accountId);
831 }
832 
DeinitLocalInfo(void)833 static void DeinitLocalInfo(void)
834 {
835     DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
836     if (g_localDeviceInfo != NULL && g_localDeviceInfo->localIfInfo != NULL) {
837         SoftBusFree(g_localDeviceInfo->localIfInfo);
838         g_localDeviceInfo->localIfInfo = NULL;
839     }
840     if (g_localDeviceInfo != NULL) {
841         SoftBusFree(g_localDeviceInfo);
842         g_localDeviceInfo = NULL;
843     }
844     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
845 
846     DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_discCoapInnerCbLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
847     if (g_discCoapInnerCb != NULL) {
848         SoftBusFree(g_discCoapInnerCb);
849         g_discCoapInnerCb = NULL;
850     }
851     (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
852 
853     (void)SoftBusMutexDestroy(&g_localDeviceInfoLock);
854     (void)SoftBusMutexDestroy(&g_discCoapInnerCbLock);
855 }
856 
InitLocalInfo(void)857 static int32_t InitLocalInfo(void)
858 {
859     if (SoftBusMutexInit(&g_localDeviceInfoLock, NULL) != SOFTBUS_OK) {
860         DISC_LOGE(DISC_COAP, "g_localDeviceInfoLock init failed");
861         return SOFTBUS_NO_INIT;
862     }
863     if (SoftBusMutexInit(&g_discCoapInnerCbLock, NULL) != SOFTBUS_OK) {
864         DISC_LOGE(DISC_COAP, "g_discCoapInnerCbLock init failed");
865         (void)SoftBusMutexDestroy(&g_localDeviceInfoLock);
866         return SOFTBUS_NO_INIT;
867     }
868 
869     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
870         DISC_COAP, "lock failed");
871     if (g_localDeviceInfo == NULL) {
872         g_localDeviceInfo = (NSTACKX_LocalDeviceInfoV2 *)SoftBusCalloc(sizeof(NSTACKX_LocalDeviceInfoV2));
873         if (g_localDeviceInfo == NULL) {
874             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
875             DeinitLocalInfo();
876             return SOFTBUS_MEM_ERR;
877         }
878         g_localDeviceInfo->localIfInfo = (NSTACKX_InterfaceInfo *)SoftBusCalloc(sizeof(NSTACKX_InterfaceInfo));
879         if (g_localDeviceInfo->localIfInfo == NULL) {
880             (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
881             DISC_LOGE(DISC_COAP, "mem local If info failed");
882             DeinitLocalInfo();
883             return SOFTBUS_MEM_ERR;
884         }
885     }
886     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
887 
888     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_discCoapInnerCbLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
889         DISC_COAP, "lock failed");
890     if (g_discCoapInnerCb == NULL) {
891         g_discCoapInnerCb = (DiscInnerCallback *)SoftBusCalloc(sizeof(DiscInnerCallback));
892         if (g_discCoapInnerCb == NULL) {
893             (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
894             DeinitLocalInfo();
895             return SOFTBUS_MEM_ERR;
896         }
897     }
898     (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
899     return SOFTBUS_OK;
900 }
901 
DiscNstackxInit(void)902 int32_t DiscNstackxInit(void)
903 {
904     if (InitLocalInfo() != SOFTBUS_OK) {
905         return SOFTBUS_DISCOVER_COAP_INIT_FAIL;
906     }
907 
908     NSTACKX_DFinderRegisterLog(NstackxLogInnerImpl);
909     if (SoftbusGetConfig(SOFTBUS_INT_DISC_COAP_MAX_DEVICE_NUM, (unsigned char *)&g_nstackxCallBack.maxDeviceNum,
910         sizeof(g_nstackxCallBack.maxDeviceNum)) != SOFTBUS_OK) {
911         DISC_LOGI(DISC_COAP, "get disc max device num config failed, use default %{public}u", DEFAULT_MAX_DEVICE_NUM);
912         g_nstackxCallBack.maxDeviceNum = DEFAULT_MAX_DEVICE_NUM;
913     }
914     if (NSTACKX_Init(&g_nstackxCallBack) != SOFTBUS_OK) {
915         DeinitLocalInfo();
916         return SOFTBUS_DISCOVER_COAP_INIT_FAIL;
917     }
918     SoftBusRegDiscVarDump((char *)NSTACKX_LOCAL_DEV_INFO, &NstackxLocalDevInfoDump);
919     return SOFTBUS_OK;
920 }
921 
DiscNstackxDeinit(void)922 void DiscNstackxDeinit(void)
923 {
924     NSTACKX_Deinit();
925     DeinitLocalInfo();
926 }
927 
NstackxLocalDevInfoDump(int fd)928 static int32_t NstackxLocalDevInfoDump(int fd)
929 {
930     char *anonymizedInfo = NULL;
931     DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
932         DISC_COAP, "lock failed");
933     SOFTBUS_DPRINTF(fd, "\n-----------------NstackxLocalDevInfo-------------------\n");
934     SOFTBUS_DPRINTF(fd, "name                                : %s\n", g_localDeviceInfo->name);
935     Anonymize(g_localDeviceInfo->deviceId, &anonymizedInfo);
936     SOFTBUS_DPRINTF(fd, "deviceId                            : %s\n", AnonymizeWrapper(anonymizedInfo));
937     AnonymizeFree(anonymizedInfo);
938     Anonymize(g_localDeviceInfo->localIfInfo->networkName, &anonymizedInfo);
939     SOFTBUS_DPRINTF(fd, "localIfInfo networkName             : %s\n", AnonymizeWrapper(anonymizedInfo));
940     AnonymizeFree(anonymizedInfo);
941     SOFTBUS_DPRINTF(fd, "ifNums                              : %d\n", g_localDeviceInfo->ifNums);
942     SOFTBUS_DPRINTF(fd, "deviceType                          : %d\n", g_localDeviceInfo->deviceType);
943     SOFTBUS_DPRINTF(fd, "businessType                        : %d\n", g_localDeviceInfo->businessType);
944     (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
945 
946     return SOFTBUS_OK;
947 }