1 /*
2 * Copyright (c) 2021-2024 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.h"
28 #include "disc_coap_parser.h"
29 #include "disc_log.h"
30 #include "securec.h"
31 #include "softbus_adapter_mem.h"
32 #include "softbus_adapter_thread.h"
33 #include "softbus_def.h"
34 #include "softbus_errcode.h"
35 #include "softbus_feature_config.h"
36 #include "softbus_hidumper_disc.h"
37 #include "softbus_hisysevt_discreporter.h"
38 #include "softbus_json_utils.h"
39 #include "softbus_utils.h"
40
41 #define WLAN_IFACE_NAME_PREFIX "wlan"
42 #define INVALID_IP_ADDR "0.0.0.0"
43 #define LOOPBACK_IP_ADDR "127.0.0.1"
44 #define DISC_FREQ_COUNT_MASK 0xFFFF
45 #define DISC_FREQ_DURATION_BIT 16
46 #define DISC_USECOND 1000
47 #define MULTI_BYTE_CHAR_LEN 8
48 #define MAX_WIDE_STR_LEN 128
49 #define DEFAULT_MAX_DEVICE_NUM 20
50
51 #define NSTACKX_LOCAL_DEV_INFO "NstackxLocalDevInfo"
52
53 static NSTACKX_LocalDeviceInfo *g_localDeviceInfo = NULL;
54 static DiscInnerCallback *g_discCoapInnerCb = NULL;
55 static SoftBusMutex g_localDeviceInfoLock = {0};
56 static SoftBusMutex g_discCoapInnerCbLock = {0};
57 static int32_t NstackxLocalDevInfoDump(int fd);
58
FillRspSettings(NSTACKX_ResponseSettings * settings,const DeviceInfo * deviceInfo,uint8_t bType)59 static int32_t FillRspSettings(NSTACKX_ResponseSettings *settings, const DeviceInfo *deviceInfo, uint8_t bType)
60 {
61 settings->businessData = NULL;
62 settings->length = 0;
63 settings->businessType = bType;
64 char localNetifName[NET_IF_NAME_LEN] = {0};
65 int32_t ret = LnnGetLocalStrInfo(STRING_KEY_NET_IF_NAME, localNetifName, sizeof(localNetifName));
66 if (ret != SOFTBUS_OK) {
67 DISC_LOGE(DISC_COAP, "get local network name from LNN failed, ret=%{public}d", ret);
68 return ret;
69 }
70 if (strcpy_s(settings->localNetworkName, sizeof(settings->localNetworkName), localNetifName) != EOK) {
71 DISC_LOGE(DISC_COAP, "copy disc response settings network name failed");
72 goto EXIT;
73 }
74 if (strcpy_s(settings->remoteIp, sizeof(settings->remoteIp), deviceInfo->addr[0].info.ip.ip) != EOK) {
75 DISC_LOGE(DISC_COAP, "copy disc response settings remote IP failed");
76 goto EXIT;
77 }
78 return SOFTBUS_OK;
79 EXIT:
80 return SOFTBUS_STRCPY_ERR;
81 }
82
DiscCoapSendRsp(const DeviceInfo * deviceInfo,uint8_t bType)83 int32_t DiscCoapSendRsp(const DeviceInfo *deviceInfo, uint8_t bType)
84 {
85 DISC_CHECK_AND_RETURN_RET_LOGE(deviceInfo, SOFTBUS_INVALID_PARAM, DISC_COAP, "DiscRsp devInfo is null");
86 NSTACKX_ResponseSettings *settings = (NSTACKX_ResponseSettings *)SoftBusCalloc(sizeof(NSTACKX_ResponseSettings));
87 DISC_CHECK_AND_RETURN_RET_LOGE(settings, SOFTBUS_MALLOC_ERR, DISC_COAP, "malloc disc response settings failed");
88
89 int32_t ret = FillRspSettings(settings, deviceInfo, bType);
90 if (ret != SOFTBUS_OK) {
91 DISC_LOGE(DISC_COAP, "fill nstackx response settings failed");
92 SoftBusFree(settings);
93 return ret;
94 }
95
96 DISC_LOGI(DISC_COAP, "send rsp with bType=%{public}u", bType);
97 ret = NSTACKX_SendDiscoveryRsp(settings);
98 if (ret != SOFTBUS_OK) {
99 DISC_LOGE(DISC_COAP, "disc send response failed, ret=%{public}d", ret);
100 }
101 SoftBusFree(settings);
102 return ret;
103 }
104
ParseReservedInfo(const NSTACKX_DeviceInfo * nstackxDevice,DeviceInfo * device)105 static int32_t ParseReservedInfo(const NSTACKX_DeviceInfo *nstackxDevice, DeviceInfo *device)
106 {
107 cJSON *reserveInfo = cJSON_Parse(nstackxDevice->reservedInfo);
108 DISC_CHECK_AND_RETURN_RET_LOGE(reserveInfo != NULL, SOFTBUS_PARSE_JSON_ERR, DISC_COAP,
109 "parse reserve data failed.");
110
111 DiscCoapParseWifiIpAddr(reserveInfo, device);
112 DiscCoapParseHwAccountHash(reserveInfo, device);
113 if (DiscCoapParseServiceData(reserveInfo, device) != SOFTBUS_OK) {
114 DISC_LOGD(DISC_COAP, "parse service data failed");
115 }
116 cJSON_Delete(reserveInfo);
117 return SOFTBUS_OK;
118 }
119
ParseDiscDevInfo(const NSTACKX_DeviceInfo * nstackxDevInfo,DeviceInfo * discDevInfo)120 static int32_t ParseDiscDevInfo(const NSTACKX_DeviceInfo *nstackxDevInfo, DeviceInfo *discDevInfo)
121 {
122 if (strcpy_s(discDevInfo->devName, sizeof(discDevInfo->devName), nstackxDevInfo->deviceName) != EOK ||
123 memcpy_s(discDevInfo->capabilityBitmap, sizeof(discDevInfo->capabilityBitmap),
124 nstackxDevInfo->capabilityBitmap, sizeof(nstackxDevInfo->capabilityBitmap)) != EOK) {
125 DISC_LOGE(DISC_COAP, "strcpy_s devName or memcpy_s capabilityBitmap failed.");
126 return SOFTBUS_MEM_ERR;
127 }
128
129 discDevInfo->devType = (DeviceType)nstackxDevInfo->deviceType;
130 discDevInfo->capabilityBitmapNum = nstackxDevInfo->capabilityBitmapNum;
131
132 if (strncmp(nstackxDevInfo->networkName, WLAN_IFACE_NAME_PREFIX, strlen(WLAN_IFACE_NAME_PREFIX)) == 0) {
133 discDevInfo->addr[0].type = CONNECTION_ADDR_WLAN;
134 } else {
135 discDevInfo->addr[0].type = CONNECTION_ADDR_ETH;
136 }
137
138 int32_t ret = DiscCoapParseDeviceUdid(nstackxDevInfo->deviceId, discDevInfo);
139 if (ret != SOFTBUS_OK) {
140 DISC_LOGE(DISC_COAP, "parse device udid failed.");
141 return ret;
142 }
143
144 ret = ParseReservedInfo(nstackxDevInfo, discDevInfo);
145 if (ret != SOFTBUS_OK) {
146 DISC_LOGE(DISC_COAP, "parse reserve information failed.");
147 return ret;
148 }
149 // coap not support range now, just assign -1 as unknown
150 discDevInfo->range = -1;
151
152 return SOFTBUS_OK;
153 }
154
OnDeviceFound(const NSTACKX_DeviceInfo * deviceList,uint32_t deviceCount)155 static void OnDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
156 {
157 DISC_CHECK_AND_RETURN_LOGE(deviceList != NULL && deviceCount != 0, DISC_COAP, "invalid param.");
158 DISC_LOGD(DISC_COAP, "Disc device found, count=%{public}u", deviceCount);
159 DeviceInfo *discDeviceInfo = (DeviceInfo *)SoftBusCalloc(sizeof(DeviceInfo));
160 DISC_CHECK_AND_RETURN_LOGE(discDeviceInfo != NULL, DISC_COAP, "malloc device info failed.");
161
162 int32_t ret;
163 for (uint32_t i = 0; i < deviceCount; i++) {
164 const NSTACKX_DeviceInfo *nstackxDeviceInfo = deviceList + i;
165 if (nstackxDeviceInfo == NULL) {
166 DISC_LOGE(DISC_COAP, "device count from nstackx is invalid");
167 SoftBusFree(discDeviceInfo);
168 return;
169 }
170
171 if ((nstackxDeviceInfo->update & 0x1) == 0) {
172 char *anonymizedName = NULL;
173 Anonymize(nstackxDeviceInfo->deviceName, &anonymizedName);
174 DISC_LOGI(DISC_COAP, "duplicate device do not need report. deviceName=%{public}s",
175 AnonymizeWrapper(anonymizedName));
176 AnonymizeFree(anonymizedName);
177 continue;
178 }
179 (void)memset_s(discDeviceInfo, sizeof(DeviceInfo), 0, sizeof(DeviceInfo));
180 ret = ParseDiscDevInfo(nstackxDeviceInfo, discDeviceInfo);
181 if (ret != SOFTBUS_OK) {
182 DISC_LOGW(DISC_COAP, "parse discovery device info failed.");
183 continue;
184 }
185 ret = DiscCoapProcessDeviceInfo(nstackxDeviceInfo, discDeviceInfo, g_discCoapInnerCb,
186 &g_discCoapInnerCbLock);
187 if (ret != SOFTBUS_OK) {
188 DISC_LOGD(DISC_COAP, "DiscRecv: process device info failed, ret=%{public}d", ret);
189 }
190 }
191
192 SoftBusFree(discDeviceInfo);
193 }
194
OnNotificationReceived(const NSTACKX_NotificationConfig * notification)195 static void OnNotificationReceived(const NSTACKX_NotificationConfig *notification)
196 {
197 DiscCoapReportNotification(notification);
198 }
199
200 static NSTACKX_Parameter g_nstackxCallBack = {
201 .onDeviceListChanged = OnDeviceFound,
202 .onDeviceFound = NULL,
203 .onMsgReceived = NULL,
204 .onDFinderMsgReceived = NULL,
205 .onNotificationReceived = OnNotificationReceived,
206 };
207
DiscCoapRegisterCb(const DiscInnerCallback * discCoapCb)208 int32_t DiscCoapRegisterCb(const DiscInnerCallback *discCoapCb)
209 {
210 DISC_CHECK_AND_RETURN_RET_LOGE(discCoapCb != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "invalid param");
211 DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_discCoapInnerCbLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
212 DISC_COAP, "lock failed");
213 if (g_discCoapInnerCb == NULL) {
214 DISC_LOGE(DISC_COAP, "coap inner callback not init.");
215 (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
216 return SOFTBUS_DISCOVER_COAP_NOT_INIT;
217 }
218 if (memcpy_s(g_discCoapInnerCb, sizeof(DiscInnerCallback), discCoapCb, sizeof(DiscInnerCallback)) != EOK) {
219 DISC_LOGE(DISC_COAP, "memcpy_s failed.");
220 (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
221 return SOFTBUS_MEM_ERR;
222 }
223 (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
224 return SOFTBUS_OK;
225 }
226
DiscCoapRegisterCapability(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[])227 int32_t DiscCoapRegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
228 {
229 DISC_CHECK_AND_RETURN_RET_LOGE(capabilityBitmapNum != 0, SOFTBUS_INVALID_PARAM,
230 DISC_COAP, "capabilityBitmapNum=0");
231
232 if (NSTACKX_RegisterCapability(capabilityBitmapNum, capabilityBitmap) != SOFTBUS_OK) {
233 DISC_LOGE(DISC_COAP, "NSTACKX Register Capability failed");
234 return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL;
235 }
236 return SOFTBUS_OK;
237 }
238
DiscCoapSetFilterCapability(uint32_t capabilityBitmapNum,uint32_t capabilityBitmap[])239 int32_t DiscCoapSetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
240 {
241 DISC_CHECK_AND_RETURN_RET_LOGE(capabilityBitmapNum != 0, SOFTBUS_INVALID_PARAM,
242 DISC_COAP, "capabilityBitmapNum=0");
243
244 if (NSTACKX_SetFilterCapability(capabilityBitmapNum, capabilityBitmap) != SOFTBUS_OK) {
245 DISC_LOGE(DISC_COAP, "NSTACKX SetFilter Capability failed");
246 SoftbusReportDiscFault(SOFTBUS_HISYSEVT_DISC_MEDIUM_COAP, SOFTBUS_HISYSEVT_DISCOVER_COAP_SET_FILTER_CAP_FAIL);
247 return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL;
248 }
249 return SOFTBUS_OK;
250 }
251
DiscCoapRegisterServiceData(const PublishOption * option,uint32_t allCap)252 int32_t DiscCoapRegisterServiceData(const PublishOption *option, uint32_t allCap)
253 {
254 int32_t authPort = 0;
255 int32_t ret = LnnGetLocalNumInfo(NUM_KEY_AUTH_PORT, &authPort);
256 if (ret != SOFTBUS_OK) {
257 DISC_LOGW(DISC_COAP, "get auth port from lnn failed. ret=%{public}d", ret);
258 }
259
260 char serviceData[NSTACKX_MAX_SERVICE_DATA_LEN] = {0};
261 if (sprintf_s(serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, "port:%d,", authPort) == -1) {
262 DISC_LOGE(DISC_COAP, "write auth port to service data failed.");
263 return SOFTBUS_STRCPY_ERR;
264 }
265 // capabilityData can be NULL, it will be check in this func
266 ret = DiscCoapFillServiceData(option, serviceData, NSTACKX_MAX_SERVICE_DATA_LEN, allCap);
267 DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "fill service data failed. ret=%{public}d", ret);
268
269 ret = NSTACKX_RegisterServiceData(serviceData);
270 DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
271 "register service data to nstackx failed. ret=%{public}d", ret);
272 return SOFTBUS_OK;
273 }
274
DiscCoapRegisterCapabilityData(const unsigned char * capabilityData,uint32_t dataLen,uint32_t capability)275 int32_t DiscCoapRegisterCapabilityData(const unsigned char *capabilityData, uint32_t dataLen, uint32_t capability)
276 {
277 if (capabilityData == NULL || dataLen == 0) {
278 // no capability data, no need to parse and register
279 return SOFTBUS_OK;
280 }
281 char *registerCapaData = (char *)SoftBusCalloc(MAX_CAPABILITYDATA_LEN);
282 DISC_CHECK_AND_RETURN_RET_LOGE(registerCapaData, SOFTBUS_MALLOC_ERR, DISC_COAP, "malloc capability data failed");
283 int32_t ret = DiscCoapAssembleCapData(capability, (const char *)capabilityData, dataLen, registerCapaData,
284 DISC_MAX_CUST_DATA_LEN);
285 if (ret == SOFTBUS_FUNC_NOT_SUPPORT) {
286 DISC_LOGI(DISC_COAP, "the capability not support yet. capability=%{public}u", capability);
287 SoftBusFree(registerCapaData);
288 return SOFTBUS_OK;
289 }
290 if (ret != SOFTBUS_OK) {
291 DISC_LOGE(DISC_COAP, "assemble the data of capability failed. capability=%{public}u", capability);
292 SoftBusFree(registerCapaData);
293 return ret;
294 }
295
296 if (NSTACKX_RegisterExtendServiceData(registerCapaData) != SOFTBUS_OK) {
297 DISC_LOGE(DISC_COAP, "register extend service data to nstackx failed");
298 SoftBusFree(registerCapaData);
299 return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_DATA_FAIL;
300 }
301 DISC_LOGI(DISC_COAP, "register extend service data to nstackx succ.");
302 SoftBusFree(registerCapaData);
303 return SOFTBUS_OK;
304 }
305
IsNetworkValid(void)306 static bool IsNetworkValid(void)
307 {
308 char localIp[IP_LEN] = {0};
309 if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, IP_LEN) != SOFTBUS_OK) {
310 DISC_LOGE(DISC_COAP, "get local ip failed");
311 return false;
312 }
313 if (strcmp(localIp, LOOPBACK_IP_ADDR) == 0 ||
314 strcmp(localIp, INVALID_IP_ADDR) == 0 ||
315 strcmp(localIp, "") == 0) {
316 DISC_LOGE(DISC_COAP, "invalid localIp: loopback or null");
317 return false;
318 }
319 return true;
320 }
321
GetDiscFreq(int32_t freq,uint32_t * discFreq)322 static int32_t GetDiscFreq(int32_t freq, uint32_t *discFreq)
323 {
324 uint32_t arrayFreq[FREQ_BUTT] = {0};
325 int32_t ret = SoftbusGetConfig(SOFTBUS_INT_DISC_FREQ, (unsigned char *)arrayFreq, sizeof(arrayFreq));
326 if (ret != SOFTBUS_OK) {
327 DISC_LOGE(DISC_COAP, "disc get freq failed");
328 return ret;
329 }
330 *discFreq = arrayFreq[freq];
331 return SOFTBUS_OK;
332 }
333
ConvertDiscoverySettings(NSTACKX_DiscoverySettings * discSet,const DiscCoapOption * option)334 static int32_t ConvertDiscoverySettings(NSTACKX_DiscoverySettings *discSet, const DiscCoapOption *option)
335 {
336 if (option->mode == ACTIVE_PUBLISH) {
337 discSet->discoveryMode = PUBLISH_MODE_PROACTIVE;
338 } else {
339 discSet->discoveryMode = DISCOVER_MODE;
340 }
341 uint32_t discFreq;
342 int32_t ret = GetDiscFreq(option->freq, &discFreq);
343 if (ret != SOFTBUS_OK) {
344 DISC_LOGE(DISC_COAP, "get discovery freq config failed");
345 return ret;
346 }
347 discSet->advertiseCount = discFreq & DISC_FREQ_COUNT_MASK;
348 discSet->advertiseDuration = (discFreq >> DISC_FREQ_DURATION_BIT) * DISC_USECOND;
349 DiscFillBtype(option->capability, option->allCap, discSet);
350 return SOFTBUS_OK;
351 }
352
FreeDiscSet(NSTACKX_DiscoverySettings * discSet)353 static void FreeDiscSet(NSTACKX_DiscoverySettings *discSet)
354 {
355 if (discSet != NULL) {
356 SoftBusFree(discSet->businessData);
357 SoftBusFree(discSet);
358 }
359 }
360
DiscCoapStartDiscovery(DiscCoapOption * option)361 int32_t DiscCoapStartDiscovery(DiscCoapOption *option)
362 {
363 DISC_CHECK_AND_RETURN_RET_LOGE(option != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "option is null.");
364 DISC_CHECK_AND_RETURN_RET_LOGE(option->mode >= ACTIVE_PUBLISH && option->mode <= ACTIVE_DISCOVERY,
365 SOFTBUS_INVALID_PARAM, DISC_COAP, "option->mode is invalid");
366 DISC_CHECK_AND_RETURN_RET_LOGE(LOW <= option->freq && option->freq < FREQ_BUTT, SOFTBUS_INVALID_PARAM,
367 DISC_COAP, "invalid freq. freq=%{public}d", option->freq);
368 DISC_CHECK_AND_RETURN_RET_LOGE(IsNetworkValid(), SOFTBUS_NETWORK_NOT_FOUND, DISC_COAP, "netif not works");
369
370 NSTACKX_DiscoverySettings *discSet = (NSTACKX_DiscoverySettings *)SoftBusCalloc(sizeof(NSTACKX_DiscoverySettings));
371 DISC_CHECK_AND_RETURN_RET_LOGE(discSet != NULL, SOFTBUS_MEM_ERR, DISC_COAP, "malloc disc settings failed");
372
373 int32_t ret = ConvertDiscoverySettings(discSet, option);
374 if (ret != SOFTBUS_OK) {
375 DISC_LOGE(DISC_COAP, "set discovery settings failed");
376 FreeDiscSet(discSet);
377 return ret;
378 }
379 if (NSTACKX_StartDeviceDiscovery(discSet) != SOFTBUS_OK) {
380 DISC_LOGE(DISC_COAP, "start device discovery failed");
381 FreeDiscSet(discSet);
382 return (option->mode == ACTIVE_PUBLISH) ? SOFTBUS_DISCOVER_COAP_START_PUBLISH_FAIL :
383 SOFTBUS_DISCOVER_COAP_START_DISCOVER_FAIL;
384 }
385 FreeDiscSet(discSet);
386 return SOFTBUS_OK;
387 }
388
DiscCoapStopDiscovery(void)389 int32_t DiscCoapStopDiscovery(void)
390 {
391 if (NSTACKX_StopDeviceFind() != SOFTBUS_OK) {
392 DISC_LOGE(DISC_COAP, "stop device discovery failed");
393 return SOFTBUS_DISCOVER_COAP_STOP_DISCOVER_FAIL;
394 }
395
396 return SOFTBUS_OK;
397 }
398
GetDeviceId(void)399 static char *GetDeviceId(void)
400 {
401 char *formatString = NULL;
402 char udid[UDID_BUF_LEN] = {0};
403 int32_t ret = LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, sizeof(udid));
404 if (ret != SOFTBUS_OK) {
405 DISC_LOGE(DISC_COAP, "get udid failed, ret=%{public}d", ret);
406 return NULL;
407 }
408 cJSON *deviceId = cJSON_CreateObject();
409 DISC_CHECK_AND_RETURN_RET_LOGW(deviceId != NULL, NULL, DISC_COAP, "create json object failed: deviceId=NULL");
410
411 if (!AddStringToJsonObject(deviceId, DEVICE_UDID, udid)) {
412 DISC_LOGE(DISC_COAP, "add udid to device id json object failed.");
413 goto GET_DEVICE_ID_END;
414 }
415 formatString = cJSON_PrintUnformatted(deviceId);
416 if (formatString == NULL) {
417 DISC_LOGE(DISC_COAP, "format device id json object failed.");
418 }
419
420 GET_DEVICE_ID_END:
421 cJSON_Delete(deviceId);
422 return formatString;
423 }
424
SetLocalDeviceInfo(void)425 static int32_t SetLocalDeviceInfo(void)
426 {
427 DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
428 DISC_COAP, "lock failed");
429 if (g_localDeviceInfo == NULL) {
430 DISC_LOGE(DISC_COAP, "disc coap not init");
431 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
432 return SOFTBUS_DISCOVER_COAP_NOT_INIT;
433 }
434 int32_t res = memset_s(g_localDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo), 0, sizeof(NSTACKX_LocalDeviceInfo));
435 if (res != EOK) {
436 DISC_LOGE(DISC_COAP, "memset_s local device info failed");
437 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
438 return SOFTBUS_MEM_ERR;
439 }
440
441 char *deviceIdStr = GetDeviceId();
442 if (deviceIdStr == NULL) {
443 DISC_LOGE(DISC_COAP, "get device id string failed.");
444 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
445 return SOFTBUS_DISCOVER_COAP_GET_DEVICE_INFO_FAIL;
446 }
447
448 if (strcpy_s(g_localDeviceInfo->deviceId, sizeof(g_localDeviceInfo->deviceId), deviceIdStr) != EOK) {
449 cJSON_free(deviceIdStr);
450 DISC_LOGE(DISC_COAP, "strcpy_s deviceId failed.");
451 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
452 return SOFTBUS_STRCPY_ERR;
453 }
454 cJSON_free(deviceIdStr);
455 int32_t deviceType = 0;
456 int32_t ret = LnnGetLocalNumInfo(NUM_KEY_DEV_TYPE_ID, &deviceType);
457 if (ret != SOFTBUS_OK) {
458 DISC_LOGE(DISC_COAP, "get local device type failed.");
459 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
460 return ret;
461 }
462 g_localDeviceInfo->deviceType = (uint32_t)deviceType;
463 g_localDeviceInfo->businessType = (uint8_t)NSTACKX_BUSINESS_TYPE_NULL;
464 if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, g_localDeviceInfo->localIfInfo[0].networkIpAddr,
465 sizeof(g_localDeviceInfo->localIfInfo[0].networkIpAddr)) != SOFTBUS_OK ||
466 LnnGetLocalStrInfo(STRING_KEY_HICE_VERSION, g_localDeviceInfo->version, sizeof(g_localDeviceInfo->version)) !=
467 SOFTBUS_OK ||
468 LnnGetLocalStrInfo(STRING_KEY_NET_IF_NAME, g_localDeviceInfo->localIfInfo[0].networkName,
469 sizeof(g_localDeviceInfo->localIfInfo[0].networkName)) != SOFTBUS_OK) {
470 DISC_LOGE(DISC_COAP, "get local device info from lnn failed.");
471 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
472 return SOFTBUS_DISCOVER_GET_LOCAL_STR_FAILED;
473 }
474 g_localDeviceInfo->ifNums = 1;
475
476 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
477 return SOFTBUS_OK;
478 }
479
DiscCoapUpdateLocalIp(LinkStatus status)480 void DiscCoapUpdateLocalIp(LinkStatus status)
481 {
482 DISC_CHECK_AND_RETURN_LOGE(status == LINK_STATUS_UP || status == LINK_STATUS_DOWN, DISC_COAP,
483 "invlaid link status, status=%{public}d.", status);
484
485 if (status == LINK_STATUS_DOWN) {
486 DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
487 if (strcpy_s(g_localDeviceInfo->localIfInfo[0].networkIpAddr,
488 sizeof(g_localDeviceInfo->localIfInfo[0].networkIpAddr), INVALID_IP_ADDR) != EOK) {
489 DISC_LOGE(DISC_COAP, "link status down: strcpy_s networkIpAddr failed.");
490 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
491 return;
492 }
493 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
494 } else {
495 DISC_CHECK_AND_RETURN_LOGE(SetLocalDeviceInfo() == SOFTBUS_OK, DISC_COAP,
496 "link status up: set local device info failed");
497 }
498
499 int64_t accountId = 0;
500 int32_t ret = LnnGetLocalNum64Info(NUM_KEY_ACCOUNT_LONG, &accountId);
501 DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "get local account failed");
502 DISC_LOGI(DISC_COAP, "register local device info. status=%{public}s, accountInfo=%{public}s",
503 status == LINK_STATUS_UP ? "up" : "down", accountId == 0 ? "without" : "with");
504 DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
505 ret = NSTACKX_RegisterDeviceAn(g_localDeviceInfo, (uint64_t)accountId);
506 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
507 DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "register local device info to dfinder failed");
508 DiscCoapUpdateDevName();
509 }
510
SetLocale(char ** localeBefore)511 static int32_t SetLocale(char **localeBefore)
512 {
513 *localeBefore = setlocale(LC_CTYPE, NULL);
514 if (*localeBefore == NULL) {
515 DISC_LOGW(DISC_COAP, "get locale failed");
516 }
517
518 char *localeAfter = setlocale(LC_CTYPE, "C.UTF-8");
519 return (localeAfter != NULL) ? SOFTBUS_OK : SOFTBUS_DISCOVER_SET_LOCALE_FAILED;
520 }
521
RestoreLocale(const char * localeBefore)522 static void RestoreLocale(const char *localeBefore)
523 {
524 if (setlocale(LC_CTYPE, localeBefore) == NULL) {
525 DISC_LOGW(DISC_COAP, "restore locale failed");
526 }
527 }
528
CalculateMbsTruncateSize(const char * multiByteStr,uint32_t capacity,uint32_t * truncatedSize)529 static int32_t CalculateMbsTruncateSize(const char *multiByteStr, uint32_t capacity, uint32_t *truncatedSize)
530 {
531 size_t multiByteStrLen = strlen(multiByteStr);
532 if (multiByteStrLen == 0) {
533 *truncatedSize = 0;
534 return SOFTBUS_OK;
535 }
536 DISC_CHECK_AND_RETURN_RET_LOGE(multiByteStrLen <= MAX_WIDE_STR_LEN, SOFTBUS_INVALID_PARAM, DISC_COAP,
537 "multi byte str too long: %zu", multiByteStrLen);
538
539 char *localeBefore = NULL;
540 int32_t ret = SetLocale(&localeBefore);
541 DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "set locale failed");
542
543 // convert multi byte str to wide str
544 wchar_t wideStr[MAX_WIDE_STR_LEN] = {0};
545 size_t numConverted = mbstowcs(wideStr, multiByteStr, multiByteStrLen);
546 if (numConverted <= 0 || numConverted > INT32_MAX) {
547 DISC_LOGE(DISC_COAP, "mbstowcs failed");
548 RestoreLocale(localeBefore);
549 return SOFTBUS_DISCOVER_CHAR_CONVERT_FAILED;
550 }
551
552 uint32_t truncateTotal = 0;
553 int32_t truncateIndex = (int32_t)numConverted - 1;
554 char multiByteChar[MULTI_BYTE_CHAR_LEN] = {0};
555 while (capacity < multiByteStrLen - truncateTotal && truncateIndex >= 0) {
556 int32_t truncateCharLen = wctomb(multiByteChar, wideStr[truncateIndex]);
557 if (truncateCharLen <= 0) {
558 DISC_LOGE(DISC_COAP, "wctomb failed");
559 RestoreLocale(localeBefore);
560 return SOFTBUS_DISCOVER_CHAR_CONVERT_FAILED;
561 }
562 truncateTotal += (uint32_t)truncateCharLen;
563 truncateIndex--;
564 }
565
566 *truncatedSize = (multiByteStrLen >= truncateTotal) ? (multiByteStrLen - truncateTotal) : 0;
567 RestoreLocale(localeBefore);
568 return SOFTBUS_OK;
569 }
570
DiscCoapUpdateDevName(void)571 void DiscCoapUpdateDevName(void)
572 {
573 char localDevName[DEVICE_NAME_BUF_LEN] = {0};
574 int32_t ret = LnnGetLocalStrInfo(STRING_KEY_DEV_NAME, localDevName, sizeof(localDevName));
575 DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "get local device name failed, ret=%{public}d.", ret);
576
577 uint32_t truncateLen = 0;
578 if (CalculateMbsTruncateSize((const char *)localDevName, NSTACKX_MAX_DEVICE_NAME_LEN - 1, &truncateLen)
579 != SOFTBUS_OK) {
580 DISC_LOGE(DISC_COAP, "truncate device name failed");
581 return;
582 }
583 localDevName[truncateLen] = '\0';
584 char *anonymizedName = NULL;
585 Anonymize(localDevName, &anonymizedName);
586 DISC_LOGI(DISC_COAP, "register new local device name. localDevName=%{public}s", AnonymizeWrapper(anonymizedName));
587 AnonymizeFree(anonymizedName);
588 ret = NSTACKX_RegisterDeviceName(localDevName);
589 DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "register local device name failed, ret=%{public}d.", ret);
590 }
591
DiscCoapUpdateAccount(void)592 void DiscCoapUpdateAccount(void)
593 {
594 DiscCoapUpdateLocalIp(LINK_STATUS_UP);
595 }
596
DeinitLocalInfo(void)597 static void DeinitLocalInfo(void)
598 {
599 DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
600 if (g_localDeviceInfo != NULL) {
601 SoftBusFree(g_localDeviceInfo);
602 g_localDeviceInfo = NULL;
603 }
604 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
605
606 DISC_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_discCoapInnerCbLock) == SOFTBUS_OK, DISC_COAP, "lock failed");
607 if (g_discCoapInnerCb != NULL) {
608 SoftBusFree(g_discCoapInnerCb);
609 g_discCoapInnerCb = NULL;
610 }
611 (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
612
613 (void)SoftBusMutexDestroy(&g_localDeviceInfoLock);
614 (void)SoftBusMutexDestroy(&g_discCoapInnerCbLock);
615 }
616
InitLocalInfo(void)617 static int32_t InitLocalInfo(void)
618 {
619 if (SoftBusMutexInit(&g_localDeviceInfoLock, NULL) != SOFTBUS_OK) {
620 DISC_LOGE(DISC_COAP, "g_localDeviceInfoLock init failed");
621 return SOFTBUS_NO_INIT;
622 }
623 if (SoftBusMutexInit(&g_discCoapInnerCbLock, NULL) != SOFTBUS_OK) {
624 DISC_LOGE(DISC_COAP, "g_discCoapInnerCbLock init failed");
625 (void)SoftBusMutexDestroy(&g_localDeviceInfoLock);
626 return SOFTBUS_NO_INIT;
627 }
628
629 DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
630 DISC_COAP, "lock failed");
631 if (g_localDeviceInfo == NULL) {
632 g_localDeviceInfo = (NSTACKX_LocalDeviceInfo *)SoftBusCalloc(sizeof(NSTACKX_LocalDeviceInfo));
633 if (g_localDeviceInfo == NULL) {
634 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
635 DeinitLocalInfo();
636 return SOFTBUS_MEM_ERR;
637 }
638 }
639 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
640
641 DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_discCoapInnerCbLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
642 DISC_COAP, "lock failed");
643 if (g_discCoapInnerCb == NULL) {
644 g_discCoapInnerCb = (DiscInnerCallback *)SoftBusCalloc(sizeof(DiscInnerCallback));
645 if (g_discCoapInnerCb == NULL) {
646 (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
647 DeinitLocalInfo();
648 return SOFTBUS_MEM_ERR;
649 }
650 }
651 (void)SoftBusMutexUnlock(&g_discCoapInnerCbLock);
652 return SOFTBUS_OK;
653 }
654
DiscNstackxInit(void)655 int32_t DiscNstackxInit(void)
656 {
657 if (InitLocalInfo() != SOFTBUS_OK) {
658 return SOFTBUS_DISCOVER_COAP_INIT_FAIL;
659 }
660
661 NSTACKX_DFinderRegisterLog(NstackxLogInnerImpl);
662 if (SoftbusGetConfig(SOFTBUS_INT_DISC_COAP_MAX_DEVICE_NUM, (unsigned char *)&g_nstackxCallBack.maxDeviceNum,
663 sizeof(g_nstackxCallBack.maxDeviceNum)) != SOFTBUS_OK) {
664 DISC_LOGI(DISC_COAP, "get disc max device num config failed, use default %{public}u", DEFAULT_MAX_DEVICE_NUM);
665 g_nstackxCallBack.maxDeviceNum = DEFAULT_MAX_DEVICE_NUM;
666 }
667 if (NSTACKX_Init(&g_nstackxCallBack) != SOFTBUS_OK) {
668 DeinitLocalInfo();
669 return SOFTBUS_DISCOVER_COAP_INIT_FAIL;
670 }
671 SoftBusRegDiscVarDump((char *)NSTACKX_LOCAL_DEV_INFO, &NstackxLocalDevInfoDump);
672 return SOFTBUS_OK;
673 }
674
DiscNstackxDeinit(void)675 void DiscNstackxDeinit(void)
676 {
677 NSTACKX_Deinit();
678 DeinitLocalInfo();
679 }
680
NstackxLocalDevInfoDump(int fd)681 static int32_t NstackxLocalDevInfoDump(int fd)
682 {
683 char deviceId[NSTACKX_MAX_DEVICE_ID_LEN] = {0};
684 DISC_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_localDeviceInfoLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
685 DISC_COAP, "lock failed");
686 SOFTBUS_DPRINTF(fd, "\n-----------------NstackxLocalDevInfo-------------------\n");
687 SOFTBUS_DPRINTF(fd, "name : %s\n", g_localDeviceInfo->name);
688 DataMasking(g_localDeviceInfo->deviceId, NSTACKX_MAX_DEVICE_ID_LEN, ID_DELIMITER, deviceId);
689 SOFTBUS_DPRINTF(fd, "deviceId : %s\n", deviceId);
690 SOFTBUS_DPRINTF(fd, "localIfInfo networkName : %s\n", g_localDeviceInfo->localIfInfo->networkName);
691 SOFTBUS_DPRINTF(fd, "ifNums : %d\n", g_localDeviceInfo->ifNums);
692 SOFTBUS_DPRINTF(fd, "networkName : %s\n", g_localDeviceInfo->networkName);
693 SOFTBUS_DPRINTF(fd, "is5GHzBandSupported : %d\n", g_localDeviceInfo->is5GHzBandSupported);
694 SOFTBUS_DPRINTF(fd, "deviceType : %d\n", g_localDeviceInfo->deviceType);
695 SOFTBUS_DPRINTF(fd, "version : %s\n", g_localDeviceInfo->version);
696 SOFTBUS_DPRINTF(fd, "businessType : %d\n", g_localDeviceInfo->businessType);
697 (void)SoftBusMutexUnlock(&g_localDeviceInfoLock);
698
699 return SOFTBUS_OK;
700 }
701