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