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> &param)231 int32_t DiscoveryManager::StartDiscoveringNoMetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
232     const std::map<std::string, std::string> &param)
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> &param)253 int32_t DiscoveryManager::StartDiscovering4MetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
254     const std::map<std::string, std::string> &param)
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