• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_manager.h"
17 #include "common_list.h"
18 #include "disc_ble_dispatcher.h"
19 #include "disc_coap.h"
20 #include "securec.h"
21 #include "softbus_adapter_mem.h"
22 #include "softbus_adapter_thread.h"
23 #include "softbus_adapter_timer.h"
24 #include "softbus_def.h"
25 #include "softbus_error_code.h"
26 #include "softbus_log.h"
27 #include "softbus_hisysevt_discreporter.h"
28 #include "softbus_utils.h"
29 
30 static bool g_isInited = false;
31 
32 static SoftBusList *g_publishInfoList = NULL;
33 static SoftBusList *g_discoveryInfoList = NULL;
34 
35 static DiscoveryFuncInterface *g_discCoapInterface = NULL;
36 static DiscoveryFuncInterface *g_discBleInterface = NULL;
37 
38 static DiscInnerCallback g_discMgrMediumCb;
39 
40 static ListNode g_capabilityList[CAPABILITY_MAX_BITNUM];
41 
42 static const char *g_discModuleMap[] = {
43     "MODULE_LNN",
44     "MODULE_CONN",
45 };
46 
47 typedef enum {
48     MIN_SERVICE = 0,
49     PUBLISH_SERVICE = MIN_SERVICE,
50     PUBLISH_INNER_SERVICE = 1,
51     SUBSCRIBE_SERVICE = 2,
52     SUBSCRIBE_INNER_SERVICE = 3,
53     MAX_SERVICE = SUBSCRIBE_INNER_SERVICE,
54 } ServiceType;
55 
56 typedef union {
57     PublishOption publishOption;
58     SubscribeOption subscribeOption;
59 } InnerOption;
60 
61 typedef union  {
62     IServerDiscInnerCallback serverCb;
63     DiscInnerCallback innerCb;
64 } InnerCallback;
65 
66 typedef struct {
67     ListNode node;
68     char packageName[PKG_NAME_SIZE_MAX];
69     InnerCallback callback;
70     uint32_t infoNum;
71     ListNode InfoList;
72 } DiscItem;
73 
74 typedef struct {
75     ListNode node;
76     int32_t id;
77     DiscoverMode mode;
78     ExchangeMedium medium;
79     InnerOption option;
80     ListNode capNode;
81     DiscItem *item;
82     DiscoveryStatistics statistics;
83 } DiscInfo;
84 
85 typedef struct {
86     ListNode node;
87     int32_t id;
88     char *pkgName;
89 } IdContainer;
90 
DfxRecordStartDiscoveryDevice(DiscInfo * infoNode)91 static void DfxRecordStartDiscoveryDevice(DiscInfo *infoNode)
92 {
93     infoNode->statistics.startTime = SoftBusGetSysTimeMs();
94     infoNode->statistics.repTimes = 0;
95     infoNode->statistics.devNum = 0;
96     infoNode->statistics.discTimes = 0;
97 }
98 
DfxRecordDeviceFound(DiscInfo * infoNode,const DeviceInfo * device,const InnerDeviceInfoAddtions * addtions)99 static void DfxRecordDeviceFound(DiscInfo *infoNode, const DeviceInfo *device, const InnerDeviceInfoAddtions *addtions)
100 {
101     DLOGI("record device found");
102     if (infoNode->statistics.repTimes == 0) {
103         uint64_t costTime = SoftBusGetSysTimeMs() - infoNode->statistics.startTime;
104         SoftbusRecordFirstDiscTime((SoftBusDiscMedium)addtions->medium, costTime);
105     }
106     infoNode->statistics.repTimes++;
107     infoNode->statistics.devNum++;
108 }
DfxRecordStopDiscoveryDevice(const char * packageName,DiscInfo * infoNode)109 static void DfxRecordStopDiscoveryDevice(const char *packageName, DiscInfo *infoNode)
110 {
111     DiscoveryStatistics *statistics = &infoNode->statistics;
112     uint64_t totalTime = SoftBusGetSysTimeMs() - statistics->startTime;
113     SoftbusRecordBleDiscDetails((char *)packageName, totalTime, statistics->repTimes, statistics->devNum,
114                                 statistics->discTimes);
115 }
BitmapSet(uint32_t * bitMap,uint32_t pos)116 static void BitmapSet(uint32_t *bitMap, uint32_t pos)
117 {
118     *bitMap |= 1U << pos;
119 }
120 
IsBitmapSet(const uint32_t * bitMap,uint32_t pos)121 static bool IsBitmapSet(const uint32_t *bitMap, uint32_t pos)
122 {
123     return ((1U << pos) & (*bitMap)) ? true : false;
124 }
125 
CallSpecificInterfaceFunc(const InnerOption * option,const DiscoveryFuncInterface * interface,const DiscoverMode mode,InterfaceFuncType type)126 NO_SANITIZE("cfi") static int32_t CallSpecificInterfaceFunc(const InnerOption *option,
127     const DiscoveryFuncInterface *interface, const DiscoverMode mode, InterfaceFuncType type)
128 {
129     DISC_CHECK_AND_RETURN_RET_LOG(interface != NULL, SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL,
130                                   "interface is null");
131     switch (type) {
132         case PUBLISH_FUNC:
133             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Publish(&(option->publishOption))) :
134                 (interface->StartScan(&(option->publishOption))));
135         case UNPUBLISH_FUNC:
136             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->Unpublish(&(option->publishOption))) :
137                 (interface->StopScan(&(option->publishOption))));
138         case STARTDISCOVERTY_FUNC:
139             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StartAdvertise(&(option->subscribeOption))) :
140                 (interface->Subscribe(&(option->subscribeOption))));
141         case STOPDISCOVERY_FUNC:
142             return ((mode == DISCOVER_MODE_ACTIVE) ? (interface->StopAdvertise(&(option->subscribeOption))) :
143                 (interface->Unsubscribe(&(option->subscribeOption))));
144         default:
145             return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
146     }
147 }
148 
CallInterfaceByMedium(const DiscInfo * info,const InterfaceFuncType type)149 static int32_t CallInterfaceByMedium(const DiscInfo *info, const InterfaceFuncType type)
150 {
151     switch (info->medium) {
152         case COAP:
153             return CallSpecificInterfaceFunc(&(info->option), g_discCoapInterface, info->mode, type);
154         case BLE:
155             return CallSpecificInterfaceFunc(&(info->option), g_discBleInterface, info->mode, type);
156         case AUTO: {
157             int coapRes = CallSpecificInterfaceFunc(&(info->option), g_discCoapInterface, info->mode, type);
158             int bleRes = CallSpecificInterfaceFunc(&(info->option), g_discBleInterface, info->mode, type);
159             DISC_CHECK_AND_RETURN_RET_LOG(coapRes == SOFTBUS_OK || bleRes == SOFTBUS_OK,
160                                           SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL, "all medium failed");
161             return SOFTBUS_OK;
162         }
163         default:
164             return SOFTBUS_DISCOVER_MANAGER_INNERFUNCTION_FAIL;
165     }
166 }
167 
TransferStringCapToBitmap(const char * capability)168 static int32_t TransferStringCapToBitmap(const char *capability)
169 {
170     DISC_CHECK_AND_RETURN_RET_LOG(capability != NULL, SOFTBUS_DISCOVER_MANAGER_CAPABILITY_INVALID,
171                                   "capability is null");
172 
173     for (uint32_t i = 0; i < sizeof(g_capabilityMap) / sizeof(g_capabilityMap[0]); i++) {
174         if (strcmp(capability, g_capabilityMap[i].capability) == 0) {
175             DLOGI("capability=%s", capability);
176             return g_capabilityMap[i].bitmap;
177         }
178     }
179 
180     return SOFTBUS_DISCOVER_MANAGER_CAPABILITY_INVALID;
181 }
182 
AddDiscInfoToCapabilityList(DiscInfo * info,const ServiceType type)183 static void AddDiscInfoToCapabilityList(DiscInfo *info, const ServiceType type)
184 {
185     DISC_CHECK_AND_RETURN_LOG(type == SUBSCRIBE_SERVICE || type == SUBSCRIBE_INNER_SERVICE, "no need to add");
186 
187     for (uint32_t tmp = 0; tmp < CAPABILITY_MAX_BITNUM; tmp++) {
188         if (IsBitmapSet(&(info->option.subscribeOption.capabilityBitmap[0]), tmp) == true) {
189             if (type == SUBSCRIBE_SERVICE) {
190                 ListTailInsert(&(g_capabilityList[tmp]), &(info->capNode));
191             } else {
192                 ListNodeInsert(&(g_capabilityList[tmp]), &(info->capNode));
193             }
194             break;
195         }
196     }
197 }
198 
RemoveDiscInfoFromCapabilityList(DiscInfo * info,const ServiceType type)199 static void RemoveDiscInfoFromCapabilityList(DiscInfo *info, const ServiceType type)
200 {
201     DISC_CHECK_AND_RETURN_LOG(type == SUBSCRIBE_SERVICE || type == SUBSCRIBE_INNER_SERVICE, "no need to delete");
202     ListDelete(&(info->capNode));
203 }
204 
FreeDiscInfo(DiscInfo * info,const ServiceType type)205 static void FreeDiscInfo(DiscInfo *info, const ServiceType type)
206 {
207     if ((type == PUBLISH_SERVICE) || (type == PUBLISH_INNER_SERVICE)) {
208         SoftBusFree(info->option.publishOption.capabilityData);
209     }
210 
211     if ((type == SUBSCRIBE_SERVICE) || (type == SUBSCRIBE_INNER_SERVICE)) {
212         SoftBusFree(info->option.subscribeOption.capabilityData);
213     }
214     SoftBusFree(info);
215 }
216 
IsInnerModule(const DiscInfo * infoNode)217 static bool IsInnerModule(const DiscInfo *infoNode)
218 {
219     for (uint32_t i = 0; i < MODULE_MAX; i++) {
220         DLOGI("%s", infoNode->item->packageName);
221         if (strcmp(infoNode->item->packageName, g_discModuleMap[i]) == 0) {
222             DLOGI("true");
223             return true;
224         }
225     }
226     DLOGI("false");
227     return false;
228 }
229 
InnerDeviceFound(DiscInfo * infoNode,const DeviceInfo * device,const InnerDeviceInfoAddtions * additions)230 NO_SANITIZE("cfi") static void InnerDeviceFound(DiscInfo *infoNode, const DeviceInfo *device,
231                                                 const InnerDeviceInfoAddtions *additions)
232 {
233     if (IsInnerModule(infoNode) == false) {
234         (void)infoNode->item->callback.serverCb.OnServerDeviceFound(infoNode->item->packageName, device, additions);
235         return;
236     }
237 
238     if (GetCallLnnStatus()) {
239         DLOGI("call from inner module.");
240         if (infoNode->item->callback.innerCb.OnDeviceFound != NULL) {
241             DfxRecordDeviceFound(infoNode, device, additions);
242             infoNode->item->callback.innerCb.OnDeviceFound(device, additions);
243         }
244     }
245 }
246 
DiscOnDeviceFound(const DeviceInfo * device,const InnerDeviceInfoAddtions * additions)247 static void DiscOnDeviceFound(const DeviceInfo *device, const InnerDeviceInfoAddtions *additions)
248 {
249     DISC_CHECK_AND_RETURN_LOG(device != NULL, "device is null");
250     DISC_CHECK_AND_RETURN_LOG(additions != NULL, "additions is null");
251 
252     DLOGI("capabilityBitmap=%d, medium=%d", device->capabilityBitmap[0], additions->medium);
253     for (uint32_t tmp = 0; tmp < CAPABILITY_MAX_BITNUM; tmp++) {
254         if (IsBitmapSet((uint32_t *)device->capabilityBitmap, tmp) == false) {
255             continue;
256         }
257 
258         if (SoftBusMutexLock(&(g_discoveryInfoList->lock)) != 0) {
259             DLOGE("lock failed");
260             return;
261         }
262         DiscInfo *infoNode = NULL;
263         LIST_FOR_EACH_ENTRY(infoNode, &(g_capabilityList[tmp]), DiscInfo, capNode) {
264             DLOGI("find callback id=%d", infoNode->id);
265             infoNode->statistics.discTimes++;
266             InnerDeviceFound(infoNode, device, additions);
267         }
268         (void)SoftBusMutexUnlock(&(g_discoveryInfoList->lock));
269     }
270 }
271 
CheckPublishInfo(const PublishInfo * info)272 static int32_t CheckPublishInfo(const PublishInfo *info)
273 {
274     DISC_CHECK_AND_RETURN_RET_LOG(info->mode == DISCOVER_MODE_PASSIVE || info->mode == DISCOVER_MODE_ACTIVE,
275                                   SOFTBUS_INVALID_PARAM, "mode is invalid");
276     DISC_CHECK_AND_RETURN_RET_LOG(info->medium >= AUTO && info->medium <= COAP,
277                                   SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM, "mode is invalid");
278     DISC_CHECK_AND_RETURN_RET_LOG(info->freq >= LOW && info->freq <= SUPER_HIGH,
279                                   SOFTBUS_INVALID_PARAM, "freq is invalid");
280 
281     if (info->capabilityData == NULL) {
282         if (info->dataLen == 0) {
283             return SOFTBUS_OK;
284         } else {
285             DLOGE("capabilityData is NULL, dataLen != 0");
286             return SOFTBUS_INVALID_PARAM;
287         }
288     } else {
289         if (info->dataLen == 0) {
290             DLOGE("capabilityData is not NULL, dataLen == 0");
291             return SOFTBUS_INVALID_PARAM;
292         }
293         if (info->dataLen > MAX_CAPABILITYDATA_LEN) {
294             DLOGE("dataLen(%u) > max length", info->dataLen);
295             return SOFTBUS_INVALID_PARAM;
296         }
297         uint32_t len = strlen((char *)info->capabilityData);
298         if (info->capabilityData[info->dataLen] != '\0') {
299             DLOGE("capabilityData is not c-string format: len(%u) and dataLen(%u)", len, info->dataLen);
300             return SOFTBUS_INVALID_PARAM;
301         }
302         if (len != info->dataLen) {
303             DLOGE("capabilityData len(%u) != dataLen(%u)", len, info->dataLen);
304             return SOFTBUS_INVALID_PARAM;
305         }
306     }
307     return SOFTBUS_OK;
308 }
309 
CheckSubscribeInfo(const SubscribeInfo * info)310 static int32_t CheckSubscribeInfo(const SubscribeInfo *info)
311 {
312     DISC_CHECK_AND_RETURN_RET_LOG(info->mode == DISCOVER_MODE_PASSIVE || info->mode == DISCOVER_MODE_ACTIVE,
313                                   SOFTBUS_INVALID_PARAM, "mode is invalid");
314     DISC_CHECK_AND_RETURN_RET_LOG(info->medium >= AUTO && info->medium <= COAP,
315                                   SOFTBUS_DISCOVER_MANAGER_INVALID_MEDIUM, "mode is invalid");
316     DISC_CHECK_AND_RETURN_RET_LOG(info->freq >= LOW && info->freq <= SUPER_HIGH,
317                                   SOFTBUS_INVALID_PARAM, "freq is invalid");
318 
319     if (info->capabilityData == NULL) {
320         if (info->dataLen == 0) {
321             return SOFTBUS_OK;
322         } else {
323             DLOGE("capabilityData is NULL, dataLen != 0");
324             return SOFTBUS_INVALID_PARAM;
325         }
326     } else {
327         if (info->dataLen == 0) {
328             DLOGE("capabilityData is not NULL, dataLen == 0");
329             return SOFTBUS_INVALID_PARAM;
330         }
331         if (info->dataLen > MAX_CAPABILITYDATA_LEN) {
332             DLOGE("dataLen(%u) > max length", info->dataLen);
333             return SOFTBUS_INVALID_PARAM;
334         }
335         uint32_t len = strlen((char *)info->capabilityData);
336         if (info->capabilityData[info->dataLen] != '\0') {
337             DLOGE("capabilityData is not c-string format: len(%u) and dataLen(%u)", len, info->dataLen);
338             return SOFTBUS_INVALID_PARAM;
339         }
340         if (len != info->dataLen) {
341             DLOGE("capabilityData len(%u) != dataLen(%u)", len, info->dataLen);
342             return SOFTBUS_INVALID_PARAM;
343         }
344     }
345     return SOFTBUS_OK;
346 }
347 
SetDiscItemCallback(DiscItem * itemNode,const InnerCallback * cb,const ServiceType type)348 static void SetDiscItemCallback(DiscItem *itemNode, const InnerCallback *cb, const ServiceType type)
349 {
350     if ((type != SUBSCRIBE_INNER_SERVICE) && (type != SUBSCRIBE_SERVICE)) {
351         return;
352     }
353     if (type == SUBSCRIBE_SERVICE) {
354         itemNode->callback.serverCb.OnServerDeviceFound = cb->serverCb.OnServerDeviceFound;
355         return;
356     }
357     if ((itemNode->callback.innerCb.OnDeviceFound != NULL) && (cb->innerCb.OnDeviceFound == NULL)) {
358         return;
359     }
360     itemNode->callback.innerCb.OnDeviceFound = cb->innerCb.OnDeviceFound;
361 }
362 
CreateDiscItem(SoftBusList * serviceList,const char * packageName,const InnerCallback * cb,const ServiceType type)363 static DiscItem *CreateDiscItem(SoftBusList *serviceList, const char *packageName, const InnerCallback *cb,
364                                 const ServiceType type)
365 {
366     DiscItem *itemNode = (DiscItem *)SoftBusCalloc(sizeof(DiscItem));
367     DISC_CHECK_AND_RETURN_RET_LOG(itemNode != NULL, NULL, "calloc item node failed");
368 
369     if (strcpy_s(itemNode->packageName, PKG_NAME_SIZE_MAX, packageName) != EOK) {
370         SoftBusFree(itemNode);
371         return NULL;
372     }
373 
374     if ((type == PUBLISH_INNER_SERVICE) || (type == SUBSCRIBE_INNER_SERVICE)) {
375         ListNodeInsert(&(serviceList->list), &(itemNode->node));
376     } else if ((type == PUBLISH_SERVICE) || (type == SUBSCRIBE_SERVICE)) {
377         ListTailInsert(&(serviceList->list), &(itemNode->node));
378     }
379 
380     SetDiscItemCallback(itemNode, cb, type);
381 
382     serviceList->cnt++;
383     ListInit(&(itemNode->InfoList));
384     return itemNode;
385 }
386 
CreateDiscInfoForPublish(const PublishInfo * info)387 static DiscInfo *CreateDiscInfoForPublish(const PublishInfo *info)
388 {
389     DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo));
390     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, NULL, "calloc info node failed");
391 
392     ListInit(&(infoNode->node));
393     ListInit(&(infoNode->capNode));
394 
395     infoNode->id = info->publishId;
396     infoNode->medium = info->medium;
397     infoNode->mode = info->mode;
398 
399     PublishOption *option = &infoNode->option.publishOption;
400     option->freq = info->freq;
401     option->ranging = info->ranging;
402     option->dataLen = info->dataLen;
403 
404     if (info->dataLen != 0) {
405         option->capabilityData = (uint8_t *)SoftBusCalloc(info->dataLen);
406         if (option->capabilityData == NULL) {
407             DLOGE("alloc capability data failed");
408             SoftBusFree(infoNode);
409             return NULL;
410         }
411         (void)memcpy_s(option->capabilityData, info->dataLen, info->capabilityData, info->dataLen);
412     }
413 
414     int32_t bitmap = TransferStringCapToBitmap(info->capability);
415     if (bitmap < 0) {
416         DLOGE("capability not found");
417         FreeDiscInfo(infoNode, PUBLISH_SERVICE);
418         return NULL;
419     }
420     BitmapSet(option->capabilityBitmap, (uint32_t)bitmap);
421 
422     return infoNode;
423 }
424 
CreateDiscInfoForSubscribe(const SubscribeInfo * info)425 static DiscInfo *CreateDiscInfoForSubscribe(const SubscribeInfo *info)
426 {
427     DiscInfo *infoNode = (DiscInfo *)SoftBusCalloc(sizeof(DiscInfo));
428     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, NULL, "alloc info node failed");
429 
430     ListInit(&(infoNode->node));
431     ListInit(&(infoNode->capNode));
432 
433     infoNode->id = info->subscribeId;
434     infoNode->medium = info->medium;
435     infoNode->mode = info->mode;
436 
437     SubscribeOption *option = &infoNode->option.subscribeOption;
438     option->freq = info->freq;
439     option->dataLen = info->dataLen;
440     option->isSameAccount = info->isSameAccount;
441     option->isWakeRemote = info->isWakeRemote;
442 
443     if (info->dataLen != 0) {
444         option->capabilityData = (uint8_t *)SoftBusCalloc(info->dataLen);
445         if (option->capabilityData == NULL) {
446             DLOGE("alloc capability data failed");
447             SoftBusFree(infoNode);
448             return NULL;
449         }
450         (void)memcpy_s(option->capabilityData, info->dataLen, info->capabilityData, info->dataLen);
451     }
452 
453     int32_t bimap = TransferStringCapToBitmap(info->capability);
454     if (bimap < 0) {
455         DLOGE("capability not found");
456         FreeDiscInfo(infoNode, SUBSCRIBE_SERVICE);
457         return NULL;
458     }
459     BitmapSet(option->capabilityBitmap, (uint32_t)bimap);
460     DfxRecordStartDiscoveryDevice(infoNode);
461     return infoNode;
462 }
463 
AddDiscInfoToList(SoftBusList * serviceList,const char * packageName,const InnerCallback * cb,DiscInfo * info,ServiceType type)464 static int32_t AddDiscInfoToList(SoftBusList *serviceList, const char *packageName, const InnerCallback *cb,
465                                  DiscInfo *info, ServiceType type)
466 {
467     if (SoftBusMutexLock(&(serviceList->lock)) != 0) {
468         DLOGE("lock failed");
469         return SOFTBUS_LOCK_ERR;
470     }
471 
472     DiscItem *itemNode = NULL;
473     bool exist = false;
474     LIST_FOR_EACH_ENTRY(itemNode, &(serviceList->list), DiscItem, node) {
475         if (strcmp(itemNode->packageName, packageName) != 0) {
476             continue;
477         }
478 
479         DiscInfo *infoNode = NULL;
480         LIST_FOR_EACH_ENTRY(infoNode, &(itemNode->InfoList), DiscInfo, node) {
481             if (infoNode->id == info->id) {
482                 DLOGI("id already existed");
483                 (void)SoftBusMutexUnlock(&(serviceList->lock));
484                 return SOFTBUS_DISCOVER_MANAGER_DUPLICATE_PARAM;
485             }
486         }
487 
488         SetDiscItemCallback(itemNode, cb, type);
489         exist = true;
490         itemNode->infoNum++;
491         info->item = itemNode;
492         ListTailInsert(&(itemNode->InfoList), &(info->node));
493         AddDiscInfoToCapabilityList(info, type);
494         break;
495     }
496 
497     if (exist == false) {
498         itemNode = CreateDiscItem(serviceList, packageName, cb, type);
499         if (itemNode == NULL) {
500             DLOGE("itemNode create failed");
501             (void)SoftBusMutexUnlock(&(serviceList->lock));
502             return SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE;
503         }
504 
505         itemNode->infoNum++;
506         info->item = itemNode;
507         ListTailInsert(&(itemNode->InfoList), &(info->node));
508         AddDiscInfoToCapabilityList(info, type);
509     }
510 
511     (void)SoftBusMutexUnlock(&(serviceList->lock));
512     return SOFTBUS_OK;
513 }
514 
AddDiscInfoToPublishList(const char * packageName,const InnerCallback * cb,DiscInfo * info,ServiceType type)515 static int32_t AddDiscInfoToPublishList(const char *packageName, const InnerCallback *cb, DiscInfo *info,
516                                         ServiceType type)
517 {
518     return AddDiscInfoToList(g_publishInfoList, packageName, cb, info, type);
519 }
520 
AddDiscInfoToDiscoveryList(const char * packageName,const InnerCallback * cb,DiscInfo * info,ServiceType type)521 static int32_t AddDiscInfoToDiscoveryList(const char *packageName, const InnerCallback *cb, DiscInfo *info,
522                                           ServiceType type)
523 {
524     return AddDiscInfoToList(g_discoveryInfoList, packageName, cb, info, type);
525 }
526 
RemoveInfoFromList(SoftBusList * serviceList,const char * packageName,const int32_t id,const ServiceType type)527 static DiscInfo *RemoveInfoFromList(SoftBusList *serviceList, const char *packageName, const int32_t id,
528                                     const ServiceType type)
529 {
530     if (SoftBusMutexLock(&(serviceList->lock)) != 0) {
531         DLOGE("lock failed");
532         return NULL;
533     }
534 
535     bool isIdExist = false;
536     DiscItem *itemNode = NULL;
537     DiscInfo *infoNode = NULL;
538 
539     LIST_FOR_EACH_ENTRY(itemNode, &(serviceList->list), DiscItem, node) {
540         if (strcmp(itemNode->packageName, packageName) != 0) {
541             continue;
542         }
543 
544         if (itemNode->infoNum == 0) {
545             serviceList->cnt--;
546             ListDelete(&(itemNode->node));
547             SoftBusFree(itemNode);
548             (void)SoftBusMutexUnlock(&(serviceList->lock));
549             return NULL;
550         }
551 
552         LIST_FOR_EACH_ENTRY(infoNode, &(itemNode->InfoList), DiscInfo, node) {
553             if (infoNode->id != id) {
554                 continue;
555             }
556             isIdExist = true;
557             itemNode->infoNum--;
558             RemoveDiscInfoFromCapabilityList(infoNode, type);
559             ListDelete(&(infoNode->node));
560 
561             if (itemNode->infoNum == 0) {
562                 serviceList->cnt--;
563                 ListDelete(&(itemNode->node));
564                 SoftBusFree(itemNode);
565             }
566             break;
567         }
568         break;
569     }
570 
571     (void)SoftBusMutexUnlock(&(serviceList->lock));
572 
573     if (isIdExist == false) {
574         DLOGI("can not find publishId");
575         return NULL;
576     }
577     return infoNode;
578 }
579 
RemoveInfoFromPublishList(const char * packageName,const int32_t id,const ServiceType type)580 static DiscInfo *RemoveInfoFromPublishList(const char *packageName, const int32_t id, const ServiceType type)
581 {
582     return RemoveInfoFromList(g_publishInfoList, packageName, id, type);
583 }
584 
RemoveInfoFromDiscoveryList(const char * packageName,const int32_t id,const ServiceType type)585 static DiscInfo *RemoveInfoFromDiscoveryList(const char *packageName, const int32_t id, const ServiceType type)
586 {
587     return RemoveInfoFromList(g_discoveryInfoList, packageName, id, type);
588 }
589 
InnerPublishService(const char * packageName,DiscInfo * info,const ServiceType type)590 static int32_t InnerPublishService(const char *packageName, DiscInfo *info, const ServiceType type)
591 {
592     int32_t ret = AddDiscInfoToPublishList(packageName, NULL, info, type);
593     DISC_CHECK_AND_RETURN_RET_LOG(ret == SOFTBUS_OK, ret, "add info to list failed");
594 
595     ret = CallInterfaceByMedium(info, PUBLISH_FUNC);
596     if (ret != SOFTBUS_OK) {
597         DLOGE("DiscInterfaceByMedium failed");
598         ListDelete(&(info->node));
599         info->item->infoNum--;
600     }
601 
602     return ret;
603 }
604 
InnerUnPublishService(const char * packageName,int32_t publishId,const ServiceType type)605 static int32_t InnerUnPublishService(const char *packageName, int32_t publishId, const ServiceType type)
606 {
607     DiscInfo *infoNode = RemoveInfoFromPublishList(packageName, publishId, type);
608     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE,
609                                   "delete info from list failed");
610 
611     int32_t ret = CallInterfaceByMedium(infoNode, UNPUBLISH_FUNC);
612     DISC_CHECK_AND_RETURN_RET_LOG(ret == SOFTBUS_OK, ret, "DiscInterfaceByMedium failed");
613 
614     FreeDiscInfo(infoNode, type);
615     return SOFTBUS_OK;
616 }
617 
InnerStartDiscovery(const char * packageName,DiscInfo * info,const IServerDiscInnerCallback * cb,const ServiceType type)618 static int32_t InnerStartDiscovery(const char *packageName, DiscInfo *info, const IServerDiscInnerCallback *cb,
619                                    const ServiceType type)
620 {
621     InnerCallback callback;
622     callback.serverCb.OnServerDeviceFound = NULL;
623     if (cb != NULL) {
624         callback.serverCb.OnServerDeviceFound = cb->OnServerDeviceFound;
625     }
626 
627     int32_t ret = AddDiscInfoToDiscoveryList(packageName, &callback, info, type);
628     DISC_CHECK_AND_RETURN_RET_LOG(ret == SOFTBUS_OK, ret, "add info to list failed");
629 
630     ret = CallInterfaceByMedium(info, STARTDISCOVERTY_FUNC);
631     if (ret != SOFTBUS_OK) {
632         DLOGE("DiscInterfaceByMedium failed");
633         RemoveDiscInfoFromCapabilityList(info, type);
634         ListDelete(&(info->node));
635         info->item->infoNum--;
636     }
637     return ret;
638 }
639 
InnerStopDiscovery(const char * packageName,int32_t subscribeId,const ServiceType type)640 static int32_t InnerStopDiscovery(const char *packageName, int32_t subscribeId, const ServiceType type)
641 {
642     DiscInfo *infoNode = RemoveInfoFromDiscoveryList(packageName, subscribeId, type);
643     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_DELETE,
644                                   "delete info from list failed");
645 
646     int32_t ret = CallInterfaceByMedium(infoNode, STOPDISCOVERY_FUNC);
647     DISC_CHECK_AND_RETURN_RET_LOG(ret == SOFTBUS_OK, ret, "DiscInterfaceByMedium failed");
648 
649     DfxRecordStopDiscoveryDevice(packageName, infoNode);
650     FreeDiscInfo(infoNode, type);
651     return SOFTBUS_OK;
652 }
653 
TransferModuleIdToPackageName(DiscModule moduleId)654 static const char* TransferModuleIdToPackageName(DiscModule moduleId)
655 {
656     return g_discModuleMap[moduleId - 1];
657 }
658 
InnerSetDiscoveryCallback(const char * packageName,const DiscInnerCallback * cb)659 static int32_t InnerSetDiscoveryCallback(const char *packageName, const DiscInnerCallback *cb)
660 {
661     if (SoftBusMutexLock(&(g_discoveryInfoList->lock)) != 0) {
662         DLOGE("lock failed");
663         return SOFTBUS_LOCK_ERR;
664     }
665 
666     bool isIdExist = false;
667     DiscItem *itemNode = NULL;
668     InnerCallback callback;
669     LIST_FOR_EACH_ENTRY(itemNode, &(g_discoveryInfoList->list), DiscItem, node) {
670         if (strcmp(itemNode->packageName, packageName) != 0) {
671             continue;
672         }
673         itemNode->callback.innerCb.OnDeviceFound = cb->OnDeviceFound;
674         isIdExist = true;
675         break;
676     }
677     if (isIdExist == false) {
678         callback.innerCb.OnDeviceFound = cb->OnDeviceFound;
679         itemNode = CreateDiscItem(g_discoveryInfoList, packageName, &callback, SUBSCRIBE_INNER_SERVICE);
680         if (itemNode == NULL) {
681             DLOGE("itemNode create failed");
682             (void)SoftBusMutexUnlock(&(g_discoveryInfoList->lock));
683             return SOFTBUS_DISCOVER_MANAGER_ITEM_NOT_CREATE;
684         }
685     }
686     (void)SoftBusMutexUnlock(&(g_discoveryInfoList->lock));
687     return SOFTBUS_OK;
688 }
689 
DiscSetDiscoverCallback(DiscModule moduleId,const DiscInnerCallback * callback)690 NO_SANITIZE("cfi") int32_t DiscSetDiscoverCallback(DiscModule moduleId, const DiscInnerCallback *callback)
691 {
692     DISC_CHECK_AND_RETURN_RET_LOG(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && callback != NULL,
693                                   SOFTBUS_INVALID_PARAM, "invalid parameters");
694     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
695     return InnerSetDiscoveryCallback(TransferModuleIdToPackageName(moduleId), callback);
696 }
697 
DiscPublish(DiscModule moduleId,const PublishInfo * info)698 NO_SANITIZE("cfi") int32_t DiscPublish(DiscModule moduleId, const PublishInfo *info)
699 {
700     DISC_CHECK_AND_RETURN_RET_LOG(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
701                                   SOFTBUS_INVALID_PARAM, "invalid parameters");
702     DISC_CHECK_AND_RETURN_RET_LOG(info->mode == DISCOVER_MODE_ACTIVE, SOFTBUS_INVALID_PARAM, "mode is not active");
703     DISC_CHECK_AND_RETURN_RET_LOG(CheckPublishInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, "invalid info");
704     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
705 
706     DiscInfo *infoNode = CreateDiscInfoForPublish(info);
707     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, "create info failed");
708 
709     int32_t ret = InnerPublishService(TransferModuleIdToPackageName(moduleId), infoNode, PUBLISH_INNER_SERVICE);
710     if (ret != SOFTBUS_OK) {
711         FreeDiscInfo(infoNode, PUBLISH_INNER_SERVICE);
712     }
713     return ret;
714 }
715 
DiscStartScan(DiscModule moduleId,const PublishInfo * info)716 NO_SANITIZE("cfi") int32_t DiscStartScan(DiscModule moduleId, const PublishInfo *info)
717 {
718     DISC_CHECK_AND_RETURN_RET_LOG(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
719                                   SOFTBUS_INVALID_PARAM, "invalid parameters");
720     DISC_CHECK_AND_RETURN_RET_LOG(info->mode == DISCOVER_MODE_PASSIVE, SOFTBUS_INVALID_PARAM, "mode is not passive");
721     DISC_CHECK_AND_RETURN_RET_LOG(CheckPublishInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, "invalid info");
722     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
723 
724     DiscInfo *infoNode = CreateDiscInfoForPublish(info);
725     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, "create info failed");
726 
727     int32_t ret = InnerPublishService(TransferModuleIdToPackageName(moduleId), infoNode, PUBLISH_INNER_SERVICE);
728     if (ret != SOFTBUS_OK) {
729         FreeDiscInfo(infoNode, PUBLISH_INNER_SERVICE);
730     }
731     return ret;
732 }
733 
DiscUnpublish(DiscModule moduleId,int32_t publishId)734 NO_SANITIZE("cfi") int32_t DiscUnpublish(DiscModule moduleId, int32_t publishId)
735 {
736     DISC_CHECK_AND_RETURN_RET_LOG(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX,
737                                   SOFTBUS_INVALID_PARAM, "invalid moduleId");
738     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
739 
740     return InnerUnPublishService(TransferModuleIdToPackageName(moduleId), publishId, PUBLISH_INNER_SERVICE);
741 }
742 
DiscStartAdvertise(DiscModule moduleId,const SubscribeInfo * info)743 NO_SANITIZE("cfi") int32_t DiscStartAdvertise(DiscModule moduleId, const SubscribeInfo *info)
744 {
745     DISC_CHECK_AND_RETURN_RET_LOG(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
746                                   SOFTBUS_INVALID_PARAM, "invalid parameters");
747     DISC_CHECK_AND_RETURN_RET_LOG(info->mode == DISCOVER_MODE_ACTIVE, SOFTBUS_INVALID_PARAM, "mode is not active");
748     DISC_CHECK_AND_RETURN_RET_LOG(CheckSubscribeInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, "invalid info");
749     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
750 
751     DiscInfo *infoNode = CreateDiscInfoForSubscribe(info);
752     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, "create info failed");
753 
754     int32_t ret = InnerStartDiscovery(TransferModuleIdToPackageName(moduleId), infoNode, NULL, SUBSCRIBE_INNER_SERVICE);
755     if (ret != SOFTBUS_OK) {
756         FreeDiscInfo(infoNode, SUBSCRIBE_INNER_SERVICE);
757     }
758     return ret;
759 }
760 
DiscSubscribe(DiscModule moduleId,const SubscribeInfo * info)761 NO_SANITIZE("cfi") int32_t DiscSubscribe(DiscModule moduleId, const SubscribeInfo *info)
762 {
763     DISC_CHECK_AND_RETURN_RET_LOG(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX && info != NULL,
764                                   SOFTBUS_INVALID_PARAM, "invalid parameters");
765     DISC_CHECK_AND_RETURN_RET_LOG(info->mode == DISCOVER_MODE_PASSIVE, SOFTBUS_INVALID_PARAM, "mode is not passive");
766     DISC_CHECK_AND_RETURN_RET_LOG(CheckSubscribeInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, "invalid info");
767     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
768 
769     DiscInfo *infoNode = CreateDiscInfoForSubscribe(info);
770     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, "create info failed");
771 
772     int32_t ret = InnerStartDiscovery(TransferModuleIdToPackageName(moduleId), infoNode, NULL, SUBSCRIBE_INNER_SERVICE);
773     if (ret != SOFTBUS_OK) {
774         FreeDiscInfo(infoNode, SUBSCRIBE_INNER_SERVICE);
775     }
776     return ret;
777 }
778 
DiscStopAdvertise(DiscModule moduleId,int32_t subscribeId)779 NO_SANITIZE("cfi") int32_t DiscStopAdvertise(DiscModule moduleId, int32_t subscribeId)
780 {
781     DISC_CHECK_AND_RETURN_RET_LOG(moduleId >= MODULE_MIN && moduleId <= MODULE_MAX,
782                                   SOFTBUS_INVALID_PARAM, "invalid moduleId");
783     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
784 
785     return InnerStopDiscovery(TransferModuleIdToPackageName(moduleId), subscribeId, SUBSCRIBE_INNER_SERVICE);
786 }
787 
DiscPublishService(const char * packageName,const PublishInfo * info)788 NO_SANITIZE("cfi") int32_t DiscPublishService(const char *packageName, const PublishInfo *info)
789 {
790     DISC_CHECK_AND_RETURN_RET_LOG(packageName != NULL && info != NULL, SOFTBUS_INVALID_PARAM, "invalid parameters");
791     DISC_CHECK_AND_RETURN_RET_LOG(strlen(packageName) < PKG_NAME_SIZE_MAX,
792                                   SOFTBUS_INVALID_PARAM, "package name too long");
793     DISC_CHECK_AND_RETURN_RET_LOG(CheckPublishInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, "invalid info");
794     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
795 
796     DiscInfo *infoNode = CreateDiscInfoForPublish(info);
797     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, "create info failed");
798 
799     int32_t ret = InnerPublishService(packageName, infoNode, PUBLISH_SERVICE);
800     if (ret != SOFTBUS_OK) {
801         FreeDiscInfo(infoNode, PUBLISH_SERVICE);
802     }
803     return ret;
804 }
805 
DiscUnPublishService(const char * packageName,int32_t publishId)806 NO_SANITIZE("cfi") int32_t DiscUnPublishService(const char *packageName, int32_t publishId)
807 {
808     DISC_CHECK_AND_RETURN_RET_LOG(packageName != NULL && strlen(packageName) < PKG_NAME_SIZE_MAX,
809                                   SOFTBUS_INVALID_PARAM, "invalid parameters");
810     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
811 
812     return InnerUnPublishService(packageName, publishId, PUBLISH_SERVICE);
813 }
814 
DiscStartDiscovery(const char * packageName,const SubscribeInfo * info,const IServerDiscInnerCallback * cb)815 NO_SANITIZE("cfi") int32_t DiscStartDiscovery(const char *packageName, const SubscribeInfo *info,
816     const IServerDiscInnerCallback *cb)
817 {
818     DISC_CHECK_AND_RETURN_RET_LOG(packageName != NULL && strlen(packageName) < PKG_NAME_SIZE_MAX,
819                                   SOFTBUS_INVALID_PARAM, "invalid package name");
820     DISC_CHECK_AND_RETURN_RET_LOG(info != NULL && cb != NULL, SOFTBUS_INVALID_PARAM, "invalid parameters");
821     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
822     DISC_CHECK_AND_RETURN_RET_LOG(CheckSubscribeInfo(info) == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, "invalid info");
823 
824     DiscInfo *infoNode = CreateDiscInfoForSubscribe(info);
825     DISC_CHECK_AND_RETURN_RET_LOG(infoNode != NULL, SOFTBUS_DISCOVER_MANAGER_INFO_NOT_CREATE, "create info failed");
826 
827     int32_t ret = InnerStartDiscovery(packageName, infoNode, cb, SUBSCRIBE_SERVICE);
828     if (ret != SOFTBUS_OK) {
829         FreeDiscInfo(infoNode, SUBSCRIBE_SERVICE);
830     }
831     return ret;
832 }
833 
DiscStopDiscovery(const char * packageName,int32_t subscribeId)834 NO_SANITIZE("cfi") int32_t DiscStopDiscovery(const char *packageName, int32_t subscribeId)
835 {
836     DISC_CHECK_AND_RETURN_RET_LOG(packageName != NULL && strlen(packageName) < PKG_NAME_SIZE_MAX,
837                                   SOFTBUS_INVALID_PARAM, "invalid parameters");
838     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == true, SOFTBUS_DISCOVER_MANAGER_NOT_INIT, "manager is not inited");
839 
840     return InnerStopDiscovery(packageName, subscribeId, SUBSCRIBE_SERVICE);
841 }
842 
DiscLinkStatusChanged(LinkStatus status,ExchangeMedium medium)843 NO_SANITIZE("cfi") void DiscLinkStatusChanged(LinkStatus status, ExchangeMedium medium)
844 {
845     if (medium == COAP) {
846         if (g_discCoapInterface != NULL) {
847             g_discCoapInterface->LinkStatusChanged(status);
848         }
849     } else {
850         DLOGE("not support medium=%d", medium);
851     }
852 }
853 
DiscDeviceInfoChanged(InfoTypeChanged type)854 NO_SANITIZE("cfi") void DiscDeviceInfoChanged(InfoTypeChanged type)
855 {
856     DLOGI("type=%d", type);
857     if (g_discBleInterface != NULL && g_discBleInterface->UpdateLocalDeviceInfo != NULL) {
858         g_discBleInterface->UpdateLocalDeviceInfo(type);
859     }
860     if (g_discCoapInterface != NULL && g_discCoapInterface->UpdateLocalDeviceInfo != NULL) {
861         g_discCoapInterface->UpdateLocalDeviceInfo(type);
862     }
863 }
864 
CreateIdContainer(int32_t id,const char * pkgName)865 static IdContainer* CreateIdContainer(int32_t id, const char *pkgName)
866 {
867     IdContainer *container = SoftBusCalloc(sizeof(IdContainer));
868     if (container == NULL) {
869         return NULL;
870     }
871 
872     ListInit(&container->node);
873     container->id = id;
874 
875     uint32_t nameLen = strlen(pkgName) + 1;
876     container->pkgName = SoftBusCalloc(nameLen);
877     if (container->pkgName == NULL) {
878         SoftBusFree(container);
879         return NULL;
880     }
881 
882     if (strcpy_s(container->pkgName, nameLen, pkgName) != EOK) {
883         SoftBusFree(container);
884         return NULL;
885     }
886 
887     return container;
888 }
889 
DestroyIdContainer(IdContainer * container)890 static void DestroyIdContainer(IdContainer* container)
891 {
892     SoftBusFree(container->pkgName);
893     SoftBusFree(container);
894 }
895 
CleanupPublishDiscovery(ListNode * ids,ServiceType type)896 static void CleanupPublishDiscovery(ListNode *ids, ServiceType type)
897 {
898     IdContainer *it = NULL;
899     int32_t ret = SOFTBUS_ERR;
900 
901     LIST_FOR_EACH_ENTRY(it, ids, IdContainer, node) {
902         if (type == PUBLISH_SERVICE) {
903             ret = DiscUnPublishService(it->pkgName, it->id);
904             DLOGE("clean publish pkgName=%s id=%d ret=%d", it->pkgName, it->id, ret);
905             return;
906         } else if (type == SUBSCRIBE_SERVICE) {
907             ret = DiscStopDiscovery(it->pkgName, it->id);
908             DLOGE("clean subscribe pkgName=%s id=%d ret=%d", it->pkgName, it->id, ret);
909         }
910     }
911 }
912 
RemoveDiscInfoByPackageName(SoftBusList * itemList,const ServiceType type,const char * pkgName)913 static void RemoveDiscInfoByPackageName(SoftBusList *itemList, const ServiceType type, const char *pkgName)
914 {
915     ListNode ids;
916     ListInit(&ids);
917 
918     if (SoftBusMutexLock(&itemList->lock) != 0) {
919         DLOGE("lock failed");
920         return;
921     }
922 
923     DiscItem *itemNode = NULL;
924     IdContainer *container = NULL;
925     LIST_FOR_EACH_ENTRY(itemNode, &itemList->list, DiscItem, node) {
926         if (pkgName != NULL) {
927             if (strcmp(itemNode->packageName, pkgName) != 0) {
928                 continue;
929             }
930         }
931 
932         DiscInfo *infoNode = NULL;
933         LIST_FOR_EACH_ENTRY(infoNode, &itemNode->InfoList, DiscInfo, node) {
934             container = CreateIdContainer(infoNode->id, itemNode->packageName);
935             if (container == NULL) {
936                 DLOGE("CreateIdContainer failed");
937                 (void)SoftBusMutexUnlock(&itemList->lock);
938                 goto CLEANUP;
939             }
940             ListTailInsert(&ids, &container->node);
941         }
942     }
943 
944     (void)SoftBusMutexUnlock(&itemList->lock);
945     CleanupPublishDiscovery(&ids, type);
946 
947 CLEANUP:
948     while (!IsListEmpty(&ids)) {
949         container = LIST_ENTRY(ids.next, IdContainer, node);
950         ListDelete(&container->node);
951         DestroyIdContainer(container);
952     }
953 }
954 
RemoveAllDiscInfoForPublish(void)955 static void RemoveAllDiscInfoForPublish(void)
956 {
957     RemoveDiscInfoByPackageName(g_publishInfoList, PUBLISH_SERVICE, NULL);
958     DestroySoftBusList(g_publishInfoList);
959     g_publishInfoList = NULL;
960 }
961 
RemoveAllDiscInfoForDiscovery(void)962 static void RemoveAllDiscInfoForDiscovery(void)
963 {
964     RemoveDiscInfoByPackageName(g_discoveryInfoList, SUBSCRIBE_SERVICE, NULL);
965     DestroySoftBusList(g_discoveryInfoList);
966     g_discoveryInfoList = NULL;
967 }
968 
RemoveDiscInfoForPublish(const char * pkgName)969 static void RemoveDiscInfoForPublish(const char *pkgName)
970 {
971     RemoveDiscInfoByPackageName(g_publishInfoList, PUBLISH_SERVICE, pkgName);
972 }
973 
RemoveDiscInfoForDiscovery(const char * pkgName)974 static void RemoveDiscInfoForDiscovery(const char *pkgName)
975 {
976     RemoveDiscInfoByPackageName(g_discoveryInfoList, SUBSCRIBE_SERVICE, pkgName);
977 }
978 
DiscMgrDeathCallback(const char * pkgName)979 NO_SANITIZE("cfi") void DiscMgrDeathCallback(const char *pkgName)
980 {
981     DISC_CHECK_AND_RETURN_LOG(pkgName != NULL, "pkgName is null");
982     DISC_CHECK_AND_RETURN_LOG(g_isInited == true, "disc manager is not inited");
983 
984     DLOGI("%s is dead", pkgName);
985     RemoveDiscInfoForPublish(pkgName);
986     RemoveDiscInfoForDiscovery(pkgName);
987 }
988 
DiscMgrInit(void)989 NO_SANITIZE("cfi") int32_t DiscMgrInit(void)
990 {
991     DISC_CHECK_AND_RETURN_RET_LOG(g_isInited == false, SOFTBUS_OK, "already inited");
992 
993     g_discMgrMediumCb.OnDeviceFound = DiscOnDeviceFound;
994 
995     g_discCoapInterface = DiscCoapInit(&g_discMgrMediumCb);
996     g_discBleInterface = DiscBleInit(&g_discMgrMediumCb);
997     DISC_CHECK_AND_RETURN_RET_LOG(g_discBleInterface != NULL || g_discCoapInterface != NULL,
998                                   SOFTBUS_ERR, "ble and coap both init failed");
999 
1000     g_publishInfoList = CreateSoftBusList();
1001     DISC_CHECK_AND_RETURN_RET_LOG(g_publishInfoList != NULL, SOFTBUS_ERR, "init publish info list failed");
1002     g_discoveryInfoList = CreateSoftBusList();
1003     DISC_CHECK_AND_RETURN_RET_LOG(g_discoveryInfoList != NULL, SOFTBUS_ERR, "init discovery info list failed");
1004 
1005     for (int32_t i = 0; i < CAPABILITY_MAX_BITNUM; i++) {
1006         ListInit(&g_capabilityList[i]);
1007     }
1008 
1009     g_isInited = true;
1010     return SOFTBUS_OK;
1011 }
1012 
DiscMgrDeinit(void)1013 NO_SANITIZE("cfi") void DiscMgrDeinit(void)
1014 {
1015     DISC_CHECK_AND_RETURN_LOG(g_isInited == true, "disc manager is not inited");
1016 
1017     RemoveAllDiscInfoForPublish();
1018     RemoveAllDiscInfoForDiscovery();
1019 
1020     g_discCoapInterface = NULL;
1021     g_discBleInterface = NULL;
1022 
1023     DiscCoapDeinit();
1024     DiscBleDeinit();
1025 
1026     g_isInited = false;
1027     DLOGI("disc manager deinit success");
1028 }