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 }