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