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             if (timer_ != nullptr) {
319                 timer_->DeleteTimer(pkgName);
320             }
321         }
322     }
323     {
324         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
325         if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
326             capabilityMap_.erase(pkgName);
327         }
328     }
329     softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgName);
330 #if (defined(MINE_HARMONY))
331     return mineSoftbusListener_->StopRefreshSoftbusLNN(subscribeId);
332 #else
333     return softbusListener_->StopRefreshSoftbusLNN(subscribeId);
334 #endif
335 }
336 
OnDeviceFound(const std::string & pkgName,const DmDeviceInfo & info,bool isOnline)337 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const DmDeviceInfo &info, bool isOnline)
338 {
339     DeviceFilterPara filterPara;
340     filterPara.isOnline = false;
341     filterPara.range = info.range;
342     filterPara.deviceType = info.deviceTypeId;
343     std::string deviceIdHash = static_cast<std::string>(info.deviceId);
344     if (isOnline && GetDeviceAclParam(pkgName, deviceIdHash, filterPara.isOnline, filterPara.authForm) != DM_OK) {
345         LOGE("The found device get online param failed.");
346     }
347     nlohmann::json jsonObject = nlohmann::json::parse(info.extraData, nullptr, false);
348     if (jsonObject.is_discarded()) {
349         LOGE("OnDeviceFound jsonStr error");
350         return;
351     }
352     if (!IsUint32(jsonObject, PARAM_KEY_DISC_CAPABILITY)) {
353         LOGE("err json string: %{public}s", PARAM_KEY_DISC_CAPABILITY);
354         return;
355     }
356     uint32_t capabilityType = jsonObject[PARAM_KEY_DISC_CAPABILITY].get<uint32_t>();
357     OnDeviceFound(pkgName, capabilityType, info, filterPara);
358 }
359 
OnDeviceFound(const std::string & pkgName,const uint32_t capabilityType,const DmDeviceInfo & info,const DeviceFilterPara & filterPara)360 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const uint32_t capabilityType,
361     const DmDeviceInfo &info, const DeviceFilterPara &filterPara)
362 {
363     bool isIndiscoveryContextMap = false;
364     DiscoveryContext discoveryContext;
365     {
366         std::lock_guard<std::mutex> autoLock(locks_);
367         auto iter = discoveryContextMap_.find(pkgName);
368         isIndiscoveryContextMap = (iter != discoveryContextMap_.end());
369         if (isIndiscoveryContextMap) {
370             discoveryContext = iter->second;
371         }
372     }
373     if (!isIndiscoveryContextMap) {
374         {
375             std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
376             if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
377                 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
378                 return;
379             }
380         }
381         uint16_t subscribeId = 0;
382         {
383             std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
384             subscribeId = pkgName2SubIdMap_[pkgName];
385         }
386         LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
387         listener_->OnDeviceFound(pkgName, subscribeId, info);
388         return;
389     }
390     DiscoveryFilter filter;
391     if (filter.IsValidDevice(discoveryContext.filterOp, discoveryContext.filters, filterPara)) {
392         {
393             std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
394             if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
395                 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
396                 return;
397             }
398         }
399         LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
400         listener_->OnDeviceFound(pkgName, discoveryContext.subscribeId, info);
401     }
402 }
403 
CompareCapability(uint32_t capabilityType,const std::string & capabilityStr)404 bool DiscoveryManager::CompareCapability(uint32_t capabilityType, const std::string &capabilityStr)
405 {
406     for (uint32_t i = 0; i < sizeof(g_capabilityMap) / sizeof(g_capabilityMap[0]); i++) {
407         if (strcmp(capabilityStr.c_str(), g_capabilityMap[i].capability) == 0) {
408             LOGD("capabilityType: %{public}d, capabilityStr: %{public}s", capabilityType, capabilityStr.c_str());
409             return ((capabilityType >> static_cast<uint32_t>(g_capabilityMap[i].bitmap)) & 1);
410         }
411     }
412     return false;
413 }
414 
OnDiscoveringResult(const std::string & pkgName,int32_t subscribeId,int32_t result)415 void DiscoveryManager::OnDiscoveringResult(const std::string &pkgName, int32_t subscribeId, int32_t result)
416 {
417     LOGI("DiscoveryManager::OnDiscoveringResult, subscribeId = %{public}d, result = %{public}d.", subscribeId, result);
418     if (pkgName.empty() || (listener_ == nullptr)) {
419         LOGE("DiscoveryManager::OnDiscoveringResult failed, IDeviceManagerServiceListener is null.");
420         return;
421     }
422     if (result == 0) {
423         std::lock_guard<std::mutex> autoLock(locks_);
424         discoveryContextMap_[pkgName].subscribeId = (uint32_t)subscribeId;
425         listener_->OnDiscoverySuccess(pkgName, subscribeId);
426         return;
427     }
428     {
429         std::lock_guard<std::mutex> autoLock(locks_);
430         if (pkgNameSet_.find(pkgName) != pkgNameSet_.end()) {
431             pkgNameSet_.erase(pkgName);
432         }
433         if (discoveryContextMap_.find(pkgName) != discoveryContextMap_.end()) {
434             discoveryContextMap_.erase(pkgName);
435             if (timer_ != nullptr) {
436                 timer_->DeleteTimer(pkgName);
437             }
438         }
439     }
440     {
441         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
442         if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
443             capabilityMap_.erase(pkgName);
444         }
445     }
446     listener_->OnDiscoveryFailed(pkgName, (uint32_t)subscribeId, result);
447     softbusListener_->StopRefreshSoftbusLNN(subscribeId);
448 }
449 
StartDiscoveryTimer(const std::string & pkgName)450 void DiscoveryManager::StartDiscoveryTimer(const std::string &pkgName)
451 {
452     if (timer_ == nullptr) {
453         timer_ = std::make_shared<DmTimer>();
454     }
455     timer_->StartTimer(pkgName, DISCOVERY_TIMEOUT,
456         [this] (std::string name) {
457             DiscoveryManager::HandleDiscoveryTimeout(name);
458         });
459 }
460 
HandleDiscoveryQueue(const std::string & pkgName,uint16_t subscribeId,const std::map<std::string,std::string> & filterOps)461 int32_t DiscoveryManager::HandleDiscoveryQueue(const std::string &pkgName, uint16_t subscribeId,
462     const std::map<std::string, std::string> &filterOps)
463 {
464     std::string filterData = "";
465     if (filterOps.find(PARAM_KEY_FILTER_OPTIONS) != filterOps.end()) {
466         filterData = filterOps.find(PARAM_KEY_FILTER_OPTIONS)->second;
467     }
468     DeviceFilterOption dmFilter;
469     if ((dmFilter.TransformToFilter(filterData) != DM_OK) && (dmFilter.TransformFilterOption(filterData) != DM_OK)) {
470         return ERR_DM_INPUT_PARA_INVALID;
471     }
472     {
473         std::lock_guard<std::mutex> autoLock(locks_);
474         if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
475             pkgNameSet_.emplace(pkgName);
476             DiscoveryContext context = {pkgName, filterData, subscribeId, dmFilter.filterOp_, dmFilter.filters_};
477             discoveryContextMap_.emplace(pkgName, context);
478             return DM_OK;
479         } else {
480             LOGE("DiscoveryManager::HandleDiscoveryQueue repeated, pkgName : %{public}s.", pkgName.c_str());
481             return ERR_DM_DISCOVERY_REPEATED;
482         }
483     }
484 }
485 
HandleDiscoveryTimeout(const std::string & pkgName)486 void DiscoveryManager::HandleDiscoveryTimeout(const std::string &pkgName)
487 {
488     LOGI("DiscoveryManager::HandleDiscoveryTimeout");
489     uint16_t subscribeId = 0;
490     {
491         std::lock_guard<std::mutex> autoLock(locks_);
492         if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
493             LOGE("HandleDiscoveryTimeout: pkgName: %{public}s is not exist.", pkgName.c_str());
494             return;
495         }
496         auto iter = discoveryContextMap_.find(pkgName);
497         if (iter == discoveryContextMap_.end()) {
498             LOGE("HandleDiscoveryTimeout: subscribeId not found by pkgName %{public}s.",
499                 GetAnonyString(pkgName).c_str());
500             return;
501         }
502         subscribeId = discoveryContextMap_[pkgName].subscribeId;
503     }
504     StopDiscovering(pkgName, subscribeId);
505 }
506 
UpdateInfoFreq(const std::map<std::string,std::string> & discoverParam,DmSubscribeInfo & dmSubInfo)507 void DiscoveryManager::UpdateInfoFreq(
508     const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo &dmSubInfo)
509 {
510     if (auto it = discoverParam.find(PARAM_KEY_DISC_FREQ); it != discoverParam.end()) {
511         int32_t freq = StringToInt(it->second, DECIMALISM);
512         if (freq < DmExchangeFreq::DM_LOW || freq > DmExchangeFreq::DM_FREQ_BUTT) {
513             LOGE("Invalid freq value.");
514             return;
515         }
516         dmSubInfo.freq = static_cast<DmExchangeFreq>(freq);
517     }
518 }
519 
GetDeviceAclParam(const std::string & pkgName,std::string deviceId,bool & isOnline,int32_t & authForm)520 int32_t DiscoveryManager::GetDeviceAclParam(const std::string &pkgName, std::string deviceId,
521     bool &isOnline, int32_t &authForm)
522 {
523 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
524     char localDeviceId[DEVICE_UUID_LENGTH];
525     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
526     std::string requestDeviceId = static_cast<std::string>(localDeviceId);
527     DmDiscoveryInfo discoveryInfo;
528     discoveryInfo.pkgname = pkgName;
529     discoveryInfo.localDeviceId = requestDeviceId;
530     discoveryInfo.remoteDeviceIdHash = deviceId;
531     if (DiscoveryManager::IsCommonDependencyReady() && DiscoveryManager::GetCommonDependencyObj() != nullptr) {
532         if (DiscoveryManager::GetCommonDependencyObj()->GetDeviceAclParam(discoveryInfo, isOnline, authForm) != DM_OK) {
533             LOGE("GetDeviceAclParam failed.");
534             return ERR_DM_FAILED;
535         }
536     }
537 #endif
538     return DM_OK;
539 }
540 
541 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
GetCommonDependencyObj()542 IDeviceProfileConnector* DiscoveryManager::GetCommonDependencyObj()
543 {
544     return dpConnector_;
545 }
546 
IsCommonDependencyReady()547 bool DiscoveryManager::IsCommonDependencyReady()
548 {
549     std::lock_guard<std::mutex> lock(comDependencyLoadLock);
550     if (isSoLoaded_ && dpConnector_ != nullptr && dpConnectorHandle_ != nullptr) {
551         return true;
552     }
553     dpConnectorHandle_ = dlopen(LIB_DM_COMDENPENDENCY_NAME, RTLD_NOW | RTLD_NODELETE);
554     if (dpConnectorHandle_ == nullptr) {
555         LOGE("load libdevicemanagerdependency so failed, errMsg: %{public}s.", dlerror());
556         return false;
557     }
558     dlerror();
559     auto func = (CreateDpConnectorFuncPtr)dlsym(dpConnectorHandle_, "CreateDpConnectorInstance");
560     if (dlerror() != nullptr || func == nullptr) {
561         dlclose(dpConnectorHandle_);
562         LOGE("Create object function is not exist.");
563         return false;
564     }
565     dpConnector_ = func();
566     isSoLoaded_ = true;
567     LOGI("IsCommonDependencyReady success.");
568     return true;
569 }
570 
CloseCommonDependencyObj()571 bool DiscoveryManager::CloseCommonDependencyObj()
572 {
573     LOGI("DiscoveryManager::CloseCommonDependencyObj start.");
574     std::lock_guard<std::mutex> lock(comDependencyLoadLock);
575     if (!isSoLoaded_ && (dpConnector_ == nullptr) && (dpConnectorHandle_ == nullptr)) {
576         return true;
577     }
578 
579     int32_t ret = dlclose(dpConnectorHandle_);
580     if (ret != 0) {
581         LOGE("close libdevicemanagerdependency failed ret = %{public}d.", ret);
582         return false;
583     }
584     isSoLoaded_ = false;
585     dpConnector_ = nullptr;
586     dpConnectorHandle_ = nullptr;
587     LOGI("close libdevicemanagerdependency so success.");
588     return true;
589 }
590 #endif
591 } // namespace DistributedHardware
592 } // namespace OHOS
593