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