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