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