• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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