1 /*
2 * Copyright (c) 2022-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 "discovery_manager.h"
17
18 #include <dlfcn.h>
19 #include <securec.h>
20
21 #include "softbus_common.h"
22
23 #include "dm_anonymous.h"
24 #include "dm_constants.h"
25 #include "parameter.h"
26
27 namespace OHOS {
28 namespace DistributedHardware {
29 const int32_t DISCOVERY_TIMEOUT = 120;
30 const uint16_t DM_INVALID_FLAG_ID = 0;
31 constexpr const char* LNN_DISC_CAPABILITY = "capability";
32 const std::string TYPE_MINE = "findDeviceMode";
33 const int32_t DECIMALISM = 10;
34
35 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
36 static std::mutex comDependencyLoadLock;
37 constexpr const char* LIB_DM_COMDENPENDENCY_NAME = "libdevicemanagerdependency.z.so";
38 bool DiscoveryManager::isSoLoaded_ = false;
39 IDeviceProfileConnector* DiscoveryManager::dpConnector_ = nullptr;
40 void* DiscoveryManager::dpConnectorHandle_ = nullptr;
41 #endif
42
DiscoveryManager(std::shared_ptr<SoftbusListener> softbusListener, std::shared_ptr<IDeviceManagerServiceListener> listener)43 DiscoveryManager::DiscoveryManager(std::shared_ptr<SoftbusListener> softbusListener,
44 std::shared_ptr<IDeviceManagerServiceListener> listener) : softbusListener_(softbusListener), listener_(listener)
45 {
46 LOGI("DiscoveryManager constructor.");
47 }
48
~DiscoveryManager()49 DiscoveryManager::~DiscoveryManager()
50 {
51 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
52 CloseCommonDependencyObj();
53 #endif
54 LOGI("DiscoveryManager destructor.");
55 }
56
EnableDiscoveryListener(const std::string &pkgName, const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)57 int32_t DiscoveryManager::EnableDiscoveryListener(const std::string &pkgName,
58 const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)
59 {
60 LOGI("DiscoveryManager::EnableDiscoveryListener begin for pkgName = %{public}s.", pkgName.c_str());
61 if (pkgName.empty()) {
62 LOGE("Invalid parameter, pkgName is empty.");
63 return ERR_DM_INPUT_PARA_INVALID;
64 }
65 DmSubscribeInfo dmSubInfo;
66 dmSubInfo.subscribeId = DM_INVALID_FLAG_ID;
67 dmSubInfo.mode = DmDiscoverMode::DM_DISCOVER_MODE_PASSIVE;
68 dmSubInfo.medium = DmExchangeMedium::DM_BLE;
69 dmSubInfo.freq = DmExchangeFreq::DM_LOW;
70 dmSubInfo.isSameAccount = false;
71 dmSubInfo.isWakeRemote = false;
72 if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_APPROACH) != EOK) {
73 LOGE("capability copy err.");
74 return ERR_DM_ENABLE_DISCOVERY_LISTENER_FAILED;
75 }
76 UpdateInfoFreq(discoverParam, dmSubInfo);
77 if (discoverParam.find(PARAM_KEY_META_TYPE) != discoverParam.end()) {
78 std::string metaType = discoverParam.find(PARAM_KEY_META_TYPE)->second;
79 LOGI("EnableDiscoveryListener, input MetaType = %{public}s in discoverParam map.", metaType.c_str());
80 }
81 if (discoverParam.find(PARAM_KEY_SUBSCRIBE_ID) != discoverParam.end()) {
82 dmSubInfo.subscribeId = std::atoi((discoverParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str());
83 {
84 std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
85 pkgName2SubIdMap_[pkgName] = dmSubInfo.subscribeId;
86 }
87 }
88 if (discoverParam.find(PARAM_KEY_DISC_CAPABILITY) != discoverParam.end()) {
89 std::string capability = discoverParam.find(PARAM_KEY_DISC_CAPABILITY)->second;
90 if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, capability.c_str()) != EOK) {
91 LOGI("EnableDiscoveryListener failed, capability copy err.");
92 return ERR_DM_ENABLE_DISCOVERY_LISTENER_FAILED;
93 }
94 }
95 LOGI("EnableDiscoveryListener capability = %{public}s,", std::string(dmSubInfo.capability).c_str());
96 {
97 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
98 capabilityMap_[pkgName] = std::string(dmSubInfo.capability);
99 }
100
101 int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, LNN_DISC_CAPABILITY);
102 if (ret != DM_OK) {
103 LOGE("EnableDiscoveryListener failed, softbus refresh lnn ret: %{public}d.", ret);
104 return ret;
105 }
106 softbusListener_->RegisterSoftbusLnnOpsCbk(pkgName, shared_from_this());
107 return DM_OK;
108 }
109
DisableDiscoveryListener(const std::string &pkgName, const std::map<std::string, std::string> &extraParam)110 int32_t DiscoveryManager::DisableDiscoveryListener(const std::string &pkgName,
111 const std::map<std::string, std::string> &extraParam)
112 {
113 LOGI("DiscoveryManager::DisableDiscoveryListener begin for pkgName = %{public}s.", pkgName.c_str());
114 if (pkgName.empty()) {
115 LOGE("Invalid parameter, pkgName is empty.");
116 return ERR_DM_INPUT_PARA_INVALID;
117 }
118
119 if (extraParam.find(PARAM_KEY_META_TYPE) != extraParam.end()) {
120 LOGI("DisableDiscoveryListener, input MetaType = %{public}s",
121 (extraParam.find(PARAM_KEY_META_TYPE)->second).c_str());
122 }
123 uint16_t subscribeId = DM_INVALID_FLAG_ID;
124 if (extraParam.find(PARAM_KEY_SUBSCRIBE_ID) != extraParam.end()) {
125 subscribeId = std::atoi((extraParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str());
126 {
127 std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
128 pkgName2SubIdMap_.erase(pkgName);
129 }
130 }
131 {
132 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
133 if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
134 capabilityMap_.erase(pkgName);
135 }
136 }
137 softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgName);
138 return softbusListener_->StopRefreshSoftbusLNN(subscribeId);
139 }
140
StartDiscovering(const std::string &pkgName, const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)141 int32_t DiscoveryManager::StartDiscovering(const std::string &pkgName,
142 const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)
143 {
144 LOGI("DiscoveryManager::StartDiscovering begin for pkgName = %{public}s.", pkgName.c_str());
145 if (pkgName.empty()) {
146 LOGE("Invalid parameter, pkgName is empty.");
147 return ERR_DM_INPUT_PARA_INVALID;
148 }
149 DmSubscribeInfo dmSubInfo;
150 ConfigDiscParam(discoverParam, &dmSubInfo);
151 if (HandleDiscoveryQueue(pkgName, dmSubInfo.subscribeId, filterOptions) != DM_OK) {
152 return ERR_DM_DISCOVERY_REPEATED;
153 }
154
155 bool isStandardMetaNode = true;
156 if (discoverParam.find(PARAM_KEY_META_TYPE) != discoverParam.end()) {
157 MetaNodeType metaType = (MetaNodeType)(std::atoi((discoverParam.find(PARAM_KEY_META_TYPE)->second).c_str()));
158 isStandardMetaNode = (metaType == MetaNodeType::PROXY_TRANSMISION);
159 }
160
161 softbusListener_->RegisterSoftbusLnnOpsCbk(pkgName, shared_from_this());
162 StartDiscoveryTimer(pkgName);
163
164 auto it = filterOptions.find(PARAM_KEY_FILTER_OPTIONS);
165 nlohmann::json jsonObject = nlohmann::json::parse(it->second, nullptr, false);
166 if (!jsonObject.is_discarded() && jsonObject.contains(TYPE_MINE)) {
167 return StartDiscovering4MineLibary(pkgName, dmSubInfo, it->second);
168 }
169
170 int32_t ret = isStandardMetaNode ? StartDiscoveringNoMetaType(pkgName, dmSubInfo, discoverParam) :
171 StartDiscovering4MetaType(pkgName, dmSubInfo, discoverParam);
172 if (ret != DM_OK) {
173 LOGE("StartDiscovering for meta node process failed, ret = %{public}d", ret);
174 return ret;
175 }
176 return ret;
177 }
178
ConfigDiscParam(const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo *dmSubInfo)179 void DiscoveryManager::ConfigDiscParam(const std::map<std::string, std::string> &discoverParam,
180 DmSubscribeInfo *dmSubInfo)
181 {
182 LOGI("DiscoveryManager::ConfigDiscParam");
183 if (dmSubInfo == nullptr) {
184 LOGE("ConfigDiscParam failed, dmSubInfo is nullptr.");
185 return;
186 }
187 dmSubInfo->subscribeId = DM_INVALID_FLAG_ID;
188 dmSubInfo->mode = DmDiscoverMode::DM_DISCOVER_MODE_ACTIVE;
189 dmSubInfo->medium = DmExchangeMedium::DM_AUTO;
190 dmSubInfo->freq = DmExchangeFreq::DM_LOW;
191 dmSubInfo->isSameAccount = false;
192 dmSubInfo->isWakeRemote = false;
193 if (discoverParam.find(PARAM_KEY_SUBSCRIBE_ID) != discoverParam.end()) {
194 dmSubInfo->subscribeId = std::atoi((discoverParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str());
195 }
196 if (discoverParam.find(PARAM_KEY_DISC_MEDIUM) != discoverParam.end()) {
197 int32_t medium = std::atoi((discoverParam.find(PARAM_KEY_DISC_MEDIUM)->second).c_str());
198 dmSubInfo->medium = static_cast<DmExchangeMedium>(medium);
199 }
200 if (discoverParam.find(PARAM_KEY_DISC_FREQ) != discoverParam.end()) {
201 int32_t freq = std::atoi((discoverParam.find(PARAM_KEY_DISC_FREQ)->second).c_str());
202 dmSubInfo->freq = static_cast<DmExchangeFreq>(freq);
203 }
204 if (discoverParam.find(PARAM_KEY_DISC_MODE) != discoverParam.end()) {
205 dmSubInfo->mode =
206 static_cast<DmDiscoverMode>(std::atoi((discoverParam.find(PARAM_KEY_DISC_MODE)->second).c_str()));
207 }
208 }
209
StartDiscovering4MineLibary(const std::string &pkgName, DmSubscribeInfo &dmSubInfo, const std::string &searchJson)210 int32_t DiscoveryManager::StartDiscovering4MineLibary(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
211 const std::string &searchJson)
212 {
213 if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_OSD) != EOK) {
214 LOGE("capability copy err.");
215 return ERR_DM_START_DISCOVERING_FAILED;
216 }
217 LOGI("StartDiscovering for mine meta node process, pkgName = %{public}s, capability = %{public}s",
218 pkgName.c_str(), std::string(dmSubInfo.capability).c_str());
219 {
220 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
221 capabilityMap_[pkgName] = std::string(dmSubInfo.capability);
222 }
223 int32_t ret = mineSoftbusListener_->RefreshSoftbusLNN(pkgName, searchJson, dmSubInfo);
224 if (ret != DM_OK) {
225 LOGE("StartDiscovering for meta node process failed, ret = %{public}d", ret);
226 return ret;
227 }
228 return ret;
229 }
230
StartDiscoveringNoMetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo, const std::map<std::string, std::string> ¶m)231 int32_t DiscoveryManager::StartDiscoveringNoMetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
232 const std::map<std::string, std::string> ¶m)
233 {
234 (void)param;
235 if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_OSD) != EOK) {
236 LOGE("capability copy err.");
237 return ERR_DM_START_DISCOVERING_FAILED;
238 }
239 LOGI("StartDiscovering for standard meta node process, pkgName = %{public}s, capability = %{public}s",
240 pkgName.c_str(), std::string(dmSubInfo.capability).c_str());
241
242 {
243 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
244 capabilityMap_[pkgName] = std::string(dmSubInfo.capability);
245 }
246 int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, LNN_DISC_CAPABILITY);
247 if (ret != DM_OK) {
248 LOGE("StartDiscoveringNoMetaType failed, softbus refresh lnn ret: %{public}d.", ret);
249 }
250 return ret;
251 }
252
StartDiscovering4MetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo, const std::map<std::string, std::string> ¶m)253 int32_t DiscoveryManager::StartDiscovering4MetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
254 const std::map<std::string, std::string> ¶m)
255 {
256 LOGI("StartDiscovering for meta node process, input metaType = %{public}s, pkgName = %{public}s",
257 (param.find(PARAM_KEY_META_TYPE)->second).c_str(), pkgName.c_str());
258 MetaNodeType metaType = (MetaNodeType)(std::atoi((param.find(PARAM_KEY_META_TYPE)->second).c_str()));
259 switch (metaType) {
260 case MetaNodeType::PROXY_SHARE:
261 LOGI("StartDiscovering4MetaType for share meta node process.");
262 if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_SHARE) != EOK) {
263 LOGE("capability copy error.");
264 return ERR_DM_FAILED;
265 }
266 break;
267 case MetaNodeType::PROXY_WEAR:
268 LOGI("StartDiscovering4MetaType for wear meta node process.");
269 if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_WEAR) != EOK) {
270 LOGE("capability copy error.");
271 return ERR_DM_FAILED;
272 }
273 break;
274 case MetaNodeType::PROXY_CASTPLUS:
275 LOGI("StartDiscovering4MetaType for cast_plus meta node process.");
276 if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_CASTPLUS) != EOK) {
277 LOGE("capability copy error.");
278 return ERR_DM_FAILED;
279 }
280 break;
281 default:
282 LOGE("StartDiscovering4MetaType failed, unsupport meta type : %{public}d.", metaType);
283 return ERR_DM_UNSUPPORTED_METHOD;
284 }
285
286 std::string customData = "";
287 if (param.find(PARAM_KEY_CUSTOM_DATA) != param.end()) {
288 customData = param.find(PARAM_KEY_CUSTOM_DATA)->second;
289 }
290 LOGI("StartDiscovering4MetaType capability = %{public}s,", std::string(dmSubInfo.capability).c_str());
291 {
292 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
293 capabilityMap_[pkgName] =std::string(dmSubInfo.capability);
294 }
295
296 int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, customData);
297 if (ret != DM_OK) {
298 LOGE("StartDiscovering4MetaType failed, softbus refresh lnn ret: %{public}d.", ret);
299 }
300 return ret;
301 }
302
StopDiscovering(const std::string &pkgName, uint16_t subscribeId)303 int32_t DiscoveryManager::StopDiscovering(const std::string &pkgName, uint16_t subscribeId)
304 {
305 LOGI("DiscoveryManager::StopDiscovering begin for pkgName = %{public}s.", pkgName.c_str());
306 if (pkgName.empty()) {
307 LOGE("Invalid parameter, pkgName is empty.");
308 return ERR_DM_INPUT_PARA_INVALID;
309 }
310 {
311 std::lock_guard<std::mutex> autoLock(locks_);
312 if (pkgNameSet_.find(pkgName) != pkgNameSet_.end()) {
313 pkgNameSet_.erase(pkgName);
314 }
315
316 if (discoveryContextMap_.find(pkgName) != discoveryContextMap_.end()) {
317 discoveryContextMap_.erase(pkgName);
318 timer_->DeleteTimer(pkgName);
319 }
320 }
321 {
322 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
323 if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
324 capabilityMap_.erase(pkgName);
325 }
326 }
327 softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgName);
328 #if (defined(MINE_HARMONY))
329 return mineSoftbusListener_->StopRefreshSoftbusLNN(subscribeId);
330 #else
331 return softbusListener_->StopRefreshSoftbusLNN(subscribeId);
332 #endif
333 }
334
OnDeviceFound(const std::string &pkgName, const DmDeviceInfo &info, bool isOnline)335 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const DmDeviceInfo &info, bool isOnline)
336 {
337 DeviceFilterPara filterPara;
338 filterPara.isOnline = false;
339 filterPara.range = info.range;
340 filterPara.deviceType = info.deviceTypeId;
341 std::string deviceIdHash = static_cast<std::string>(info.deviceId);
342 if (isOnline && GetDeviceAclParam(pkgName, deviceIdHash, filterPara.isOnline, filterPara.authForm) != DM_OK) {
343 LOGE("The found device get online param failed.");
344 }
345 nlohmann::json jsonObject = nlohmann::json::parse(info.extraData, nullptr, false);
346 if (jsonObject.is_discarded()) {
347 LOGE("OnDeviceFound jsonStr error");
348 return;
349 }
350 if (!IsUint32(jsonObject, PARAM_KEY_DISC_CAPABILITY)) {
351 LOGE("err json string: %{public}s", PARAM_KEY_DISC_CAPABILITY);
352 return;
353 }
354 uint32_t capabilityType = jsonObject[PARAM_KEY_DISC_CAPABILITY].get<uint32_t>();
355 OnDeviceFound(pkgName, capabilityType, info, filterPara);
356 }
357
OnDeviceFound(const std::string &pkgName, const uint32_t capabilityType, const DmDeviceInfo &info, const DeviceFilterPara &filterPara)358 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const uint32_t capabilityType,
359 const DmDeviceInfo &info, const DeviceFilterPara &filterPara)
360 {
361 bool isIndiscoveryContextMap = false;
362 DiscoveryContext discoveryContext;
363 {
364 std::lock_guard<std::mutex> autoLock(locks_);
365 auto iter = discoveryContextMap_.find(pkgName);
366 isIndiscoveryContextMap = (iter != discoveryContextMap_.end());
367 if (isIndiscoveryContextMap) {
368 discoveryContext = iter->second;
369 }
370 }
371 if (!isIndiscoveryContextMap) {
372 {
373 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
374 if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
375 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
376 return;
377 }
378 }
379 uint16_t subscribeId = 0;
380 {
381 std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
382 subscribeId = pkgName2SubIdMap_[pkgName];
383 }
384 LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
385 listener_->OnDeviceFound(pkgName, subscribeId, info);
386 return;
387 }
388 DiscoveryFilter filter;
389 if (filter.IsValidDevice(discoveryContext.filterOp, discoveryContext.filters, filterPara)) {
390 {
391 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
392 if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
393 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
394 return;
395 }
396 }
397 LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
398 listener_->OnDeviceFound(pkgName, discoveryContext.subscribeId, info);
399 }
400 }
401
CompareCapability(uint32_t capabilityType, const std::string &capabilityStr)402 bool DiscoveryManager::CompareCapability(uint32_t capabilityType, const std::string &capabilityStr)
403 {
404 for (uint32_t i = 0; i < sizeof(g_capabilityMap) / sizeof(g_capabilityMap[0]); i++) {
405 if (strcmp(capabilityStr.c_str(), g_capabilityMap[i].capability) == 0) {
406 LOGD("capabilityType: %{public}d, capabilityStr: %{public}s", capabilityType, capabilityStr.c_str());
407 return ((capabilityType >> static_cast<uint32_t>(g_capabilityMap[i].bitmap)) & 1);
408 }
409 }
410 return false;
411 }
412
OnDiscoveringResult(const std::string &pkgName, int32_t subscribeId, int32_t result)413 void DiscoveryManager::OnDiscoveringResult(const std::string &pkgName, int32_t subscribeId, int32_t result)
414 {
415 LOGI("DiscoveryManager::OnDiscoveringResult, subscribeId = %{public}d, result = %{public}d.", subscribeId, result);
416 if (pkgName.empty() || (listener_ == nullptr)) {
417 LOGE("DiscoveryManager::OnDiscoveringResult failed, IDeviceManagerServiceListener is null.");
418 return;
419 }
420 if (result == 0) {
421 std::lock_guard<std::mutex> autoLock(locks_);
422 discoveryContextMap_[pkgName].subscribeId = (uint32_t)subscribeId;
423 listener_->OnDiscoverySuccess(pkgName, subscribeId);
424 return;
425 }
426 {
427 std::lock_guard<std::mutex> autoLock(locks_);
428 if (pkgNameSet_.find(pkgName) != pkgNameSet_.end()) {
429 pkgNameSet_.erase(pkgName);
430 }
431 if (discoveryContextMap_.find(pkgName) != discoveryContextMap_.end()) {
432 discoveryContextMap_.erase(pkgName);
433 timer_->DeleteTimer(pkgName);
434 }
435 }
436 {
437 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
438 if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
439 capabilityMap_.erase(pkgName);
440 }
441 }
442 listener_->OnDiscoveryFailed(pkgName, (uint32_t)subscribeId, result);
443 softbusListener_->StopRefreshSoftbusLNN(subscribeId);
444 }
445
StartDiscoveryTimer(const std::string &pkgName)446 void DiscoveryManager::StartDiscoveryTimer(const std::string &pkgName)
447 {
448 if (timer_ == nullptr) {
449 timer_ = std::make_shared<DmTimer>();
450 }
451 timer_->StartTimer(pkgName, DISCOVERY_TIMEOUT,
452 [this] (std::string name) {
453 DiscoveryManager::HandleDiscoveryTimeout(name);
454 });
455 }
456
HandleDiscoveryQueue(const std::string &pkgName, uint16_t subscribeId, const std::map<std::string, std::string> &filterOps)457 int32_t DiscoveryManager::HandleDiscoveryQueue(const std::string &pkgName, uint16_t subscribeId,
458 const std::map<std::string, std::string> &filterOps)
459 {
460 std::string filterData = "";
461 if (filterOps.find(PARAM_KEY_FILTER_OPTIONS) != filterOps.end()) {
462 filterData = filterOps.find(PARAM_KEY_FILTER_OPTIONS)->second;
463 }
464 DeviceFilterOption dmFilter;
465 if ((dmFilter.TransformToFilter(filterData) != DM_OK) && (dmFilter.TransformFilterOption(filterData) != DM_OK)) {
466 return ERR_DM_INPUT_PARA_INVALID;
467 }
468 {
469 std::lock_guard<std::mutex> autoLock(locks_);
470 if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
471 pkgNameSet_.emplace(pkgName);
472 DiscoveryContext context = {pkgName, filterData, subscribeId, dmFilter.filterOp_, dmFilter.filters_};
473 discoveryContextMap_.emplace(pkgName, context);
474 return DM_OK;
475 } else {
476 LOGE("DiscoveryManager::HandleDiscoveryQueue repeated, pkgName : %{public}s.", pkgName.c_str());
477 return ERR_DM_DISCOVERY_REPEATED;
478 }
479 }
480 }
481
HandleDiscoveryTimeout(const std::string &pkgName)482 void DiscoveryManager::HandleDiscoveryTimeout(const std::string &pkgName)
483 {
484 LOGI("DiscoveryManager::HandleDiscoveryTimeout");
485 uint16_t subscribeId = 0;
486 {
487 std::lock_guard<std::mutex> autoLock(locks_);
488 if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
489 LOGE("HandleDiscoveryTimeout: pkgName: %{public}s is not exist.", pkgName.c_str());
490 return;
491 }
492 auto iter = discoveryContextMap_.find(pkgName);
493 if (iter == discoveryContextMap_.end()) {
494 LOGE("HandleDiscoveryTimeout: subscribeId not found by pkgName %{public}s.",
495 GetAnonyString(pkgName).c_str());
496 return;
497 }
498 subscribeId = discoveryContextMap_[pkgName].subscribeId;
499 }
500 StopDiscovering(pkgName, subscribeId);
501 }
502
UpdateInfoFreq( const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo &dmSubInfo)503 void DiscoveryManager::UpdateInfoFreq(
504 const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo &dmSubInfo)
505 {
506 if (auto it = discoverParam.find(PARAM_KEY_DISC_FREQ); it != discoverParam.end()) {
507 int32_t freq = StringToInt(it->second, DECIMALISM);
508 if (freq < DmExchangeFreq::DM_LOW || freq > DmExchangeFreq::DM_FREQ_BUTT) {
509 LOGE("Invalid freq value.");
510 return;
511 }
512 dmSubInfo.freq = static_cast<DmExchangeFreq>(freq);
513 }
514 }
515
GetDeviceAclParam(const std::string &pkgName, std::string deviceId, bool &isOnline, int32_t &authForm)516 int32_t DiscoveryManager::GetDeviceAclParam(const std::string &pkgName, std::string deviceId,
517 bool &isOnline, int32_t &authForm)
518 {
519 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
520 char localDeviceId[DEVICE_UUID_LENGTH];
521 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
522 std::string requestDeviceId = static_cast<std::string>(localDeviceId);
523 DmDiscoveryInfo discoveryInfo;
524 discoveryInfo.pkgname = pkgName;
525 discoveryInfo.localDeviceId = requestDeviceId;
526 discoveryInfo.remoteDeviceIdHash = deviceId;
527 if (DiscoveryManager::IsCommonDependencyReady() && DiscoveryManager::GetCommonDependencyObj() != nullptr) {
528 if (DiscoveryManager::GetCommonDependencyObj()->GetDeviceAclParam(discoveryInfo, isOnline, authForm) != DM_OK) {
529 LOGE("GetDeviceAclParam failed.");
530 return ERR_DM_FAILED;
531 }
532 }
533 #endif
534 return DM_OK;
535 }
536
537 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
GetCommonDependencyObj()538 IDeviceProfileConnector* DiscoveryManager::GetCommonDependencyObj()
539 {
540 return dpConnector_;
541 }
542
IsCommonDependencyReady()543 bool DiscoveryManager::IsCommonDependencyReady()
544 {
545 std::lock_guard<std::mutex> lock(comDependencyLoadLock);
546 if (isSoLoaded_ && dpConnector_ != nullptr && dpConnectorHandle_ != nullptr) {
547 return true;
548 }
549 dpConnectorHandle_ = dlopen(LIB_DM_COMDENPENDENCY_NAME, RTLD_NOW | RTLD_NODELETE);
550 if (dpConnectorHandle_ == nullptr) {
551 LOGE("load libdevicemanagerdependency so failed, errMsg: %{public}s.", dlerror());
552 return false;
553 }
554 dlerror();
555 auto func = (CreateDpConnectorFuncPtr)dlsym(dpConnectorHandle_, "CreateDpConnectorInstance");
556 if (dlerror() != nullptr || func == nullptr) {
557 dlclose(dpConnectorHandle_);
558 LOGE("Create object function is not exist.");
559 return false;
560 }
561 dpConnector_ = func();
562 isSoLoaded_ = true;
563 LOGI("IsCommonDependencyReady success.");
564 return true;
565 }
566
CloseCommonDependencyObj()567 bool DiscoveryManager::CloseCommonDependencyObj()
568 {
569 LOGI("DiscoveryManager::CloseCommonDependencyObj start.");
570 std::lock_guard<std::mutex> lock(comDependencyLoadLock);
571 if (!isSoLoaded_ && (dpConnector_ == nullptr) && (dpConnectorHandle_ == nullptr)) {
572 return true;
573 }
574
575 int32_t ret = dlclose(dpConnectorHandle_);
576 if (ret != 0) {
577 LOGE("close libdevicemanagerdependency failed ret = %{public}d.", ret);
578 return false;
579 }
580 isSoLoaded_ = false;
581 dpConnector_ = nullptr;
582 dpConnectorHandle_ = nullptr;
583 LOGI("close libdevicemanagerdependency so success.");
584 return true;
585 }
586 #endif
587
ClearDiscoveryCache(const std::string &pkgName)588 void DiscoveryManager::ClearDiscoveryCache(const std::string &pkgName)
589 {
590 LOGI("PkgName %{public}s.", pkgName.c_str());
591 uint16_t subscribeId = 0;
592 {
593 std::lock_guard<std::mutex> autoLock(locks_);
594 if (pkgNameSet_.find(pkgName) != pkgNameSet_.end()) {
595 LOGI("Erase pkgname %{public}s from pkgNameSet.", pkgName.c_str());
596 pkgNameSet_.erase(pkgName);
597 }
598 if (discoveryContextMap_.find(pkgName) != discoveryContextMap_.end()) {
599 LOGI("Erase pkgname %{public}s from pkgNameSet.", pkgName.c_str());
600 subscribeId = discoveryContextMap_[pkgName].subscribeId;
601 discoveryContextMap_.erase(pkgName);
602 }
603 }
604 {
605 std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
606 if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
607 capabilityMap_.erase(pkgName);
608 }
609 }
610 {
611 std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
612 if (pkgName2SubIdMap_.find(pkgName) != pkgName2SubIdMap_.end()) {
613 pkgName2SubIdMap_.erase(pkgName);
614 }
615 }
616 CHECK_NULL_VOID(softbusListener_);
617 softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgName);
618 softbusListener_->StopRefreshSoftbusLNN(subscribeId);
619 CHECK_NULL_VOID(timer_);
620 timer_->DeleteTimer(pkgName);
621 }
622 } // namespace DistributedHardware
623 } // namespace OHOS
624