• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "softbus_common.h"
20 
21 #include "dm_anonymous.h"
22 #include "dm_constants.h"
23 #include "dm_random.h"
24 #include "parameter.h"
25 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
26 #include "multiple_user_connector.h"
27 #endif
28 
29 namespace OHOS {
30 namespace DistributedHardware {
31 const int32_t DISCOVERY_TIMEOUT = 120;
32 const uint16_t DM_INVALID_FLAG_ID = 0;
33 constexpr const char* LNN_DISC_CAPABILITY = "capability";
34 const std::string TYPE_MINE = "findDeviceMode";
35 const int32_t DECIMALISM = 10;
36 
37 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
38 static std::mutex comDependencyLoadLock;
39 constexpr const char* LIB_DM_COMDENPENDENCY_NAME = "libdevicemanagerdependency.z.so";
40 bool DiscoveryManager::isSoLoaded_ = false;
41 IDeviceProfileConnector* DiscoveryManager::dpConnector_ = nullptr;
42 void* DiscoveryManager::dpConnectorHandle_ = nullptr;
43 #endif
44 
DiscoveryManager(std::shared_ptr<SoftbusListener> softbusListener,std::shared_ptr<IDeviceManagerServiceListener> listener)45 DiscoveryManager::DiscoveryManager(std::shared_ptr<SoftbusListener> softbusListener,
46     std::shared_ptr<IDeviceManagerServiceListener> listener) : softbusListener_(softbusListener), listener_(listener)
47 {
48     LOGI("DiscoveryManager constructor.");
49 }
50 
~DiscoveryManager()51 DiscoveryManager::~DiscoveryManager()
52 {
53 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
54     CloseCommonDependencyObj();
55 #endif
56     LOGI("DiscoveryManager destructor.");
57 }
58 
EnableDiscoveryListener(const std::string & pkgName,const std::map<std::string,std::string> & discoverParam,const std::map<std::string,std::string> & filterOptions)59 int32_t DiscoveryManager::EnableDiscoveryListener(const std::string &pkgName,
60     const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)
61 {
62     if (pkgName.empty()) {
63         LOGE("Invalid parameter, pkgName is empty.");
64         return ERR_DM_INPUT_PARA_INVALID;
65     }
66     LOGI("begin for pkgName = %{public}s.", pkgName.c_str());
67     std::string pkgNameTemp = AddMultiUserIdentify(pkgName);
68     DmSubscribeInfo dmSubInfo;
69     dmSubInfo.subscribeId = DM_INVALID_FLAG_ID;
70     dmSubInfo.mode = DmDiscoverMode::DM_DISCOVER_MODE_PASSIVE;
71     dmSubInfo.freq = DmExchangeFreq::DM_LOW;
72     dmSubInfo.isSameAccount = false;
73     dmSubInfo.isWakeRemote = false;
74     if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_APPROACH) != EOK) {
75         LOGE("capability copy err.");
76         return ERR_DM_ENABLE_DISCOVERY_LISTENER_FAILED;
77     }
78     UpdateInfoFreq(discoverParam, dmSubInfo);
79     if (discoverParam.find(PARAM_KEY_META_TYPE) != discoverParam.end()) {
80         std::string metaType = discoverParam.find(PARAM_KEY_META_TYPE)->second;
81         LOGI("input MetaType = %{public}s.", metaType.c_str());
82     }
83     if (discoverParam.find(PARAM_KEY_SUBSCRIBE_ID) != discoverParam.end() &&
84         IsNumberString((discoverParam.find(PARAM_KEY_SUBSCRIBE_ID)->second))) {
85             uint16_t externalSubId =
86                 static_cast<uint16_t>(std::atoi((discoverParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str()));
87             dmSubInfo.subscribeId = GenInnerSubId(pkgNameTemp, externalSubId);
88     }
89     if (discoverParam.find(PARAM_KEY_DISC_CAPABILITY) != discoverParam.end()) {
90         std::string capability = discoverParam.find(PARAM_KEY_DISC_CAPABILITY)->second;
91         if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, capability.c_str()) != EOK) {
92             LOGE("failed, capability copy err.");
93             return ERR_DM_ENABLE_DISCOVERY_LISTENER_FAILED;
94         }
95     }
96     LOGI("capability = %{public}s,", std::string(dmSubInfo.capability).c_str());
97     {
98         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
99         capabilityMap_[pkgNameTemp] = std::string(dmSubInfo.capability);
100     }
101     UpdateInfoMedium(discoverParam, dmSubInfo);
102     int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, LNN_DISC_CAPABILITY);
103     if (ret != DM_OK) {
104         LOGE("failed, softbus refresh lnn ret: %{public}d.", ret);
105         return ret;
106     }
107     softbusListener_->RegisterSoftbusLnnOpsCbk(pkgNameTemp, shared_from_this());
108     return DM_OK;
109 }
110 
DisableDiscoveryListener(const std::string & pkgName,const std::map<std::string,std::string> & extraParam)111 int32_t DiscoveryManager::DisableDiscoveryListener(const std::string &pkgName,
112     const std::map<std::string, std::string> &extraParam)
113 {
114     if (pkgName.empty()) {
115         LOGE("Invalid parameter, pkgName is empty.");
116         return ERR_DM_INPUT_PARA_INVALID;
117     }
118     LOGI("begin for pkgName = %{public}s.", pkgName.c_str());
119     std::string pkgNameTemp = RemoveMultiUserIdentify(pkgName);
120     if (extraParam.find(PARAM_KEY_META_TYPE) != extraParam.end()) {
121         LOGI("DisableDiscoveryListener, input MetaType = %{public}s",
122             (extraParam.find(PARAM_KEY_META_TYPE)->second).c_str());
123     }
124     uint16_t innerSubId = DM_INVALID_FLAG_ID;
125     if (extraParam.find(PARAM_KEY_SUBSCRIBE_ID) != extraParam.end() &&
126         IsNumberString(extraParam.find(PARAM_KEY_SUBSCRIBE_ID)->second)) {
127         uint16_t externalSubId =
128             static_cast<uint16_t>(std::atoi((extraParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str()));
129         innerSubId = GetAndRemoveInnerSubId(pkgNameTemp, externalSubId);
130     }
131     {
132         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
133         if (capabilityMap_.find(pkgNameTemp) != capabilityMap_.end()) {
134             capabilityMap_.erase(pkgNameTemp);
135         }
136     }
137     softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgNameTemp);
138     if (innerSubId == DM_INVALID_FLAG_ID) {
139         LOGE("Invalid parameter, cannot find subscribeId in cache map.");
140         return ERR_DM_INPUT_PARA_INVALID;
141     }
142     return softbusListener_->StopRefreshSoftbusLNN(innerSubId);
143 }
144 
StartDiscovering(const std::string & pkgName,const std::map<std::string,std::string> & discoverParam,const std::map<std::string,std::string> & filterOptions)145 int32_t DiscoveryManager::StartDiscovering(const std::string &pkgName,
146     const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)
147 {
148     if (pkgName.empty()) {
149         LOGE("Invalid parameter, pkgName is empty.");
150         return ERR_DM_INPUT_PARA_INVALID;
151     }
152     LOGI("begin for pkgName = %{public}s.", pkgName.c_str());
153     std::string pkgNameTemp = AddMultiUserIdentify(pkgName);
154     DmSubscribeInfo dmSubInfo;
155     ConfigDiscParam(discoverParam, &dmSubInfo);
156     if (HandleDiscoveryQueue(pkgNameTemp, dmSubInfo.subscribeId, filterOptions) != DM_OK) {
157         return ERR_DM_DISCOVERY_REPEATED;
158     }
159     dmSubInfo.subscribeId = GenInnerSubId(pkgNameTemp, dmSubInfo.subscribeId);
160 
161     bool isStandardMetaNode = true;
162     if (discoverParam.find(PARAM_KEY_META_TYPE) != discoverParam.end()) {
163         MetaNodeType metaType = (MetaNodeType)(std::atoi((discoverParam.find(PARAM_KEY_META_TYPE)->second).c_str()));
164         isStandardMetaNode = (metaType == MetaNodeType::PROXY_TRANSMISION);
165     }
166 
167     softbusListener_->RegisterSoftbusLnnOpsCbk(pkgNameTemp, shared_from_this());
168     StartDiscoveryTimer(pkgNameTemp);
169 
170     auto it = filterOptions.find(PARAM_KEY_FILTER_OPTIONS);
171     if (it != filterOptions.end()) {
172         JsonObject jsonObject(it->second);
173         if (!jsonObject.IsDiscarded() && jsonObject.Contains(TYPE_MINE)) {
174             return StartDiscovering4MineLibary(pkgNameTemp, dmSubInfo, it->second);
175         }
176     }
177 
178     int32_t ret = isStandardMetaNode ? StartDiscoveringNoMetaType(pkgNameTemp, dmSubInfo, discoverParam) :
179             StartDiscovering4MetaType(pkgNameTemp, dmSubInfo, discoverParam);
180     if (ret != DM_OK) {
181         LOGE("StartDiscovering for meta node process failed, ret = %{public}d", ret);
182         return ret;
183     }
184     return ret;
185 }
186 
ConfigDiscParam(const std::map<std::string,std::string> & discoverParam,DmSubscribeInfo * dmSubInfo)187 void DiscoveryManager::ConfigDiscParam(const std::map<std::string, std::string> &discoverParam,
188     DmSubscribeInfo *dmSubInfo)
189 {
190     if (dmSubInfo == nullptr) {
191         LOGE("ConfigDiscParam failed, dmSubInfo is nullptr.");
192         return;
193     }
194     dmSubInfo->subscribeId = DM_INVALID_FLAG_ID;
195     dmSubInfo->mode = DmDiscoverMode::DM_DISCOVER_MODE_ACTIVE;
196     dmSubInfo->medium = DmExchangeMedium::DM_AUTO;
197     dmSubInfo->freq = DmExchangeFreq::DM_LOW;
198     dmSubInfo->isSameAccount = false;
199     dmSubInfo->isWakeRemote = false;
200     if (discoverParam.find(PARAM_KEY_SUBSCRIBE_ID) != discoverParam.end()) {
201         dmSubInfo->subscribeId = std::atoi((discoverParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str());
202     }
203     if (discoverParam.find(PARAM_KEY_DISC_MEDIUM) != discoverParam.end()) {
204         int32_t medium = std::atoi((discoverParam.find(PARAM_KEY_DISC_MEDIUM)->second).c_str());
205         dmSubInfo->medium = static_cast<DmExchangeMedium>(medium);
206     }
207     if (discoverParam.find(PARAM_KEY_DISC_FREQ) != discoverParam.end()) {
208         int32_t freq = std::atoi((discoverParam.find(PARAM_KEY_DISC_FREQ)->second).c_str());
209         dmSubInfo->freq = static_cast<DmExchangeFreq>(freq);
210     }
211     if (discoverParam.find(PARAM_KEY_DISC_MODE) != discoverParam.end()) {
212         dmSubInfo->mode =
213             static_cast<DmDiscoverMode>(std::atoi((discoverParam.find(PARAM_KEY_DISC_MODE)->second).c_str()));
214     }
215 }
216 
StartDiscovering4MineLibary(const std::string & pkgName,DmSubscribeInfo & dmSubInfo,const std::string & searchJson)217 int32_t DiscoveryManager::StartDiscovering4MineLibary(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
218     const std::string &searchJson)
219 {
220     if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_OSD) != EOK) {
221         LOGE("capability copy err.");
222         return ERR_DM_START_DISCOVERING_FAILED;
223     }
224     LOGI("mine meta node process, pkgName = %{public}s, capability = %{public}s",
225         pkgName.c_str(), std::string(dmSubInfo.capability).c_str());
226     {
227         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
228         CHECK_SIZE_RETURN(capabilityMap_, ERR_DM_START_DISCOVERING_FAILED);
229         capabilityMap_[pkgName] = std::string(dmSubInfo.capability);
230     }
231     int32_t ret = mineSoftbusListener_->RefreshSoftbusLNN(pkgName, searchJson, dmSubInfo);
232     if (ret != DM_OK) {
233         LOGE("StartDiscovering for meta node process failed, ret = %{public}d", ret);
234         return ret;
235     }
236     return ret;
237 }
238 
StartDiscoveringNoMetaType(const std::string & pkgName,DmSubscribeInfo & dmSubInfo,const std::map<std::string,std::string> & param)239 int32_t DiscoveryManager::StartDiscoveringNoMetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
240     const std::map<std::string, std::string> &param)
241 {
242     if (param.find(PARAM_KEY_DISC_CAPABILITY) != param.end() &&
243         !param.find(PARAM_KEY_DISC_CAPABILITY)->second.empty()) {
244         if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN,
245             param.find(PARAM_KEY_DISC_CAPABILITY)->second.c_str()) != EOK) {
246             LOGE("capability copy err.");
247             return ERR_DM_START_DISCOVERING_FAILED;
248         }
249     } else if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_OSD) != EOK) {
250         LOGE("capability copy err.");
251         return ERR_DM_START_DISCOVERING_FAILED;
252     }
253     LOGI("standard meta node process, pkgName = %{public}s, capability = %{public}s",
254         pkgName.c_str(), std::string(dmSubInfo.capability).c_str());
255 
256     {
257         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
258         CHECK_SIZE_RETURN(capabilityMap_, ERR_DM_START_DISCOVERING_FAILED);
259         capabilityMap_[pkgName] = std::string(dmSubInfo.capability);
260     }
261     std::string customData = LNN_DISC_CAPABILITY;
262     if (param.find(PARAM_KEY_CUSTOM_DATA) != param.end() && !param.find(PARAM_KEY_CUSTOM_DATA)->second.empty()) {
263         customData = param.find(PARAM_KEY_CUSTOM_DATA)->second;
264     }
265     int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, customData);
266     if (ret != DM_OK) {
267         LOGE("StartDiscoveringNoMetaType failed, softbus refresh lnn ret: %{public}d.", ret);
268     }
269     return ret;
270 }
271 
StartDiscovering4MetaType(const std::string & pkgName,DmSubscribeInfo & dmSubInfo,const std::map<std::string,std::string> & param)272 int32_t DiscoveryManager::StartDiscovering4MetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
273     const std::map<std::string, std::string> &param)
274 {
275     MetaNodeType metaType = MetaNodeType::CUSTOM_UNKNOWN;
276     if (param.find(PARAM_KEY_META_TYPE) != param.end()) {
277         LOGI("meta node process, input metaType = %{public}s, pkgName = %{public}s",
278             (param.find(PARAM_KEY_META_TYPE)->second).c_str(), pkgName.c_str());
279         metaType = (MetaNodeType)(std::atoi((param.find(PARAM_KEY_META_TYPE)->second).c_str()));
280     }
281     switch (metaType) {
282         case MetaNodeType::PROXY_SHARE:
283             if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_SHARE) != EOK) {
284                 LOGE("capability copy error.");
285                 return ERR_DM_FAILED;
286             }
287             break;
288         case MetaNodeType::PROXY_WEAR:
289             if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_WEAR) != EOK) {
290                 LOGE("capability copy error.");
291                 return ERR_DM_FAILED;
292             }
293             break;
294         case MetaNodeType::PROXY_CASTPLUS:
295             if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_CASTPLUS) != EOK) {
296                 LOGE("capability copy error.");
297                 return ERR_DM_FAILED;
298             }
299             break;
300         default:
301             return ERR_DM_UNSUPPORTED_METHOD;
302     }
303 
304     std::string customData = "";
305     if (param.find(PARAM_KEY_CUSTOM_DATA) != param.end()) {
306         customData = param.find(PARAM_KEY_CUSTOM_DATA)->second;
307     }
308     LOGI("capability = %{public}s,", std::string(dmSubInfo.capability).c_str());
309     {
310         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
311         CHECK_SIZE_RETURN(capabilityMap_, ERR_DM_START_DISCOVERING_FAILED);
312         capabilityMap_[pkgName] =std::string(dmSubInfo.capability);
313     }
314 
315     int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, customData);
316     if (ret != DM_OK) {
317         LOGE("StartDiscovering4MetaType failed, softbus refresh lnn ret: %{public}d.", ret);
318     }
319     return ret;
320 }
321 
StopDiscovering(const std::string & pkgName,uint16_t subscribeId)322 int32_t DiscoveryManager::StopDiscovering(const std::string &pkgName, uint16_t subscribeId)
323 {
324     if (pkgName.empty()) {
325         LOGE("Invalid parameter, pkgName is empty.");
326         return ERR_DM_INPUT_PARA_INVALID;
327     }
328     LOGI("begin for pkgName = %{public}s.", pkgName.c_str());
329     std::string pkgNameTemp = RemoveMultiUserIdentify(pkgName);
330     return StopDiscoveringByInnerSubId(pkgNameTemp, subscribeId);
331 }
332 
StopDiscoveringByInnerSubId(const std::string & pkgName,uint16_t subscribeId)333 int32_t DiscoveryManager::StopDiscoveringByInnerSubId(const std::string &pkgName, uint16_t subscribeId)
334 {
335     if (pkgName.empty()) {
336         LOGE("Invalid parameter, pkgName is empty.");
337         return ERR_DM_INPUT_PARA_INVALID;
338     }
339     LOGI("begin for pkgName = %{public}s.", pkgName.c_str());
340     uint16_t innerSubId = static_cast<uint16_t>(GetAndRemoveInnerSubId(pkgName, subscribeId));
341     if (innerSubId == DM_INVALID_FLAG_ID) {
342         LOGE("Invalid parameter, cannot find subscribeId in cache map.");
343         return ERR_DM_INPUT_PARA_INVALID;
344     }
345     {
346         std::lock_guard<std::mutex> autoLock(locks_);
347         if (pkgNameSet_.find(pkgName) != pkgNameSet_.end()) {
348             pkgNameSet_.erase(pkgName);
349         }
350 
351         if (discoveryContextMap_.find(pkgName) != discoveryContextMap_.end()) {
352             discoveryContextMap_.erase(pkgName);
353             if (timer_ != nullptr) {
354                 timer_->DeleteTimer(pkgName);
355             }
356         }
357     }
358     {
359         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
360         if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
361             capabilityMap_.erase(pkgName);
362         }
363     }
364     softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgName);
365 #if (defined(MINE_HARMONY))
366     return mineSoftbusListener_->StopRefreshSoftbusLNN(innerSubId);
367 #else
368     return softbusListener_->StopRefreshSoftbusLNN(innerSubId);
369 #endif
370 }
371 
OnDeviceFound(const std::string & pkgName,const DmDeviceInfo & info,bool isOnline)372 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const DmDeviceInfo &info, bool isOnline)
373 {
374     int32_t userId = -1;
375     std::string callerPkgName = "";
376     GetPkgNameAndUserId(pkgName, callerPkgName, userId);
377     DeviceFilterPara filterPara;
378     filterPara.isOnline = false;
379     filterPara.range = info.range;
380     filterPara.deviceType = info.deviceTypeId;
381     std::string deviceIdHash = static_cast<std::string>(info.deviceId);
382     if (isOnline && GetDeviceAclParam(callerPkgName, userId, deviceIdHash, filterPara.isOnline,
383         filterPara.authForm) != DM_OK) {
384         LOGE("The found device get online param failed.");
385     }
386     JsonObject jsonObject(info.extraData);
387     if (jsonObject.IsDiscarded()) {
388         LOGE("OnDeviceFound jsonStr error");
389         return;
390     }
391     if (!IsUint32(jsonObject, PARAM_KEY_DISC_CAPABILITY)) {
392         LOGE("err json string: %{public}s", PARAM_KEY_DISC_CAPABILITY);
393         return;
394     }
395     uint32_t capabilityType = jsonObject[PARAM_KEY_DISC_CAPABILITY].Get<uint32_t>();
396     OnDeviceFound(pkgName, capabilityType, info, filterPara);
397 }
398 
OnDeviceFound(const std::string & pkgName,const uint32_t capabilityType,const DmDeviceInfo & info,const DeviceFilterPara & filterPara)399 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const uint32_t capabilityType,
400     const DmDeviceInfo &info, const DeviceFilterPara &filterPara)
401 {
402     int32_t userId = -1;
403     std::string callerPkgName = "";
404     GetPkgNameAndUserId(pkgName, callerPkgName, userId);
405     ProcessInfo processInfo;
406     processInfo.userId = userId;
407     processInfo.pkgName = callerPkgName;
408     bool isIndiscoveryContextMap = false;
409     DiscoveryContext discoveryContext;
410     {
411         std::lock_guard<std::mutex> autoLock(locks_);
412         auto iter = discoveryContextMap_.find(pkgName);
413         isIndiscoveryContextMap = (iter != discoveryContextMap_.end());
414         if (isIndiscoveryContextMap) {
415             discoveryContext = iter->second;
416         }
417     }
418     uint16_t externalSubId = DM_INVALID_FLAG_ID;
419     {
420         std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
421         for (auto iter : pkgName2SubIdMap_[pkgName]) {
422             externalSubId = iter.first;
423             break;
424         }
425     }
426     if (!isIndiscoveryContextMap) {
427         {
428             std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
429             if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
430                 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
431                 return;
432             }
433         }
434         LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
435         listener_->OnDeviceFound(processInfo, externalSubId, info);
436         return;
437     }
438     DiscoveryFilter filter;
439     if (filter.IsValidDevice(discoveryContext.filterOp, discoveryContext.filters, filterPara)) {
440         {
441             std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
442             if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
443                 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
444                 return;
445             }
446         }
447         LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
448         listener_->OnDeviceFound(processInfo, externalSubId, info);
449     }
450 }
451 
CompareCapability(uint32_t capabilityType,const std::string & capabilityStr)452 bool DiscoveryManager::CompareCapability(uint32_t capabilityType, const std::string &capabilityStr)
453 {
454     for (uint32_t i = 0; i < sizeof(g_capabilityMap) / sizeof(g_capabilityMap[0]); i++) {
455         if (strcmp(capabilityStr.c_str(), g_capabilityMap[i].capability) == 0) {
456             LOGD("capabilityType: %{public}d, capabilityStr: %{public}s", capabilityType, capabilityStr.c_str());
457             return ((capabilityType >> static_cast<uint32_t>(g_capabilityMap[i].bitmap)) & 1);
458         }
459     }
460     return false;
461 }
462 
OnDiscoveringResult(const std::string & pkgName,int32_t subscribeId,int32_t result)463 void DiscoveryManager::OnDiscoveringResult(const std::string &pkgName, int32_t subscribeId, int32_t result)
464 {
465     LOGI("subscribeId = %{public}d, result = %{public}d.", subscribeId, result);
466     int32_t userId = -1;
467     std::string callerPkgName = "";
468     GetPkgNameAndUserId(pkgName, callerPkgName, userId);
469     ProcessInfo processInfo;
470     processInfo.userId = userId;
471     processInfo.pkgName = callerPkgName;
472     if (pkgName.empty() || (listener_ == nullptr)) {
473         LOGE("DiscoveryManager::OnDiscoveringResult failed, IDeviceManagerServiceListener is null.");
474         return;
475     }
476     uint16_t externalSubId = DM_INVALID_FLAG_ID;
477     {
478         std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
479         for (auto iter : pkgName2SubIdMap_[pkgName]) {
480             if (iter.second == subscribeId) {
481                 externalSubId = iter.first;
482                 break;
483             }
484         }
485     }
486     if (result == 0) {
487         std::lock_guard<std::mutex> autoLock(locks_);
488         discoveryContextMap_[pkgName].subscribeId = (uint32_t)externalSubId;
489         listener_->OnDiscoverySuccess(processInfo, externalSubId);
490         return;
491     }
492     {
493         std::lock_guard<std::mutex> autoLock(locks_);
494         if (pkgNameSet_.find(pkgName) != pkgNameSet_.end()) {
495             pkgNameSet_.erase(pkgName);
496         }
497         if (discoveryContextMap_.find(pkgName) != discoveryContextMap_.end()) {
498             discoveryContextMap_.erase(pkgName);
499             if (timer_ != nullptr) {
500                 timer_->DeleteTimer(pkgName);
501             }
502         }
503     }
504     {
505         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
506         if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
507             capabilityMap_.erase(pkgName);
508         }
509     }
510     listener_->OnDiscoveryFailed(processInfo, (uint32_t)externalSubId, result);
511     softbusListener_->StopRefreshSoftbusLNN(subscribeId);
512 }
513 
StartDiscoveryTimer(const std::string & pkgName)514 void DiscoveryManager::StartDiscoveryTimer(const std::string &pkgName)
515 {
516     if (timer_ == nullptr) {
517         timer_ = std::make_shared<DmTimer>();
518     }
519     timer_->StartTimer(pkgName, DISCOVERY_TIMEOUT,
520         [this] (std::string name) {
521             DiscoveryManager::HandleDiscoveryTimeout(name);
522         });
523 }
524 
HandleDiscoveryQueue(const std::string & pkgName,uint16_t subscribeId,const std::map<std::string,std::string> & filterOps)525 int32_t DiscoveryManager::HandleDiscoveryQueue(const std::string &pkgName, uint16_t subscribeId,
526     const std::map<std::string, std::string> &filterOps)
527 {
528     std::string filterData = "";
529     if (filterOps.find(PARAM_KEY_FILTER_OPTIONS) != filterOps.end()) {
530         filterData = filterOps.find(PARAM_KEY_FILTER_OPTIONS)->second;
531     }
532     DeviceFilterOption dmFilter;
533     if ((dmFilter.TransformToFilter(filterData) != DM_OK) && (dmFilter.TransformFilterOption(filterData) != DM_OK)) {
534         return ERR_DM_INPUT_PARA_INVALID;
535     }
536     {
537         std::lock_guard<std::mutex> autoLock(locks_);
538         CHECK_SIZE_RETURN(pkgNameSet_, ERR_DM_DISCOVERY_REPEATED);
539         CHECK_SIZE_RETURN(discoveryContextMap_, ERR_DM_DISCOVERY_REPEATED);
540         if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
541             pkgNameSet_.emplace(pkgName);
542             DiscoveryContext context = {pkgName, filterData, subscribeId, dmFilter.filterOp_, dmFilter.filters_};
543             discoveryContextMap_.emplace(pkgName, context);
544             return DM_OK;
545         } else {
546             LOGE("DiscoveryManager::HandleDiscoveryQueue repeated, pkgName : %{public}s.", pkgName.c_str());
547             return ERR_DM_DISCOVERY_REPEATED;
548         }
549     }
550 }
551 
HandleDiscoveryTimeout(const std::string & pkgName)552 void DiscoveryManager::HandleDiscoveryTimeout(const std::string &pkgName)
553 {
554     LOGI("pkgName: %{public}s.", pkgName.c_str());
555     uint16_t subscribeId = 0;
556     {
557         std::lock_guard<std::mutex> autoLock(locks_);
558         if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
559             LOGE("HandleDiscoveryTimeout: pkgName: %{public}s is not exist.", pkgName.c_str());
560             return;
561         }
562         auto iter = discoveryContextMap_.find(pkgName);
563         if (iter == discoveryContextMap_.end()) {
564             LOGE("HandleDiscoveryTimeout: subscribeId not found by pkgName %{public}s.",
565                 GetAnonyString(pkgName).c_str());
566             return;
567         }
568         subscribeId = discoveryContextMap_[pkgName].subscribeId;
569     }
570     StopDiscoveringByInnerSubId(pkgName, subscribeId);
571     {
572         std::lock_guard<std::mutex> autoLock(multiUserDiscLocks_);
573         multiUserDiscMap_.erase(pkgName);
574     }
575 }
576 
UpdateInfoFreq(const std::map<std::string,std::string> & discoverParam,DmSubscribeInfo & dmSubInfo)577 void DiscoveryManager::UpdateInfoFreq(
578     const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo &dmSubInfo)
579 {
580     if (auto it = discoverParam.find(PARAM_KEY_DISC_FREQ); it != discoverParam.end()) {
581         int32_t freq = StringToInt(it->second, DECIMALISM);
582         if (freq < DmExchangeFreq::DM_LOW || freq > DmExchangeFreq::DM_FREQ_BUTT) {
583             LOGE("Invalid freq value.");
584             return;
585         }
586         dmSubInfo.freq = static_cast<DmExchangeFreq>(freq);
587     }
588 }
589 
UpdateInfoMedium(const std::map<std::string,std::string> & discoverParam,DmSubscribeInfo & dmSubInfo)590 void DiscoveryManager::UpdateInfoMedium(
591     const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo &dmSubInfo)
592 {
593     dmSubInfo.medium = DmExchangeMedium::DM_BLE;
594     if (discoverParam.find(PARAM_KEY_DISC_MEDIUM) != discoverParam.end()) {
595         int32_t medium = std::atoi((discoverParam.find(PARAM_KEY_DISC_MEDIUM)->second).c_str());
596         dmSubInfo.medium = static_cast<DmExchangeMedium>(medium);
597     }
598 }
599 
GetDeviceAclParam(const std::string & pkgName,int32_t userId,std::string deviceId,bool & isOnline,int32_t & authForm)600 int32_t DiscoveryManager::GetDeviceAclParam(const std::string &pkgName, int32_t userId, std::string deviceId,
601     bool &isOnline, int32_t &authForm)
602 {
603 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
604     char localDeviceId[DEVICE_UUID_LENGTH];
605     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
606     std::string requestDeviceId = static_cast<std::string>(localDeviceId);
607     DmDiscoveryInfo discoveryInfo;
608     discoveryInfo.pkgname = pkgName;
609     discoveryInfo.localDeviceId = requestDeviceId;
610     discoveryInfo.remoteDeviceIdHash = deviceId;
611     discoveryInfo.userId = userId;
612     if (DiscoveryManager::IsCommonDependencyReady() && DiscoveryManager::GetCommonDependencyObj() != nullptr) {
613         if (DiscoveryManager::GetCommonDependencyObj()->GetDeviceAclParam(discoveryInfo, isOnline, authForm) != DM_OK) {
614             LOGE("GetDeviceAclParam failed.");
615             return ERR_DM_FAILED;
616         }
617     }
618 #endif
619     return DM_OK;
620 }
621 
622 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
GetCommonDependencyObj()623 IDeviceProfileConnector* DiscoveryManager::GetCommonDependencyObj()
624 {
625     return dpConnector_;
626 }
627 
IsCommonDependencyReady()628 bool DiscoveryManager::IsCommonDependencyReady()
629 {
630     std::lock_guard<std::mutex> lock(comDependencyLoadLock);
631     if (isSoLoaded_ && dpConnector_ != nullptr && dpConnectorHandle_ != nullptr) {
632         return true;
633     }
634     dpConnectorHandle_ = dlopen(LIB_DM_COMDENPENDENCY_NAME, RTLD_NOW | RTLD_NODELETE | RTLD_NOLOAD);
635     if (dpConnectorHandle_ == nullptr) {
636         dpConnectorHandle_ = dlopen(LIB_DM_COMDENPENDENCY_NAME, RTLD_NOW | RTLD_NODELETE);
637     }
638     if (dpConnectorHandle_ == nullptr) {
639         LOGE("load libdevicemanagerdependency so failed, errMsg: %{public}s.", dlerror());
640         return false;
641     }
642     dlerror();
643     auto func = (CreateDpConnectorFuncPtr)dlsym(dpConnectorHandle_, "CreateDpConnectorInstance");
644     if (dlerror() != nullptr || func == nullptr) {
645         dlclose(dpConnectorHandle_);
646         LOGE("Create object function is not exist.");
647         return false;
648     }
649     dpConnector_ = func();
650     isSoLoaded_ = true;
651     return true;
652 }
653 
CloseCommonDependencyObj()654 bool DiscoveryManager::CloseCommonDependencyObj()
655 {
656     LOGI("start.");
657     std::lock_guard<std::mutex> lock(comDependencyLoadLock);
658     if (!isSoLoaded_ && (dpConnector_ == nullptr) && (dpConnectorHandle_ == nullptr)) {
659         return true;
660     }
661 
662     int32_t ret = dlclose(dpConnectorHandle_);
663     if (ret != 0) {
664         LOGE("close libdevicemanagerdependency failed ret = %{public}d.", ret);
665         return false;
666     }
667     isSoLoaded_ = false;
668     dpConnector_ = nullptr;
669     dpConnectorHandle_ = nullptr;
670     return true;
671 }
672 #endif
673 
ClearDiscoveryCache(const ProcessInfo & processInfo)674 void DiscoveryManager::ClearDiscoveryCache(const ProcessInfo &processInfo)
675 {
676     LOGI("PkgName: %{public}s, userId: %{public}d", processInfo.pkgName.c_str(), processInfo.userId);
677     std::string pkgName = processInfo.pkgName + "#";
678     std::set<uint16_t> subscribeIdSet = ClearDiscoveryPkgName(pkgName);
679 
680     CHECK_NULL_VOID(softbusListener_);
681     for (auto it : subscribeIdSet) {
682         std::string pkgNameTemp = (ComposeStr(ComposeStr(processInfo.pkgName, it), processInfo.userId));
683         softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgNameTemp);
684         uint16_t innerSubId = DM_INVALID_FLAG_ID;
685         {
686             std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
687             innerSubId = static_cast<uint16_t>(pkgName2SubIdMap_[pkgNameTemp][it]);
688             randSubIdSet_.erase(innerSubId);
689             pkgName2SubIdMap_.erase(pkgNameTemp);
690         }
691         softbusListener_->StopRefreshSoftbusLNN(innerSubId);
692     }
693 
694     CHECK_NULL_VOID(timer_);
695     for (auto it : subscribeIdSet) {
696         std::string pkgNameTemp = (ComposeStr(ComposeStr(processInfo.pkgName, it), processInfo.userId));
697         timer_->DeleteTimer(pkgNameTemp);
698     }
699 }
700 
ClearDiscoveryPkgName(const std::string & pkgName)701 std::set<uint16_t> DiscoveryManager::ClearDiscoveryPkgName(const std::string &pkgName)
702 {
703     std::set<uint16_t> subscribeIdSet;
704     {
705         std::lock_guard<std::mutex> autoLock(locks_);
706         for (auto it = pkgNameSet_.begin(); it != pkgNameSet_.end();) {
707             if ((*it).find(pkgName) != std::string::npos) {
708                 LOGI("Erase pkgname %{public}s from pkgNameSet.", (*it).c_str());
709                 it = pkgNameSet_.erase(it);
710             } else {
711                 ++it;
712             }
713         }
714         for (auto it = discoveryContextMap_.begin(); it != discoveryContextMap_.end();) {
715             if (it->first.find(pkgName) != std::string::npos) {
716                 LOGI("Erase pkgname %{public}s from discoveryContextMap_.", it->first.c_str());
717                 subscribeIdSet.insert(it->second.subscribeId);
718                 it = discoveryContextMap_.erase(it);
719             } else {
720                 ++it;
721             }
722         }
723     }
724     {
725         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
726         for (auto it = capabilityMap_.begin(); it != capabilityMap_.end();) {
727             if (it->first.find(pkgName) != std::string::npos) {
728                 LOGI("Erase pkgname %{public}s from capabilityMap_.", it->first.c_str());
729                 it = capabilityMap_.erase(it);
730             } else {
731                 ++it;
732             }
733         }
734     }
735     {
736         std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
737         for (auto it = pkgName2SubIdMap_.begin(); it != pkgName2SubIdMap_.end(); ++it) {
738             if (it->first.find(pkgName) != std::string::npos) {
739                 LOGI("Erase pkgname %{public}s from pkgName2SubIdMap_.", it->first.c_str());
740                 for (auto iter : it->second) {
741                     subscribeIdSet.insert(iter.first);
742                 }
743             }
744         }
745     }
746     return subscribeIdSet;
747 }
748 
AddMultiUserIdentify(const std::string & pkgName)749 std::string DiscoveryManager::AddMultiUserIdentify(const std::string &pkgName)
750 {
751     int32_t userId = -1;
752 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
753     MultipleUserConnector::GetCallerUserId(userId);
754 #endif
755     if (userId == -1) {
756         LOGE("Get caller userId failed.");
757         return pkgName;
758     }
759     MultiUserDiscovery multiUserDisc;
760     multiUserDisc.pkgName = pkgName;
761     multiUserDisc.userId = userId;
762     std::string pkgNameTemp = ComposeStr(pkgName, userId);
763     {
764         std::lock_guard<std::mutex> autoLock(multiUserDiscLocks_);
765         CHECK_SIZE_RETURN(multiUserDiscMap_, pkgNameTemp);
766         multiUserDiscMap_[pkgNameTemp] = multiUserDisc;
767     }
768     return pkgNameTemp;
769 }
770 
RemoveMultiUserIdentify(const std::string & pkgName)771 std::string DiscoveryManager::RemoveMultiUserIdentify(const std::string &pkgName)
772 {
773     int32_t userId = -1;
774 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
775     MultipleUserConnector::GetCallerUserId(userId);
776 #endif
777     if (userId == -1) {
778         LOGE("Get caller userId failed.");
779         return pkgName;
780     }
781     std::string pkgNameTemp = ComposeStr(pkgName, userId);
782     {
783         std::lock_guard<std::mutex> autoLock(multiUserDiscLocks_);
784         if (multiUserDiscMap_.find(pkgNameTemp) != multiUserDiscMap_.end()) {
785             multiUserDiscMap_.erase(pkgNameTemp);
786         }
787     }
788     return pkgNameTemp;
789 }
790 
GetPkgNameAndUserId(const std::string & pkgName,std::string & callerPkgName,int32_t & userId)791 void DiscoveryManager::GetPkgNameAndUserId(const std::string &pkgName, std::string &callerPkgName,
792     int32_t &userId)
793 {
794     {
795         std::lock_guard<std::mutex> autoLock(multiUserDiscLocks_);
796         if (multiUserDiscMap_.find(pkgName) != multiUserDiscMap_.end()) {
797             callerPkgName = GetCallerPkgName(multiUserDiscMap_[pkgName].pkgName);
798             userId = multiUserDiscMap_[pkgName].userId;
799             return;
800         }
801     }
802     LOGE("find failed PkgName %{public}s.", pkgName.c_str());
803 }
804 
GenInnerSubId(const std::string & pkgName,uint16_t subId)805 int32_t DiscoveryManager::GenInnerSubId(const std::string &pkgName, uint16_t subId)
806 {
807     uint16_t tempSubId = DM_INVALID_FLAG_ID;
808     {
809         std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
810         CHECK_SIZE_RETURN(pkgName2SubIdMap_, tempSubId);
811         CHECK_SIZE_RETURN(pkgName2SubIdMap_[pkgName], tempSubId);
812         if (pkgName2SubIdMap_[pkgName].find(subId) != pkgName2SubIdMap_[pkgName].end()) {
813             return pkgName2SubIdMap_[pkgName][subId];
814         }
815         if (pkgName2SubIdMap_.find(pkgName) == pkgName2SubIdMap_.end()) {
816             pkgName2SubIdMap_[pkgName] = std::map<uint16_t, uint16_t>();
817         }
818         tempSubId = GenUniqueRandUint(randSubIdSet_);
819         pkgName2SubIdMap_[pkgName][subId] = tempSubId;
820     }
821     return tempSubId;
822 }
823 
GetAndRemoveInnerSubId(const std::string & pkgName,uint16_t subId)824 int32_t DiscoveryManager::GetAndRemoveInnerSubId(const std::string &pkgName, uint16_t subId)
825 {
826     uint16_t tempSubId = DM_INVALID_FLAG_ID;
827     {
828         std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
829         if (pkgName2SubIdMap_[pkgName].find(subId) != pkgName2SubIdMap_[pkgName].end()) {
830             tempSubId = pkgName2SubIdMap_[pkgName][subId];
831             pkgName2SubIdMap_[pkgName].erase(subId);
832             randSubIdSet_.erase(tempSubId);
833         }
834         if (pkgName2SubIdMap_[pkgName].empty()) {
835             pkgName2SubIdMap_.erase(pkgName);
836         }
837     }
838     return tempSubId;
839 }
840 } // namespace DistributedHardware
841 } // namespace OHOS
842