• 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 <unistd.h>
17 
18 #include "disc_manager.h"
19 #include "bus_center_event.h"
20 #include "common_list.h"
21 #include "disc_ble_dispatcher.h"
22 #include "disc_coap.h"
23 #include "disc_event.h"
24 #include "disc_log.h"
25 #include "disc_usb_dispatcher.h"
26 #include "securec.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_adapter_thread.h"
29 #include "softbus_adapter_timer.h"
30 #include "softbus_def.h"
31 #include "softbus_error_code.h"
32 #include "softbus_json_utils.h"
33 #include "legacy/softbus_hisysevt_discreporter.h"
34 #include "lnn_devicename_info.h"
35 #include "softbus_utils.h"
36 
37 #define SKIP_VALID_PID_VALUE (-1)
38 #define DEVICE_TYPE_SIZE_MAX 3
39 #define DUMP_STR_LEN 256
40 #define DISC_INFO_LIST_SIZE_MAX 1024
41 #define DISPLAY_NAME_BUF_LEN 128
42 #define DISPLAY_NAME_LEN_24 24
43 #define DISPLAY_NAME_LEN_21 21
44 #define DISPLAY_NAME_LEN_18 18
45 #define JSON_KEY_RAW_NAME        "raw"
46 #define JSON_KEY_NAME_LEN_24     "name24"
47 #define JSON_KEY_NAME_LEN_21     "name21"
48 #define JSON_KEY_NAME_LEN_18     "name18"
49 
50 static bool g_isInited = false;
51 
52 static SoftBusList *g_publishInfoList = NULL;
53 static SoftBusList *g_discoveryInfoList = NULL;
54 
55 static DiscoveryFuncInterface *g_discCoapInterface = NULL;
56 static DiscoveryFuncInterface *g_discBleInterface = NULL;
57 static DiscoveryFuncInterface *g_discUsbInterface = NULL;
58 
59 static DiscInnerCallback g_discMgrMediumCb;
60 
61 static ListNode g_capabilityList[CAPABILITY_MAX_BITNUM];
62 
63 typedef struct {
64     char raw[DISPLAY_NAME_BUF_LEN];
65     char name18[DISPLAY_NAME_LEN_18 + 1];
66     char name21[DISPLAY_NAME_LEN_21 + 1];
67     char name24[DISPLAY_NAME_LEN_24 + 1];
68 } DisplayNameList;
69 
70 static DisplayNameList g_displayName = { 0 };
71 
72 static const char *g_discModuleMap[] = {
73     "MODULE_LNN",
74     "MODULE_CONN",
75 };
76 
77 typedef enum {
78     MIN_SERVICE = 0,
79     PUBLISH_SERVICE = MIN_SERVICE,
80     PUBLISH_INNER_SERVICE = 1,
81     SUBSCRIBE_SERVICE = 2,
82     SUBSCRIBE_INNER_SERVICE = 3,
83     MAX_SERVICE = SUBSCRIBE_INNER_SERVICE,
84 } ServiceType;
85 
86 typedef union {
87     PublishOption publishOption;
88     SubscribeOption subscribeOption;
89 } InnerOption;
90 
91 typedef union  {
92     IServerDiscInnerCallback serverCb;
93     DiscInnerCallback innerCb;
94 } InnerCallback;
95 
96 typedef struct {
97     ListNode node;
98     char packageName[PKG_NAME_SIZE_MAX];
99     InnerCallback callback;
100     uint32_t infoNum;
101     ListNode InfoList;
102 } DiscItem;
103 
104 typedef struct {
105     ListNode node;
106     int32_t id;
107     DiscoverMode mode;
108     ExchangeMedium medium;
109     ListNode capNode;
110     DiscItem *item;
111     DiscoveryStatistics statistics;
112     InnerOption option;
113     int32_t pid;
114 } DiscInfo;
115 
116 typedef struct {
117     ListNode node;
118     int32_t id;
119     char *pkgName;
120     int32_t pid;
121 } IdContainer;
122 
123 #define DFX_RECORD_DISC_CALL_START(infoNode, packageName, interfaceType)   \
124     do {                                                                   \
125         DiscEventExtra extra = { 0 };                                      \
126         DiscEventExtraInit(&extra);                                        \
127         BuildDiscCallEvent(&extra, infoNode, packageName, interfaceType);  \
128         DISC_EVENT(EVENT_SCENE_DISC, EVENT_STAGE_CALL_INTERFACE, extra);   \
129     } while (0)
130 
UpdateDiscEventAndReport(DiscEventExtra * extra,const DeviceInfo * device)131 static void UpdateDiscEventAndReport(DiscEventExtra *extra, const DeviceInfo *device)
132 {
133     if (device == NULL) {
134         DISC_EVENT(EVENT_SCENE_DISC, EVENT_STAGE_DEVICE_FOUND, *extra);
135         DISC_LOGI(DISC_CONTROL, "device info is null");
136         return;
137     }
138     if (device->addrNum <= CONNECTION_ADDR_WLAN || device->addrNum > CONNECTION_ADDR_MAX) {
139         DISC_EVENT(EVENT_SCENE_DISC, EVENT_STAGE_DEVICE_FOUND, *extra);
140         DISC_LOGI(DISC_CONTROL, "unknown device info");
141         return;
142     }
143 
144     for (uint32_t i = 0; i < device->addrNum; i++) {
145         switch (device->addr[i].type) {
146             case CONNECTION_ADDR_BR:
147                 extra->peerBrMac = device->addr[i].info.br.brMac;
148                 break;
149             case CONNECTION_ADDR_BLE:
150                 extra->peerBleMac = device->addr[i].info.ble.bleMac;
151                 break;
152             case CONNECTION_ADDR_WLAN:
153                 /* fall-through */
154             case CONNECTION_ADDR_ETH:
155                 extra->peerIp = device->addr[i].info.ip.ip;
156                 break;
157             default:
158                 DISC_LOGI(DISC_CONTROL, "unknown param type!");
159                 break;
160         }
161     }
162 
163     char *deviceType = SoftBusCalloc(DEVICE_TYPE_SIZE_MAX + 1);
164     DISC_CHECK_AND_RETURN_LOGE(deviceType != NULL, DISC_CONTROL, "SoftBusCalloc failed");
165     if (snprintf_s(deviceType, DEVICE_TYPE_SIZE_MAX + 1, DEVICE_TYPE_SIZE_MAX, "%03X", device->devType) >= 0) {
166         extra->peerDeviceType = deviceType;
167     }
168     DISC_EVENT(EVENT_SCENE_DISC, EVENT_STAGE_DEVICE_FOUND, *extra);
169     SoftBusFree(deviceType);
170     extra->peerDeviceType = NULL;
171 }
172 
DfxRecordStartDiscoveryDevice(DiscInfo * infoNode)173 static void DfxRecordStartDiscoveryDevice(DiscInfo *infoNode)
174 {
175     infoNode->statistics.startTime = SoftBusGetSysTimeMs();
176     infoNode->statistics.repTimes = 0;
177     infoNode->statistics.devNum = 0;
178     infoNode->statistics.discTimes = 0;
179 }
180 
UpdateDdmpStartDiscoveryTime(DiscInfo * info)181 static void UpdateDdmpStartDiscoveryTime(DiscInfo *info)
182 {
183     if (info->medium != AUTO && info->medium != COAP) {
184         DISC_LOGD(DISC_CONTROL, "no need update ddmp start discovery time");
185         return;
186     }
187 
188     DiscInfo *infoNode = NULL;
189     LIST_FOR_EACH_ENTRY(infoNode, &(g_capabilityList[DDMP_CAPABILITY_BITMAP]), DiscInfo, capNode) {
190         if (infoNode->statistics.repTimes == 0) {
191             DISC_LOGD(DISC_CONTROL, "update ddmp callback id=%{public}d", infoNode->id);
192             infoNode->statistics.startTime = info->statistics.startTime;
193         }
194     }
195 }
196 
DfxRecordDeviceFound(DiscInfo * infoNode,const DeviceInfo * device,const InnerDeviceInfoAddtions * additions)197 static void DfxRecordDeviceFound(DiscInfo *infoNode, const DeviceInfo *device, const InnerDeviceInfoAddtions *additions)
198 {
199     DISC_LOGD(DISC_CONTROL, "record device found");
200     if (infoNode->statistics.repTimes == 0) {
201         uint64_t costTime = 0;
202         uint64_t sysTime = SoftBusGetSysTimeMs();
203         if (sysTime >= infoNode->statistics.startTime) {
204             costTime = sysTime - infoNode->statistics.startTime;
205         } else {
206             DISC_LOGE(DISC_CONTROL, "CurTime < startTime");
207         }
208         SoftbusRecordFirstDiscTime((SoftBusDiscMedium)additions->medium, costTime);
209         DiscEventExtra extra = { 0 };
210         DiscEventExtraInit(&extra);
211         extra.discMode = infoNode == NULL ? 0 : infoNode->mode;
212         extra.discType = additions == NULL ? 0 : additions->medium + 1;
213         extra.costTime = costTime;
214         extra.result = EVENT_STAGE_RESULT_OK;
215         UpdateDiscEventAndReport(&extra, device);
216     }
217     infoNode->statistics.repTimes++;
218     infoNode->statistics.devNum++;
219 }
220 
DfxRecordStopDiscoveryDevice(const char * packageName,DiscInfo * infoNode)221 static void DfxRecordStopDiscoveryDevice(const char *packageName, DiscInfo *infoNode)
222 {
223     DiscoveryStatistics *statistics = &infoNode->statistics;
224     uint64_t totalTime = SoftBusGetSysTimeMs() - statistics->startTime;
225     SoftbusRecordBleDiscDetails((char *)packageName, totalTime, statistics->repTimes, statistics->devNum,
226                                 statistics->discTimes);
227 }
228 
BitmapSet(uint32_t * bitMap,uint32_t pos)229 static void BitmapSet(uint32_t *bitMap, uint32_t pos)
230 {
231     *bitMap |= 1U << pos;
232 }
233 
IsBitmapSet(const uint32_t * bitMap,uint32_t pos)234 static bool IsBitmapSet(const uint32_t *bitMap, uint32_t pos)
235 {
236     return ((1U << pos) & (*bitMap)) ? true : false;
237 }
238 
BuildDiscCallEvent(DiscEventExtra * extra,const DiscInfo * info,const char * packageName,const InterfaceFuncType type)239 static void BuildDiscCallEvent(DiscEventExtra *extra, const DiscInfo *info, const char *packageName,
240     const InterfaceFuncType type)
241 {
242     DISC_CHECK_AND_RETURN_LOGE(extra != NULL, DISC_CONTROL, "discEventExtra is null");
243 
244     if (info != NULL) {
245         extra->discType = info->medium + 1;
246         extra->discMode = info->mode;
247     }
248     if (IsValidString(packageName, PKG_NAME_SIZE_MAX - 1)) {
249         extra->callerPkg = packageName;
250     }
251     extra->interFuncType = type + 1;
252 }
253 
CallSpecificInterfaceFunc(const InnerOption * option,const DiscoveryFuncInterface * interface,const DiscoverMode mode,InterfaceFuncType type)254 static int32_t CallSpecificInterfaceFunc(const InnerOption *option,
255     const DiscoveryFuncInterface *interface, const DiscoverMode mode, InterfaceFuncType type)
256 {
257     DISC_CHECK_AND_RETURN_RET_LOGW(interface != NULL, SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL,
258         DISC_CONTROL, "interface is null");
259     switch (type) {
260         case PUBLISH_FUNC:
261             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Publish(&(option->publishOption))) :
262                 (interface->StartScan(&(option->publishOption))));
263         case UNPUBLISH_FUNC:
264             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Unpublish(&(option->publishOption))) :
265                 (interface->StopScan(&(option->publishOption))));
266         case STARTDISCOVERTY_FUNC:
267             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StartAdvertise(&(option->subscribeOption))) :
268                 (interface->Subscribe(&(option->subscribeOption))));
269         case STOPDISCOVERY_FUNC:
270             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StopAdvertise(&(option->subscribeOption))) :
271                 (interface->Unsubscribe(&(option->subscribeOption))));
272         default:
273             return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
274     }
275 }
276 
DfxCallInterfaceByMedium(const DiscInfo * infoNode,const char * packageName,const InterfaceFuncType type,int32_t reason)277 static void DfxCallInterfaceByMedium(
278     const DiscInfo *infoNode, const char *packageName, const InterfaceFuncType type, int32_t reason)
279 {
280     DiscEventExtra extra = {0};
281     DiscEventExtraInit(&extra);
282     extra.errcode = reason;
283     BuildDiscCallEvent(&extra, infoNode, packageName, type);
284     extra.result = (reason == SOFTBUS_OK) ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED;
285     DISC_EVENT(EVENT_SCENE_DISC, EVENT_STAGE_CALL_INTERFACE, extra);
286 }
287 
CallInterfaceByMedium(const DiscInfo * info,const char * packageName,const InterfaceFuncType type)288 static int32_t CallInterfaceByMedium(const DiscInfo *info, const char *packageName, const InterfaceFuncType type)
289 {
290     int32_t ret = SOFTBUS_OK;
291     switch (info->medium) {
292         case COAP:
293             ret = CallSpecificInterfaceFunc(&(info->option), g_discCoapInterface, info->mode, type);
294             DfxCallInterfaceByMedium(info, packageName, type, ret);
295             return ret;
296         case BLE:
297             ret = CallSpecificInterfaceFunc(&(info->option), g_discBleInterface, info->mode, type);
298             DfxCallInterfaceByMedium(info, packageName, type, ret);
299             return ret;
300         case AUTO: {
301             int32_t coapRet = CallSpecificInterfaceFunc(&(info->option), g_discCoapInterface, info->mode, type);
302             DfxCallInterfaceByMedium(info, packageName, type, coapRet);
303             int32_t bleRet = CallSpecificInterfaceFunc(&(info->option), g_discBleInterface, info->mode, type);
304             DfxCallInterfaceByMedium(info, packageName, type, bleRet);
305 
306             DISC_CHECK_AND_RETURN_RET_LOGE(coapRet == SOFTBUS_OK || bleRet == SOFTBUS_OK,
307                 SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL, DISC_CONTROL, "all medium failed");
308             return SOFTBUS_OK;
309         }
310         case USB:
311             ret = CallSpecificInterfaceFunc(&(info->option), g_discUsbInterface, info->mode, type);
312             DfxCallInterfaceByMedium(info, packageName, type, ret);
313             return ret;
314         default:
315             return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
316     }
317 }
318 
TransferStringCapToBitmap(const char * capability)319 static int32_t TransferStringCapToBitmap(const char *capability)
320 {
321     DISC_CHECK_AND_RETURN_RET_LOGW(capability != NULL, SOFTBUS_DISCOVER_MANAGER_CAPABILITY_INVALID,
322         DISC_CONTROL, "capability is null");
323 
324     for (uint32_t i = 0; i < sizeof(g_capabilityMap) / sizeof(g_capabilityMap[0]); i++) {
325         if (strcmp(capability, g_capabilityMap[i].capability) == 0) {
326             DISC_LOGD(DISC_CONTROL, "capability=%{public}s", capability);
327             return g_capabilityMap[i].bitmap;
328         }
329     }
330 
331     return SOFTBUS_DISCOVER_MANAGER_CAPABILITY_INVALID;
332 }
333 
AddDiscInfoToCapabilityList(DiscInfo * info,const ServiceType type)334 static void AddDiscInfoToCapabilityList(DiscInfo *info, const ServiceType type)
335 {
336     if (type != SUBSCRIBE_SERVICE && type != SUBSCRIBE_INNER_SERVICE) {
337         DISC_LOGD(DISC_CONTROL, "publish no need to add");
338         return;
339     }
340 
341     for (uint32_t tmp = 0; tmp < CAPABILITY_MAX_BITNUM; tmp++) {
342         if (IsBitmapSet(&(info->option.subscribeOption.capabilityBitmap[0]), tmp) == true) {
343             if (type == SUBSCRIBE_SERVICE) {
344                 ListTailInsert(&(g_capabilityList[tmp]), &(info->capNode));
345             } else {
346                 ListNodeInsert(&(g_capabilityList[tmp]), &(info->capNode));
347             }
348             break;
349         }
350     }
351 }
352 
RemoveDiscInfoFromCapabilityList(DiscInfo * info,const ServiceType type)353 static void RemoveDiscInfoFromCapabilityList(DiscInfo *info, const ServiceType type)
354 {
355     if (type != SUBSCRIBE_SERVICE && type != SUBSCRIBE_INNER_SERVICE) {
356         DISC_LOGD(DISC_CONTROL, "publish no need to delete");
357         return;
358     }
359     ListDelete(&(info->capNode));
360 }
361 
FreeDiscInfo(DiscInfo * info,const ServiceType type)362 static void FreeDiscInfo(DiscInfo *info, const ServiceType type)
363 {
364     if ((type == PUBLISH_SERVICE) || (type == PUBLISH_INNER_SERVICE)) {
365         SoftBusFree(info->option.publishOption.capabilityData);
366         info->option.publishOption.capabilityData = NULL;
367     }
368 
369     if ((type == SUBSCRIBE_SERVICE) || (type == SUBSCRIBE_INNER_SERVICE)) {
370         SoftBusFree(info->option.subscribeOption.capabilityData);
371         info->option.subscribeOption.capabilityData = NULL;
372     }
373     SoftBusFree(info);
374     info = NULL;
375 }
376 
IsInnerModule(const DiscInfo * infoNode)377 static bool IsInnerModule(const DiscInfo *infoNode)
378 {
379     for (uint32_t i = 0; i < MODULE_MAX; i++) {
380         DISC_LOGD(DISC_CONTROL, "packageName=%{public}s", infoNode->item->packageName);
381         if (strcmp(infoNode->item->packageName, g_discModuleMap[i]) == 0) {
382             DISC_LOGD(DISC_CONTROL, "true");
383             return true;
384         }
385     }
386     DISC_LOGD(DISC_CONTROL, "false");
387     return false;
388 }
389 
InnerDeviceFound(DiscInfo * infoNode,const DeviceInfo * device,const InnerDeviceInfoAddtions * additions)390 static void InnerDeviceFound(DiscInfo *infoNode, const DeviceInfo *device,
391                                                 const InnerDeviceInfoAddtions *additions)
392 {
393     if (infoNode->item != NULL && infoNode->item->callback.serverCb.OnServerDeviceFound != NULL &&
394         !IsInnerModule(infoNode)) {
395         (void)infoNode->item->callback.serverCb.OnServerDeviceFound(infoNode->item->packageName, device, additions);
396         return;
397     }
398 
399     DISC_LOGD(DISC_CONTROL, "call from inner module.");
400     if (infoNode->item != NULL && infoNode->item->callback.innerCb.OnDeviceFound != NULL) {
401         DfxRecordDeviceFound(infoNode, device, additions);
402         infoNode->item->callback.innerCb.OnDeviceFound(device, additions);
403     }
404 }
405 
DiscOnDeviceFound(const DeviceInfo * device,const InnerDeviceInfoAddtions * additions)406 static void DiscOnDeviceFound(const DeviceInfo *device, const InnerDeviceInfoAddtions *additions)
407 {
408     DISC_CHECK_AND_RETURN_LOGE(device != NULL, DISC_CONTROL, "device is null");
409     DISC_CHECK_AND_RETURN_LOGE(additions != NULL, DISC_CONTROL, "additions is null");
410 
411     DISC_LOGD(DISC_CONTROL,
412         "capabilityBitmap=%{public}d, medium=%{public}d", device->capabilityBitmap[0], additions->medium);
413     for (uint32_t tmp = 0; tmp < CAPABILITY_MAX_BITNUM; tmp++) {
414         if (IsBitmapSet((uint32_t *)device->capabilityBitmap, tmp) == false) {
415             continue;
416         }
417 
418         if (SoftBusMutexLock(&(g_discoveryInfoList->lock)) != SOFTBUS_OK) {
419             DISC_LOGE(DISC_CONTROL, "lock failed");
420             return;
421         }
422         DiscInfo *infoNode = NULL;
423         LIST_FOR_EACH_ENTRY(infoNode, &(g_capabilityList[tmp]), DiscInfo, capNode) {
424             DISC_LOGD(DISC_CONTROL, "find callback id=%{public}d", infoNode->id);
425             infoNode->statistics.discTimes++;
426             InnerDeviceFound(infoNode, device, additions);
427         }
428         (void)SoftBusMutexUnlock(&(g_discoveryInfoList->lock));
429     }
430 }
431 
CheckPublishInfo(const PublishInfo * info)432 static int32_t CheckPublishInfo(const PublishInfo *info)
433 {
434     DISC_CHECK_AND_RETURN_RET_LOGW(info->mode == DISCOVER_MODE_PASSIVE || info->mode == DISCOVER_MODE_ACTIVE,
435         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "mode is invalid");
436     DISC_CHECK_AND_RETURN_RET_LOGW(info->medium >= AUTO && info->medium <= COAP,
437         SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM, DISC_CONTROL, "mode is invalid");
438     DISC_CHECK_AND_RETURN_RET_LOGW(info->freq >= LOW && info->freq < FREQ_BUTT,
439         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "freq is invalid");
440 
441     if (info->capabilityData == NULL) {
442         if (info->dataLen == 0) {
443             return SOFTBUS_OK;
444         } else {
445             DISC_LOGE(DISC_CONTROL, "capabilityData is NULL, dataLen != 0");
446             return SOFTBUS_INVALID_PARAM;
447         }
448     } else {
449         if (info->dataLen == 0) {
450             DISC_LOGE(DISC_CONTROL, "capabilityData is not NULL, dataLen == 0");
451             return SOFTBUS_INVALID_PARAM;
452         }
453         if (info->dataLen > MAX_CAPABILITYDATA_LEN) {
454             DISC_LOGE(DISC_CONTROL, "dataLen > max length. dataLen=%{public}u", info->dataLen);
455             return SOFTBUS_INVALID_PARAM;
456         }
457         uint32_t len = strlen((char *)info->capabilityData);
458         if (info->capabilityData[info->dataLen] != '\0') {
459             DISC_LOGE(DISC_CONTROL, "capabilityData is not c-string format: len=%{public}u, dataLen=%{public}u",
460                 len, info->dataLen);
461             return SOFTBUS_INVALID_PARAM;
462         }
463         if (len != info->dataLen) {
464             DISC_LOGE(DISC_CONTROL, "capabilityData len != dataLen. len=%{public}u, dataLen=%{public}u",
465                 len, info->dataLen);
466             return SOFTBUS_INVALID_PARAM;
467         }
468     }
469     return SOFTBUS_OK;
470 }
471 
CheckSubscribeInfo(const SubscribeInfo * info)472 static int32_t CheckSubscribeInfo(const SubscribeInfo *info)
473 {
474     DISC_CHECK_AND_RETURN_RET_LOGW(info->mode == DISCOVER_MODE_PASSIVE || info->mode == DISCOVER_MODE_ACTIVE,
475         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "mode is invalid");
476     DISC_CHECK_AND_RETURN_RET_LOGW(info->medium >= AUTO && info->medium <= USB,
477         SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM, DISC_CONTROL, "medium is invalid");
478     DISC_CHECK_AND_RETURN_RET_LOGW(info->freq >= LOW && info->freq < FREQ_BUTT,
479         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "freq is invalid");
480     DISC_CHECK_AND_RETURN_RET_LOGW(!(info->medium == USB && info->mode == DISCOVER_MODE_ACTIVE),
481         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "usb is not support active mode");
482 
483     if (info->capabilityData == NULL) {
484         if (info->dataLen == 0) {
485             return SOFTBUS_OK;
486         } else {
487             DISC_LOGE(DISC_CONTROL, "capabilityData is NULL, dataLen != 0");
488             return SOFTBUS_INVALID_PARAM;
489         }
490     } else {
491         if (info->dataLen == 0) {
492             DISC_LOGE(DISC_CONTROL, "capabilityData is not NULL, dataLen == 0");
493             return SOFTBUS_INVALID_PARAM;
494         }
495         if (info->dataLen > MAX_CAPABILITYDATA_LEN) {
496             DISC_LOGE(DISC_CONTROL, "dataLen > max length. dataLen=%{public}u", info->dataLen);
497             return SOFTBUS_INVALID_PARAM;
498         }
499         uint32_t len = strlen((char *)info->capabilityData);
500         if (info->capabilityData[info->dataLen] != '\0') {
501             DISC_LOGE(DISC_CONTROL, "capabilityData is not c-string format: len=%{public}u, dataLen=%{public}u",
502                 len, info->dataLen);
503             return SOFTBUS_INVALID_PARAM;
504         }
505         if (len != info->dataLen) {
506             DISC_LOGE(DISC_CONTROL, "capabilityData len != dataLen. len=%{public}u, dataLen=%{public}u",
507                 len, info->dataLen);
508             return SOFTBUS_INVALID_PARAM;
509         }
510     }
511     return SOFTBUS_OK;
512 }
513 
SetDiscItemCallback(DiscItem * itemNode,const InnerCallback * cb,const ServiceType type)514 static void SetDiscItemCallback(DiscItem *itemNode, const InnerCallback *cb, const ServiceType type)
515 {
516     if ((type != SUBSCRIBE_INNER_SERVICE && type != SUBSCRIBE_SERVICE) || cb == NULL) {
517         return;
518     }
519     if (type == SUBSCRIBE_SERVICE) {
520         itemNode->callback.serverCb.OnServerDeviceFound = cb->serverCb.OnServerDeviceFound;
521         return;
522     }
523     if ((itemNode->callback.innerCb.OnDeviceFound != NULL) && (cb->innerCb.OnDeviceFound == NULL)) {
524         return;
525     }
526     itemNode->callback.innerCb.OnDeviceFound = cb->innerCb.OnDeviceFound;
527 }
528 
CreateDiscItem(SoftBusList * serviceList,const char * packageName,const InnerCallback * cb,const ServiceType type)529 static DiscItem *CreateDiscItem(SoftBusList *serviceList, const char *packageName, const InnerCallback *cb,
530                                 const ServiceType type)
531 {
532     DiscItem *itemNode = (DiscItem *)SoftBusCalloc(sizeof(DiscItem));
533     DISC_CHECK_AND_RETURN_RET_LOGE(itemNode != NULL, NULL, DISC_CONTROL, "calloc item node failed");
534 
535     if (strcpy_s(itemNode->packageName, PKG_NAME_SIZE_MAX, packageName) != EOK) {
536         SoftBusFree(itemNode);
537         return NULL;
538     }
539 
540     if ((type == PUBLISH_INNER_SERVICE) || (type == SUBSCRIBE_INNER_SERVICE)) {
541         ListNodeInsert(&(serviceList->list), &(itemNode->node));
542     } else if ((type == PUBLISH_SERVICE) || (type == SUBSCRIBE_SERVICE)) {
543         ListTailInsert(&(serviceList->list), &(itemNode->node));
544     }
545 
546     SetDiscItemCallback(itemNode, cb, type);
547 
548     serviceList->cnt++;
549     ListInit(&(itemNode->InfoList));
550     return itemNode;
551 }
552 
CreateDiscInfoForPublish(const PublishInfo * info,int32_t callingPid)553 static DiscInfo *CreateDiscInfoForPublish(const PublishInfo *info, int32_t callingPid)
554 {
555     DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo));
556     DISC_CHECK_AND_RETURN_RET_LOGE(infoNode != NULL, NULL, DISC_CONTROL, "calloc info node failed");
557 
558     ListInit(&(infoNode->node));
559     ListInit(&(infoNode->capNode));
560 
561     infoNode->id = info->publishId;
562     infoNode->medium = info->medium;
563     infoNode->mode = info->mode;
564     infoNode->pid = callingPid;
565 
566     PublishOption *option = &infoNode->option.publishOption;
567     option->freq = info->freq;
568     option->ranging = info->ranging;
569     option->dataLen = info->dataLen;
570 
571     if (info->dataLen != 0) {
572         option->capabilityData = (uint8_t *)SoftBusCalloc(info->dataLen + 1);
573         if (option->capabilityData == NULL) {
574             DISC_LOGE(DISC_CONTROL, "alloc capability data failed");
575             SoftBusFree(infoNode);
576             return NULL;
577         }
578         if (memcpy_s(option->capabilityData, info->dataLen, info->capabilityData, info->dataLen) != EOK) {
579             DISC_LOGE(DISC_CONTROL, "memcpy_s failed");
580             FreeDiscInfo(infoNode, PUBLISH_SERVICE);
581             return NULL;
582         }
583     }
584 
585     int32_t bitmap = TransferStringCapToBitmap(info->capability);
586     if (bitmap < 0) {
587         DISC_LOGE(DISC_CONTROL, "capability not found");
588         FreeDiscInfo(infoNode, PUBLISH_SERVICE);
589         return NULL;
590     }
591     BitmapSet(option->capabilityBitmap, (uint32_t)bitmap);
592 
593     return infoNode;
594 }
595 
CreateDiscInfoForSubscribe(const SubscribeInfo * info,int32_t callingPid)596 static DiscInfo *CreateDiscInfoForSubscribe(const SubscribeInfo *info, int32_t callingPid)
597 {
598     DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo));
599     DISC_CHECK_AND_RETURN_RET_LOGE(infoNode != NULL, NULL, DISC_CONTROL, "alloc info node failed");
600 
601     ListInit(&(infoNode->node));
602     ListInit(&(infoNode->capNode));
603 
604     infoNode->id = info->subscribeId;
605     infoNode->medium = info->medium;
606     infoNode->mode = info->mode;
607     infoNode->pid = callingPid;
608 
609     SubscribeOption *option = &infoNode->option.subscribeOption;
610     option->freq = info->freq;
611     option->dataLen = info->dataLen;
612     option->isSameAccount = info->isSameAccount;
613     option->isWakeRemote = info->isWakeRemote;
614 
615     if (info->dataLen != 0) {
616         option->capabilityData = (uint8_t *)SoftBusCalloc(info->dataLen + 1);
617         if (option->capabilityData == NULL) {
618             DISC_LOGE(DISC_CONTROL, "alloc capability data failed");
619             SoftBusFree(infoNode);
620             return NULL;
621         }
622         if (memcpy_s(option->capabilityData, info->dataLen, info->capabilityData, info->dataLen) != EOK) {
623             DISC_LOGE(DISC_CONTROL, "memcpy_s failed");
624             FreeDiscInfo(infoNode, SUBSCRIBE_SERVICE);
625             return NULL;
626         }
627     }
628 
629     int32_t bimap = TransferStringCapToBitmap(info->capability);
630     if (bimap < 0) {
631         DISC_LOGE(DISC_CONTROL, "capability not found");
632         FreeDiscInfo(infoNode, SUBSCRIBE_SERVICE);
633         return NULL;
634     }
635     BitmapSet(option->capabilityBitmap, (uint32_t)bimap);
636     DfxRecordStartDiscoveryDevice(infoNode);
637     return infoNode;
638 }
639 
DumpDiscInfoList(const DiscItem * itemNode)640 static void DumpDiscInfoList(const DiscItem *itemNode)
641 {
642     char dumpStr[DUMP_STR_LEN] = {0};
643     int32_t dumpStrPos = 0;
644     int32_t itemStrLen = 0;
645     DiscInfo *infoNode = NULL;
646 
647     LIST_FOR_EACH_ENTRY(infoNode, &(itemNode->InfoList), DiscInfo, node) {
648         itemStrLen = sprintf_s(&dumpStr[dumpStrPos], DUMP_STR_LEN - dumpStrPos, "%d,", infoNode->id);
649         if (itemStrLen <= 0) {
650             DISC_LOGI(DISC_CONTROL, "info id=%{public}s", dumpStr);
651             dumpStrPos = 0;
652             itemStrLen = sprintf_s(&dumpStr[dumpStrPos], DUMP_STR_LEN - dumpStrPos, "%d,", infoNode->id);
653             DISC_CHECK_AND_RETURN_LOGW(itemStrLen > 0, DISC_CONTROL, "sprintf_s failed");
654         }
655         dumpStrPos += itemStrLen;
656     }
657 
658     if (dumpStrPos > 0) {
659         DISC_LOGI(DISC_CONTROL, "info id=%{public}s", dumpStr);
660     }
661 }
662 
AddDiscInfoToList(SoftBusList * serviceList,const char * packageName,const InnerCallback * cb,DiscInfo * info,ServiceType type)663 static int32_t AddDiscInfoToList(SoftBusList *serviceList, const char *packageName, const InnerCallback *cb,
664                                  DiscInfo *info, ServiceType type)
665 {
666     bool isDumpable = (strcmp(g_discModuleMap[0], packageName) != 0);
667     if (isDumpable) {
668         DISC_LOGI(DISC_CONTROL, "packageName=%{public}s, id=%{public}d", packageName, info->id);
669     }
670 
671     DiscItem *itemNode = NULL;
672     bool exist = false;
673     LIST_FOR_EACH_ENTRY(itemNode, &(serviceList->list), DiscItem, node) {
674         if (strcmp(itemNode->packageName, packageName) != 0) {
675             continue;
676         }
677 
678         if (isDumpable) {
679             DumpDiscInfoList(itemNode);
680         }
681 
682         DiscInfo *infoNode = NULL;
683         LIST_FOR_EACH_ENTRY(infoNode, &(itemNode->InfoList), DiscInfo, node) {
684             if (infoNode->id == info->id) {
685                 DISC_LOGI(DISC_CONTROL, "id already existed");
686                 return SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM;
687             }
688         }
689         DISC_CHECK_AND_RETURN_RET_LOGE(
690             itemNode->infoNum < DISC_INFO_LIST_SIZE_MAX, SOFTBUS_DISCOVER_MANAGER_ID_MAX_ERR,
691             DISC_CONTROL, "infolist size limit reached, packageName=%{public}s", packageName);
692 
693         SetDiscItemCallback(itemNode, cb, type);
694         exist = true;
695         itemNode->infoNum++;
696         info->item = itemNode;
697         ListTailInsert(&(itemNode->InfoList), &(info->node));
698         AddDiscInfoToCapabilityList(info, type);
699         break;
700     }
701 
702     if (exist == false) {
703         itemNode = CreateDiscItem(serviceList, packageName, cb, type);
704         if (itemNode == NULL) {
705             DISC_LOGE(DISC_CONTROL, "itemNode create failed");
706             return SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE;
707         }
708 
709         itemNode->infoNum++;
710         info->item = itemNode;
711         ListTailInsert(&(itemNode->InfoList), &(info->node));
712         AddDiscInfoToCapabilityList(info, type);
713     }
714 
715     return SOFTBUS_OK;
716 }
717 
AddDiscInfoToPublishList(const char * packageName,const InnerCallback * cb,DiscInfo * info,ServiceType type)718 static int32_t AddDiscInfoToPublishList(const char *packageName, const InnerCallback *cb, DiscInfo *info,
719                                         ServiceType type)
720 {
721     return AddDiscInfoToList(g_publishInfoList, packageName, cb, info, type);
722 }
723 
AddDiscInfoToDiscoveryList(const char * packageName,const InnerCallback * cb,DiscInfo * info,ServiceType type)724 static int32_t AddDiscInfoToDiscoveryList(const char *packageName, const InnerCallback *cb, DiscInfo *info,
725                                           ServiceType type)
726 {
727     return AddDiscInfoToList(g_discoveryInfoList, packageName, cb, info, type);
728 }
729 
RemoveInfoFromList(SoftBusList * serviceList,const char * packageName,const int32_t id,const ServiceType type,int32_t callingPid)730 static DiscInfo *RemoveInfoFromList(SoftBusList *serviceList, const char *packageName, const int32_t id,
731                                     const ServiceType type, int32_t callingPid)
732 {
733     bool isDumpable = (strcmp(g_discModuleMap[0], packageName) != 0);
734     if (isDumpable) {
735         DISC_LOGI(DISC_CONTROL, "packageName=%{public}s, id=%{public}d", packageName, id);
736     }
737 
738     bool isIdExist = false;
739     DiscItem *itemNode = NULL;
740     DiscInfo *infoNode = NULL;
741     LIST_FOR_EACH_ENTRY(itemNode, &(serviceList->list), DiscItem, node) {
742         if (strcmp(itemNode->packageName, packageName) != 0) {
743             continue;
744         }
745 
746         if (isDumpable) {
747             DumpDiscInfoList(itemNode);
748         }
749 
750         if (itemNode->infoNum == 0) {
751             serviceList->cnt--;
752             ListDelete(&(itemNode->node));
753             SoftBusFree(itemNode);
754             return NULL;
755         }
756 
757         LIST_FOR_EACH_ENTRY(infoNode, &(itemNode->InfoList), DiscInfo, node) {
758             if (infoNode->pid != callingPid) {
759                 continue;
760             }
761             if (infoNode->id != id) {
762                 continue;
763             }
764             isIdExist = true;
765             itemNode->infoNum--;
766             RemoveDiscInfoFromCapabilityList(infoNode, type);
767             ListDelete(&(infoNode->node));
768 
769             if (itemNode->infoNum == 0) {
770                 serviceList->cnt--;
771                 ListDelete(&(itemNode->node));
772                 SoftBusFree(itemNode);
773             }
774             break;
775         }
776         break;
777     }
778 
779     if (isIdExist == false) {
780         DISC_LOGD(DISC_CONTROL, "can not find publishId");
781         return NULL;
782     }
783     return infoNode;
784 }
785 
RemoveInfoFromPublishList(const char * packageName,const int32_t id,const ServiceType type,int32_t callingPid)786 static DiscInfo *RemoveInfoFromPublishList(const char *packageName, const int32_t id, const ServiceType type,
787     int32_t callingPid)
788 {
789     return RemoveInfoFromList(g_publishInfoList, packageName, id, type, callingPid);
790 }
791 
RemoveInfoFromDiscoveryList(const char * packageName,const int32_t id,const ServiceType type,int32_t callingPid)792 static DiscInfo *RemoveInfoFromDiscoveryList(const char *packageName, const int32_t id, const ServiceType type,
793     int32_t callingPid)
794 {
795     return RemoveInfoFromList(g_discoveryInfoList, packageName, id, type, callingPid);
796 }
797 
InnerPublishService(const char * packageName,DiscInfo * info,const ServiceType type)798 static int32_t InnerPublishService(const char *packageName, DiscInfo *info, const ServiceType type)
799 {
800     int32_t ret = SoftBusMutexLock(&g_publishInfoList->lock);
801     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, DISC_CONTROL, "lock failed");
802 
803     do {
804         ret = AddDiscInfoToPublishList(packageName, NULL, info, type);
805         if (ret != SOFTBUS_OK) {
806             DISC_LOGE(DISC_CONTROL, "add info to list failed");
807             break;
808         }
809 
810         DFX_RECORD_DISC_CALL_START(info, packageName, PUBLISH_FUNC);
811         ret = CallInterfaceByMedium(info, packageName, PUBLISH_FUNC);
812         if (ret != SOFTBUS_OK) {
813             DISC_LOGE(DISC_CONTROL, "call interface by medium failed");
814             ListDelete(&(info->node));
815             info->item->infoNum--;
816         }
817     } while (false);
818 
819     SoftBusMutexUnlock(&g_publishInfoList->lock);
820     return ret;
821 }
822 
InnerUnPublishService(const char * packageName,int32_t publishId,const ServiceType type,int32_t callingPid)823 static int32_t InnerUnPublishService(const char *packageName, int32_t publishId, const ServiceType type,
824     int32_t callingPid)
825 {
826     int32_t ret = SoftBusMutexLock(&g_publishInfoList->lock);
827     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, DISC_CONTROL, "lock failed");
828 
829     DiscInfo *infoNode = NULL;
830     do {
831         infoNode = RemoveInfoFromPublishList(packageName, publishId, type, callingPid);
832         if (infoNode == NULL) {
833             DISC_LOGE(DISC_CONTROL, "delete info from list failed");
834             ret = SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE;
835             break;
836         }
837 
838         DFX_RECORD_DISC_CALL_START(infoNode, packageName, UNPUBLISH_FUNC);
839         ret = CallInterfaceByMedium(infoNode, packageName, UNPUBLISH_FUNC);
840         if (ret != SOFTBUS_OK) {
841             DISC_LOGE(DISC_CONTROL, "call interface by medium failed");
842         }
843         FreeDiscInfo(infoNode, type);
844     } while (false);
845 
846     SoftBusMutexUnlock(&g_publishInfoList->lock);
847     return ret;
848 }
849 
InnerStartDiscovery(const char * packageName,DiscInfo * info,const IServerDiscInnerCallback * cb,const ServiceType type)850 static int32_t InnerStartDiscovery(const char *packageName, DiscInfo *info, const IServerDiscInnerCallback *cb,
851                                    const ServiceType type)
852 {
853     InnerCallback callback;
854     callback.serverCb.OnServerDeviceFound = NULL;
855     if (cb != NULL) {
856         callback.serverCb.OnServerDeviceFound = cb->OnServerDeviceFound;
857     }
858 
859     int32_t ret = SoftBusMutexLock(&g_discoveryInfoList->lock);
860     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, DISC_CONTROL, "lock failed");
861 
862     do {
863         ret = AddDiscInfoToDiscoveryList(packageName, &callback, info, type);
864         if (ret != SOFTBUS_OK) {
865             DISC_LOGE(DISC_CONTROL, "add info to list failed");
866             break;
867         }
868 
869         UpdateDdmpStartDiscoveryTime(info);
870         DFX_RECORD_DISC_CALL_START(info, packageName, STARTDISCOVERTY_FUNC);
871         ret = CallInterfaceByMedium(info, packageName, STARTDISCOVERTY_FUNC);
872         if (ret != SOFTBUS_OK) {
873             DISC_LOGE(DISC_CONTROL, "call interface by medium failed");
874             RemoveDiscInfoFromCapabilityList(info, type);
875             ListDelete(&(info->node));
876             info->item->infoNum--;
877         }
878     } while (false);
879 
880     SoftBusMutexUnlock(&g_discoveryInfoList->lock);
881     return ret;
882 }
883 
InnerStopDiscovery(const char * packageName,int32_t subscribeId,const ServiceType type,int32_t callingPid)884 static int32_t InnerStopDiscovery(const char *packageName, int32_t subscribeId, const ServiceType type,
885     int32_t callingPid)
886 {
887     int32_t ret = SoftBusMutexLock(&g_discoveryInfoList->lock);
888     DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, DISC_CONTROL, "lock failed");
889 
890     DiscInfo *infoNode = NULL;
891     do {
892         infoNode = RemoveInfoFromDiscoveryList(packageName, subscribeId, type, callingPid);
893         if (infoNode == NULL) {
894             DISC_LOGE(DISC_CONTROL, "delete info from list failed");
895             ret = SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE;
896             break;
897         }
898 
899         DFX_RECORD_DISC_CALL_START(infoNode, packageName, STOPDISCOVERY_FUNC);
900         ret = CallInterfaceByMedium(infoNode, packageName, STOPDISCOVERY_FUNC);
901         if (ret != SOFTBUS_OK) {
902             DISC_LOGE(DISC_CONTROL, "call interface by medium failed");
903         } else {
904             DfxRecordStopDiscoveryDevice(packageName, infoNode);
905         }
906         FreeDiscInfo(infoNode, type);
907     } while (false);
908 
909     SoftBusMutexUnlock(&g_discoveryInfoList->lock);
910     return ret;
911 }
912 
TransferModuleIdToPackageName(DiscModule moduleId)913 static const char* TransferModuleIdToPackageName(DiscModule moduleId)
914 {
915     return g_discModuleMap[moduleId - 1];
916 }
917 
InnerSetDiscoveryCallback(const char * packageName,const DiscInnerCallback * cb)918 static int32_t InnerSetDiscoveryCallback(const char *packageName, const DiscInnerCallback *cb)
919 {
920     if (SoftBusMutexLock(&(g_discoveryInfoList->lock)) != SOFTBUS_OK) {
921         DISC_LOGE(DISC_CONTROL, "lock failed");
922         return SOFTBUS_LOCK_ERR;
923     }
924 
925     bool isIdExist = false;
926     DiscItem *itemNode = NULL;
927     InnerCallback callback;
928     LIST_FOR_EACH_ENTRY(itemNode, &(g_discoveryInfoList->list), DiscItem, node) {
929         if (strcmp(itemNode->packageName, packageName) != 0) {
930             continue;
931         }
932         itemNode->callback.innerCb.OnDeviceFound = cb->OnDeviceFound;
933         isIdExist = true;
934         break;
935     }
936     if (isIdExist == false) {
937         callback.innerCb.OnDeviceFound = cb->OnDeviceFound;
938         itemNode = CreateDiscItem(g_discoveryInfoList, packageName, &callback, SUBSCRIBE_INNER_SERVICE);
939         if (itemNode == NULL) {
940             DISC_LOGE(DISC_CONTROL, "itemNode create failed");
941             (void)SoftBusMutexUnlock(&(g_discoveryInfoList->lock));
942             return SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE;
943         }
944     }
945     (void)SoftBusMutexUnlock(&(g_discoveryInfoList->lock));
946     return SOFTBUS_OK;
947 }
948 
DiscSetDiscoverCallback(DiscModule moduleId,const DiscInnerCallback * callback)949 int32_t DiscSetDiscoverCallback(DiscModule moduleId, const DiscInnerCallback *callback)
950 {
951     DISC_CHECK_AND_RETURN_RET_LOGW(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && callback != NULL,
952         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid parameters");
953     DISC_CHECK_AND_RETURN_RET_LOGW(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
954         "manager is not inited");
955     return InnerSetDiscoveryCallback(TransferModuleIdToPackageName(moduleId), callback);
956 }
957 
DiscPublish(DiscModule moduleId,const PublishInfo * info)958 int32_t DiscPublish(DiscModule moduleId, const PublishInfo *info)
959 {
960     DISC_CHECK_AND_RETURN_RET_LOGW(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
961         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid parameters");
962     DISC_CHECK_AND_RETURN_RET_LOGW(info->mode == DISCOVER_MODE_ACTIVE, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
963         "mode is not active");
964     DISC_CHECK_AND_RETURN_RET_LOGE(CheckPublishInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
965         "invalid info");
966     DISC_CHECK_AND_RETURN_RET_LOGE(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
967         "manager is not inited");
968 
969     DiscInfo *infoNode = CreateDiscInfoForPublish(info, 0);
970     DISC_CHECK_AND_RETURN_RET_LOGW(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, DISC_CONTROL,
971         "create info failed");
972 
973     int32_t ret = InnerPublishService(TransferModuleIdToPackageName(moduleId), infoNode, PUBLISH_INNER_SERVICE);
974     if (ret != SOFTBUS_OK) {
975         FreeDiscInfo(infoNode, PUBLISH_INNER_SERVICE);
976     }
977     return ret;
978 }
979 
DiscStartScan(DiscModule moduleId,const PublishInfo * info,int32_t callingPid)980 int32_t DiscStartScan(DiscModule moduleId, const PublishInfo *info, int32_t callingPid)
981 {
982     DISC_CHECK_AND_RETURN_RET_LOGW(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
983         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid parameters");
984     DISC_CHECK_AND_RETURN_RET_LOGW(info->mode == DISCOVER_MODE_PASSIVE, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
985         "mode is not passive");
986     DISC_CHECK_AND_RETURN_RET_LOGE(CheckPublishInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
987         "invalid info");
988     DISC_CHECK_AND_RETURN_RET_LOGE(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
989         "manager is not inited");
990 
991     DiscInfo *infoNode = CreateDiscInfoForPublish(info, callingPid);
992     DISC_CHECK_AND_RETURN_RET_LOGE(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, DISC_CONTROL,
993         "create info failed");
994 
995     int32_t ret = InnerPublishService(TransferModuleIdToPackageName(moduleId), infoNode, PUBLISH_INNER_SERVICE);
996     if (ret != SOFTBUS_OK) {
997         FreeDiscInfo(infoNode, PUBLISH_INNER_SERVICE);
998     }
999     return ret;
1000 }
1001 
DiscUnpublish(DiscModule moduleId,int32_t publishId,int32_t callingPid)1002 int32_t DiscUnpublish(DiscModule moduleId, int32_t publishId, int32_t callingPid)
1003 {
1004     DISC_CHECK_AND_RETURN_RET_LOGW(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX,
1005         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid moduleId");
1006     DISC_CHECK_AND_RETURN_RET_LOGW(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1007         "manager is not inited");
1008 
1009     return InnerUnPublishService(TransferModuleIdToPackageName(moduleId), publishId, PUBLISH_INNER_SERVICE,
1010         callingPid);
1011 }
1012 
DiscStartAdvertise(DiscModule moduleId,const SubscribeInfo * info,int32_t callingPid)1013 int32_t DiscStartAdvertise(DiscModule moduleId, const SubscribeInfo *info, int32_t callingPid)
1014 {
1015     DISC_CHECK_AND_RETURN_RET_LOGW(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
1016         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid parameters");
1017     DISC_CHECK_AND_RETURN_RET_LOGW(info->mode == DISCOVER_MODE_ACTIVE, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1018         "mode is not active");
1019     DISC_CHECK_AND_RETURN_RET_LOGE(CheckSubscribeInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1020         "invalid info");
1021     DISC_CHECK_AND_RETURN_RET_LOGE(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1022         "manager is not inited");
1023 
1024     DiscInfo *infoNode = CreateDiscInfoForSubscribe(info, callingPid);
1025     DISC_CHECK_AND_RETURN_RET_LOGE(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, DISC_CONTROL,
1026         "create info failed");
1027 
1028     int32_t ret = InnerStartDiscovery(TransferModuleIdToPackageName(moduleId), infoNode, NULL, SUBSCRIBE_INNER_SERVICE);
1029     if (ret != SOFTBUS_OK) {
1030         FreeDiscInfo(infoNode, SUBSCRIBE_INNER_SERVICE);
1031     }
1032     return ret;
1033 }
1034 
DiscSubscribe(DiscModule moduleId,const SubscribeInfo * info)1035 int32_t DiscSubscribe(DiscModule moduleId, const SubscribeInfo *info)
1036 {
1037     DISC_CHECK_AND_RETURN_RET_LOGW(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
1038         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid parameters");
1039     DISC_CHECK_AND_RETURN_RET_LOGW(info->mode == DISCOVER_MODE_PASSIVE, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1040         "mode is not passive");
1041     DISC_CHECK_AND_RETURN_RET_LOGE(CheckSubscribeInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1042         "invalid info");
1043     DISC_CHECK_AND_RETURN_RET_LOGE(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1044         "manager is not inited");
1045 
1046     DiscInfo *infoNode = CreateDiscInfoForSubscribe(info, 0);
1047     DISC_CHECK_AND_RETURN_RET_LOGE(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, DISC_CONTROL,
1048         "create info failed");
1049 
1050     int32_t ret = InnerStartDiscovery(TransferModuleIdToPackageName(moduleId), infoNode, NULL, SUBSCRIBE_INNER_SERVICE);
1051     if (ret != SOFTBUS_OK) {
1052         FreeDiscInfo(infoNode, SUBSCRIBE_INNER_SERVICE);
1053     }
1054     return ret;
1055 }
1056 
DiscStopAdvertise(DiscModule moduleId,int32_t subscribeId,int32_t callingPid)1057 int32_t DiscStopAdvertise(DiscModule moduleId, int32_t subscribeId, int32_t callingPid)
1058 {
1059     DISC_CHECK_AND_RETURN_RET_LOGW(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX,
1060         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid moduleId");
1061     DISC_CHECK_AND_RETURN_RET_LOGW(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1062         "manager is not inited");
1063 
1064     return InnerStopDiscovery(TransferModuleIdToPackageName(moduleId), subscribeId, SUBSCRIBE_INNER_SERVICE,
1065         callingPid);
1066 }
1067 
IsInnerPackageName(const char * packageName)1068 static bool IsInnerPackageName(const char *packageName)
1069 {
1070     for (uint32_t i = 0; i < MODULE_MAX; i++) {
1071         if (strcmp(packageName, g_discModuleMap[i]) == 0) {
1072             DISC_LOGD(DISC_CONTROL, "true");
1073             return true;
1074         }
1075     }
1076     DISC_LOGD(DISC_CONTROL, "false");
1077     return false;
1078 }
1079 
DiscPublishService(const char * packageName,const PublishInfo * info,int32_t callingPid)1080 int32_t DiscPublishService(const char *packageName, const PublishInfo *info, int32_t callingPid)
1081 {
1082     DISC_CHECK_AND_RETURN_RET_LOGE(packageName != NULL && info != NULL, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1083         "invalid parameters");
1084     DISC_CHECK_AND_RETURN_RET_LOGW(strlen(packageName) < PKG_NAME_SIZE_MAX,
1085         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "package name too long");
1086     DISC_CHECK_AND_RETURN_RET_LOGE(!IsInnerPackageName(packageName), SOFTBUS_INVALID_PARAM,
1087         DISC_CONTROL, "package name is reserved, not allowed");
1088     DISC_CHECK_AND_RETURN_RET_LOGW(CheckPublishInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1089         "invalid info");
1090     DISC_CHECK_AND_RETURN_RET_LOGE(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1091         "manager is not inited");
1092 
1093     DiscInfo *infoNode = CreateDiscInfoForPublish(info, callingPid);
1094     DISC_CHECK_AND_RETURN_RET_LOGE(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, DISC_CONTROL,
1095         "create info failed");
1096 
1097     int32_t ret = InnerPublishService(packageName, infoNode, PUBLISH_SERVICE);
1098     if (ret != SOFTBUS_OK) {
1099         FreeDiscInfo(infoNode, PUBLISH_SERVICE);
1100     }
1101     return ret;
1102 }
1103 
DiscUnPublishService(const char * packageName,int32_t publishId,int32_t callingPid)1104 int32_t DiscUnPublishService(const char *packageName, int32_t publishId, int32_t callingPid)
1105 {
1106     DISC_CHECK_AND_RETURN_RET_LOGW(packageName != NULL && strlen(packageName) < PKG_NAME_SIZE_MAX,
1107         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid parameters");
1108     DISC_CHECK_AND_RETURN_RET_LOGE(!IsInnerPackageName(packageName), SOFTBUS_INVALID_PARAM,
1109         DISC_CONTROL, "package name is reserved, not allowed");
1110     DISC_CHECK_AND_RETURN_RET_LOGW(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1111         "manager is not inited");
1112 
1113     return InnerUnPublishService(packageName, publishId, PUBLISH_SERVICE, callingPid);
1114 }
1115 
DiscStartDiscovery(const char * packageName,const SubscribeInfo * info,const IServerDiscInnerCallback * cb,int32_t callingPid)1116 int32_t DiscStartDiscovery(const char *packageName, const SubscribeInfo *info,
1117     const IServerDiscInnerCallback *cb, int32_t callingPid)
1118 {
1119     DISC_CHECK_AND_RETURN_RET_LOGW(packageName != NULL && strlen(packageName) < PKG_NAME_SIZE_MAX,
1120         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid package name");
1121     DISC_CHECK_AND_RETURN_RET_LOGE(!IsInnerPackageName(packageName), SOFTBUS_INVALID_PARAM,
1122         DISC_CONTROL, "package name is reserved, not allowed");
1123     DISC_CHECK_AND_RETURN_RET_LOGW(info != NULL && cb != NULL, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1124         "invalid parameters");
1125     DISC_CHECK_AND_RETURN_RET_LOGE(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1126         "manager is not inited");
1127     DISC_CHECK_AND_RETURN_RET_LOGE(CheckSubscribeInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, DISC_CONTROL,
1128         "invalid info");
1129 
1130     DiscInfo *infoNode = CreateDiscInfoForSubscribe(info, callingPid);
1131     DISC_CHECK_AND_RETURN_RET_LOGE(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, DISC_CONTROL,
1132         "create info failed");
1133 
1134     int32_t ret = InnerStartDiscovery(packageName, infoNode, cb, SUBSCRIBE_SERVICE);
1135     if (ret != SOFTBUS_OK) {
1136         FreeDiscInfo(infoNode, SUBSCRIBE_SERVICE);
1137     }
1138     return ret;
1139 }
1140 
DiscStopDiscovery(const char * packageName,int32_t subscribeId,int32_t callingPid)1141 int32_t DiscStopDiscovery(const char *packageName, int32_t subscribeId, int32_t callingPid)
1142 {
1143     DISC_CHECK_AND_RETURN_RET_LOGW(packageName != NULL && strlen(packageName) < PKG_NAME_SIZE_MAX,
1144         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid parameters");
1145     DISC_CHECK_AND_RETURN_RET_LOGE(!IsInnerPackageName(packageName), SOFTBUS_INVALID_PARAM,
1146         DISC_CONTROL, "package name is reserved, not allowed");
1147     DISC_CHECK_AND_RETURN_RET_LOGW(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, DISC_CONTROL,
1148         "manager is not inited");
1149 
1150     return InnerStopDiscovery(packageName, subscribeId, SUBSCRIBE_SERVICE, callingPid);
1151 }
1152 
DiscLinkStatusChanged(LinkStatus status,ExchangeMedium medium)1153 void DiscLinkStatusChanged(LinkStatus status, ExchangeMedium medium)
1154 {
1155     if (medium == COAP) {
1156         if (g_discCoapInterface != NULL) {
1157             g_discCoapInterface->LinkStatusChanged(status);
1158         }
1159     } else {
1160         DISC_LOGE(DISC_CONTROL, "not support medium=%{public}d", medium);
1161     }
1162 }
1163 
DiscDeviceInfoChanged(InfoTypeChanged type)1164 void DiscDeviceInfoChanged(InfoTypeChanged type)
1165 {
1166     DISC_LOGI(DISC_CONTROL, "type=%{public}d", type);
1167     if (g_discBleInterface != NULL && g_discBleInterface->UpdateLocalDeviceInfo != NULL) {
1168         g_discBleInterface->UpdateLocalDeviceInfo(type);
1169     }
1170     if (g_discCoapInterface != NULL && g_discCoapInterface->UpdateLocalDeviceInfo != NULL) {
1171         g_discCoapInterface->UpdateLocalDeviceInfo(type);
1172     }
1173 }
1174 
CreateIdContainer(int32_t id,const char * pkgName,int32_t pid)1175 static IdContainer* CreateIdContainer(int32_t id, const char *pkgName, int32_t pid)
1176 {
1177     IdContainer *container = SoftBusCalloc(sizeof(IdContainer));
1178     if (container == NULL) {
1179         DISC_LOGE(DISC_CONTROL, "container calloc failed");
1180         return NULL;
1181     }
1182 
1183     ListInit(&container->node);
1184     container->id = id;
1185     container->pid = pid;
1186 
1187     uint32_t nameLen = strlen(pkgName) + 1;
1188     container->pkgName = SoftBusCalloc(nameLen);
1189     if (container->pkgName == NULL) {
1190         DISC_LOGE(DISC_CONTROL, "Container pkgName calloc failed");
1191         SoftBusFree(container);
1192         return NULL;
1193     }
1194 
1195     if (strcpy_s(container->pkgName, nameLen, pkgName) != EOK) {
1196         DISC_LOGE(DISC_CONTROL, "strcpy_s failed");
1197         SoftBusFree(container->pkgName);
1198         container->pkgName = NULL;
1199         SoftBusFree(container);
1200         return NULL;
1201     }
1202 
1203     return container;
1204 }
1205 
DestroyIdContainer(IdContainer * container)1206 static void DestroyIdContainer(IdContainer* container)
1207 {
1208     SoftBusFree(container->pkgName);
1209     SoftBusFree(container);
1210 }
1211 
CleanupPublishDiscovery(ListNode * ids,ServiceType type)1212 static void CleanupPublishDiscovery(ListNode *ids, ServiceType type)
1213 {
1214     IdContainer *it = NULL;
1215     int32_t ret = SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE;
1216 
1217     LIST_FOR_EACH_ENTRY(it, ids, IdContainer, node) {
1218         if (type == PUBLISH_SERVICE) {
1219             ret = DiscUnPublishService(it->pkgName, it->id, it->pid);
1220             DISC_LOGI(DISC_CONTROL, "clean publish pkgName=%{public}s, id=%{public}d, ret=%{public}d",
1221                 it->pkgName, it->id, ret);
1222         } else if (type == SUBSCRIBE_SERVICE) {
1223             ret = DiscStopDiscovery(it->pkgName, it->id, it->pid);
1224             DISC_LOGI(DISC_CONTROL, "clean subscribe pkgName=%{public}s, id=%{public}d, ret=%{public}d",
1225                 it->pkgName, it->id, ret);
1226         }
1227     }
1228 }
1229 
RemoveDiscInfoByPackageName(SoftBusList * itemList,const ServiceType type,const char * pkgName,int32_t pid)1230 static void RemoveDiscInfoByPackageName(SoftBusList *itemList, const ServiceType type, const char *pkgName,
1231     int32_t pid)
1232 {
1233     ListNode ids;
1234     ListInit(&ids);
1235 
1236     if (SoftBusMutexLock(&itemList->lock) != SOFTBUS_OK) {
1237         DISC_LOGE(DISC_CONTROL, "lock failed");
1238         return;
1239     }
1240 
1241     DiscItem *itemNode = NULL;
1242     IdContainer *container = NULL;
1243     LIST_FOR_EACH_ENTRY(itemNode, &itemList->list, DiscItem, node) {
1244         if (pkgName != NULL) {
1245             if (strcmp(itemNode->packageName, pkgName) != 0) {
1246                 continue;
1247             }
1248         }
1249 
1250         DiscInfo *infoNode = NULL;
1251         LIST_FOR_EACH_ENTRY(infoNode, &itemNode->InfoList, DiscInfo, node) {
1252             if (pid != SKIP_VALID_PID_VALUE && infoNode->pid != pid) {
1253                 continue;
1254             }
1255             container = CreateIdContainer(infoNode->id, itemNode->packageName, infoNode->pid);
1256             if (container == NULL) {
1257                 DISC_LOGE(DISC_CONTROL, "CreateIdContainer failed");
1258                 (void)SoftBusMutexUnlock(&itemList->lock);
1259                 goto CLEANUP;
1260             }
1261             ListTailInsert(&ids, &container->node);
1262         }
1263     }
1264 
1265     (void)SoftBusMutexUnlock(&itemList->lock);
1266     CleanupPublishDiscovery(&ids, type);
1267 
1268 CLEANUP:
1269     while (!IsListEmpty(&ids)) {
1270         container = LIST_ENTRY(ids.next, IdContainer, node);
1271         ListDelete(&container->node);
1272         DestroyIdContainer(container);
1273     }
1274 }
1275 
RemoveAllDiscInfoForPublish(void)1276 static void RemoveAllDiscInfoForPublish(void)
1277 {
1278     RemoveDiscInfoByPackageName(g_publishInfoList, PUBLISH_SERVICE, NULL, SKIP_VALID_PID_VALUE);
1279     DestroySoftBusList(g_publishInfoList);
1280     g_publishInfoList = NULL;
1281 }
1282 
RemoveAllDiscInfoForDiscovery(void)1283 static void RemoveAllDiscInfoForDiscovery(void)
1284 {
1285     RemoveDiscInfoByPackageName(g_discoveryInfoList, SUBSCRIBE_SERVICE, NULL, SKIP_VALID_PID_VALUE);
1286     DestroySoftBusList(g_discoveryInfoList);
1287     g_discoveryInfoList = NULL;
1288 }
1289 
RemoveDiscInfoForPublish(const char * pkgName,int32_t pid)1290 static void RemoveDiscInfoForPublish(const char *pkgName, int32_t pid)
1291 {
1292     RemoveDiscInfoByPackageName(g_publishInfoList, PUBLISH_SERVICE, pkgName, pid);
1293 }
1294 
RemoveDiscInfoForDiscovery(const char * pkgName,int32_t pid)1295 static void RemoveDiscInfoForDiscovery(const char *pkgName, int32_t pid)
1296 {
1297     RemoveDiscInfoByPackageName(g_discoveryInfoList, SUBSCRIBE_SERVICE, pkgName, pid);
1298 }
1299 
DiscMgrDeathCallback(const char * pkgName,int32_t pid)1300 void DiscMgrDeathCallback(const char *pkgName, int32_t pid)
1301 {
1302     DISC_CHECK_AND_RETURN_LOGE(pkgName != NULL, DISC_CONTROL, "pkgName is null");
1303     DISC_CHECK_AND_RETURN_LOGE(!IsInnerPackageName(pkgName), DISC_CONTROL, "package name is reserved, not allowed");
1304     DISC_CHECK_AND_RETURN_LOGE(g_isInited == true, DISC_CONTROL, "disc manager is not inited");
1305 
1306     DISC_LOGD(DISC_CONTROL, "pkg is dead. pkgName=%{public}s", pkgName);
1307     DISC_CHECK_AND_RETURN_LOGE(pid != getpid(), DISC_CONTROL, "pid is different");
1308     RemoveDiscInfoForPublish(pkgName, pid);
1309     RemoveDiscInfoForDiscovery(pkgName, pid);
1310 }
1311 
DiscMgrInit(void)1312 int32_t DiscMgrInit(void)
1313 {
1314     DISC_CHECK_AND_RETURN_RET_LOGE(g_isInited == false, SOFTBUS_OK, DISC_INIT, "already inited");
1315 
1316     g_discMgrMediumCb.OnDeviceFound = DiscOnDeviceFound;
1317 
1318     g_discCoapInterface = DiscCoapInit(&g_discMgrMediumCb);
1319     g_discBleInterface = DiscBleInit(&g_discMgrMediumCb);
1320     g_discUsbInterface = DiscUsbDispatcherInit(&g_discMgrMediumCb);
1321 
1322     DISC_CHECK_AND_RETURN_RET_LOGE(g_discBleInterface != NULL || g_discCoapInterface != NULL ||
1323         g_discUsbInterface != NULL, SOFTBUS_DISCOVER_MANAGER_INIT_FAIL, DISC_INIT, "ble coap and usb init failed");
1324 
1325     g_publishInfoList = CreateSoftBusList();
1326     DISC_CHECK_AND_RETURN_RET_LOGE(g_publishInfoList != NULL, SOFTBUS_DISCOVER_MANAGER_INIT_FAIL, DISC_INIT,
1327         "init publish info list failed");
1328     g_discoveryInfoList = CreateSoftBusList();
1329     if (g_discoveryInfoList == NULL) {
1330         DISC_LOGE(DISC_INIT, "init discovery Info List failed");
1331         DestroySoftBusList(g_publishInfoList);
1332         g_publishInfoList = NULL;
1333         return SOFTBUS_DISCOVER_MANAGER_INIT_FAIL;
1334     }
1335 
1336     for (int32_t i = 0; i < CAPABILITY_MAX_BITNUM; i++) {
1337         ListInit(&g_capabilityList[i]);
1338     }
1339 
1340     g_isInited = true;
1341     return SOFTBUS_OK;
1342 }
1343 
DiscMgrDeinit(void)1344 void DiscMgrDeinit(void)
1345 {
1346     DISC_CHECK_AND_RETURN_LOGW(g_isInited == true, DISC_INIT, "disc manager is not inited");
1347 
1348     RemoveAllDiscInfoForPublish();
1349     RemoveAllDiscInfoForDiscovery();
1350 
1351     g_discCoapInterface = NULL;
1352     g_discBleInterface = NULL;
1353     g_discUsbInterface = NULL;
1354 
1355     DiscCoapDeinit();
1356     DiscBleDeinit();
1357     DiscUsbDispatcherDeinit();
1358 
1359     g_isInited = false;
1360     DISC_LOGI(DISC_INIT, "disc manager deinit success");
1361 }
1362 
DiscSetDisplayName(const char * pkgName,const char * nameData,uint32_t len)1363 int32_t DiscSetDisplayName(const char *pkgName, const char *nameData, uint32_t len)
1364 {
1365     DISC_CHECK_AND_RETURN_RET_LOGE(
1366         (pkgName != NULL && nameData != NULL), SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid param");
1367     int ret = SOFTBUS_PARSE_JSON_ERR;
1368     if (memset_s(&g_displayName, sizeof(g_displayName), 0, sizeof(g_displayName)) != EOK) {
1369         DISC_LOGE(DISC_CONTROL, "DiscSetDisplayName failed");
1370         return SOFTBUS_MEM_ERR;
1371     }
1372     cJSON *json = cJSON_ParseWithLength(nameData, len);
1373     DISC_CHECK_AND_RETURN_RET_LOGE(json != NULL, SOFTBUS_PARSE_JSON_ERR, DISC_CONTROL, "parse cJSON failed");
1374 
1375     if (!GetJsonObjectStringItem(json, JSON_KEY_RAW_NAME, g_displayName.raw, DISPLAY_NAME_BUF_LEN)) {
1376         DISC_LOGE(DISC_CONTROL, "GetJsonObjectStringItem raw name failed. displayName=%{public}s", g_displayName.raw);
1377         goto CLEANUP;
1378     }
1379 
1380     if (LnnSetLocalDeviceName(g_displayName.raw) != SOFTBUS_OK) {
1381         DISC_LOGE(DISC_CONTROL, "LnnSetLocalDeviceName fail");
1382         goto CLEANUP;
1383     }
1384 
1385     if (!GetJsonObjectStringItem(json, JSON_KEY_NAME_LEN_18, g_displayName.name18, sizeof(g_displayName.name18))) {
1386         DISC_LOGE(DISC_CONTROL, "GetJsonObjectStringItem name18 failed. displayName=%{public}s", g_displayName.name18);
1387         goto CLEANUP;
1388     }
1389 
1390     if (!GetJsonObjectStringItem(json, JSON_KEY_NAME_LEN_21, g_displayName.name21, sizeof(g_displayName.name21))) {
1391         DISC_LOGE(DISC_CONTROL, "GetJsonObjectStringItem name21 failed. displayName=%{public}s", g_displayName.name21);
1392         goto CLEANUP;
1393     }
1394 
1395     if (!GetJsonObjectStringItem(json, JSON_KEY_NAME_LEN_24, g_displayName.name24, sizeof(g_displayName.name24))) {
1396         DISC_LOGE(DISC_CONTROL, "GetJsonObjectStringItem name24 failed. displayName=%{public}s", g_displayName.name24);
1397         goto CLEANUP;
1398     }
1399     DiscDeviceInfoChanged(TYPE_LOCAL_DEVICE_NAME);
1400     ret = SOFTBUS_OK;
1401 CLEANUP:
1402     cJSON_Delete(json);
1403     return ret;
1404 }
1405 
DiscGetDisplayName(char * displayName,uint32_t length,uint32_t remainLen)1406 int32_t DiscGetDisplayName(char *displayName, uint32_t length, uint32_t remainLen)
1407 {
1408     DISC_CHECK_AND_RETURN_RET_LOGE((displayName != NULL && remainLen > 0 && remainLen <= DISPLAY_NAME_BUF_LEN),
1409         SOFTBUS_INVALID_PARAM, DISC_CONTROL, "invalid param");
1410     char *source = NULL;
1411     uint32_t len = 0;
1412     if (remainLen > strlen(g_displayName.raw)) {
1413         source = g_displayName.raw;
1414         len = strlen(g_displayName.raw);
1415         goto END;
1416     }
1417     if (remainLen > DISPLAY_NAME_LEN_24) {
1418         source = g_displayName.name24;
1419         len = DISPLAY_NAME_LEN_24;
1420         goto END;
1421     }
1422     if (remainLen > DISPLAY_NAME_LEN_21) {
1423         source = g_displayName.name21;
1424         len = DISPLAY_NAME_LEN_21;
1425         goto END;
1426     }
1427     if (remainLen > DISPLAY_NAME_LEN_18) {
1428         source = g_displayName.name18;
1429         len = DISPLAY_NAME_LEN_18;
1430         goto END;
1431     } else {
1432         source = g_displayName.name18;
1433         len = remainLen;
1434     }
1435 
1436 END:
1437     DISC_CHECK_AND_RETURN_RET_LOGW(len < length, SOFTBUS_INVALID_PARAM, DISC_CONTROL, "length too long");
1438     if (memcpy_s(displayName, length, source, len) != EOK) {
1439         DISC_LOGE(DISC_CONTROL, "memcpy reply fail");
1440         return SOFTBUS_MEM_ERR;
1441     }
1442     displayName[len] = '\0';
1443     return SOFTBUS_OK;
1444 }
1445