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