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