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> ¶m)
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> ¶m)
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