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