1 /*
2 * Copyright (c) 2022-2023 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 "dm_discovery_manager.h"
17 #include "dm_discovery_filter.h"
18 #include "dm_anonymous.h"
19 #include "dm_constants.h"
20 #include "dm_log.h"
21
22 namespace OHOS {
23 namespace DistributedHardware {
24 constexpr const char* DISCOVERY_TIMEOUT_TASK = "deviceManagerTimer:discovery";
25 const int32_t DISCOVERY_TIMEOUT = 120;
26
DmDiscoveryManager(std::shared_ptr<SoftbusConnector> softbusConnector,std::shared_ptr<IDeviceManagerServiceListener> listener)27 DmDiscoveryManager::DmDiscoveryManager(std::shared_ptr<SoftbusConnector> softbusConnector,
28 std::shared_ptr<IDeviceManagerServiceListener> listener)
29 : softbusConnector_(softbusConnector), listener_(listener)
30 {
31 LOGI("DmDiscoveryManager constructor");
32 }
33
~DmDiscoveryManager()34 DmDiscoveryManager::~DmDiscoveryManager()
35 {
36 LOGI("DmDiscoveryManager destructor");
37 }
38
CfgDiscoveryTimer()39 void DmDiscoveryManager::CfgDiscoveryTimer()
40 {
41 if (timer_ == nullptr) {
42 timer_ = std::make_shared<DmTimer>();
43 }
44 timer_->StartTimer(std::string(DISCOVERY_TIMEOUT_TASK), DISCOVERY_TIMEOUT,
45 [this] (std::string name) {
46 DmDiscoveryManager::HandleDiscoveryTimeout(name);
47 });
48 }
49
CheckDiscoveryQueue(const std::string & pkgName)50 int32_t DmDiscoveryManager::CheckDiscoveryQueue(const std::string &pkgName)
51 {
52 uint16_t subscribeId = 0;
53 std::string frontPkgname = "";
54 {
55 std::lock_guard<std::mutex> autoLock(locks_);
56 if (discoveryQueue_.empty()) {
57 return DM_OK;
58 }
59 frontPkgname = discoveryQueue_.front();
60 if (pkgName == frontPkgname) {
61 LOGE("DmDiscoveryManager::StartDeviceDiscovery repeated, pkgName:%s", pkgName.c_str());
62 return ERR_DM_DISCOVERY_REPEATED;
63 }
64 LOGI("DmDiscoveryManager::StartDeviceDiscovery stop preview discovery first, the preview pkgName is %s",
65 frontPkgname.c_str());
66 subscribeId = discoveryContextMap_[discoveryQueue_.front()].subscribeId;
67 }
68 StopDeviceDiscovery(frontPkgname, subscribeId);
69 return DM_OK;
70 }
71
StartDeviceDiscovery(const std::string & pkgName,const DmSubscribeInfo & subscribeInfo,const std::string & extra)72 int32_t DmDiscoveryManager::StartDeviceDiscovery(const std::string &pkgName, const DmSubscribeInfo &subscribeInfo,
73 const std::string &extra)
74 {
75 DmDeviceFilterOption dmFilter;
76 if (dmFilter.TransformToFilter(extra) != DM_OK) {
77 return ERR_DM_INPUT_PARA_INVALID;
78 }
79
80 if (CheckDiscoveryQueue(pkgName) != DM_OK) {
81 return ERR_DM_DISCOVERY_REPEATED;
82 }
83
84 {
85 std::lock_guard<std::mutex> autoLock(locks_);
86 discoveryQueue_.push(pkgName);
87 DmDiscoveryContext context = {pkgName, extra, subscribeInfo.subscribeId, dmFilter.filterOp_, dmFilter.filters_};
88 discoveryContextMap_.emplace(pkgName, context);
89 }
90 softbusConnector_->RegisterSoftbusDiscoveryCallback(pkgName,
91 std::shared_ptr<ISoftbusDiscoveryCallback>(shared_from_this()));
92 CfgDiscoveryTimer();
93 return softbusConnector_->StartDiscovery(subscribeInfo);
94 }
95
StopDeviceDiscovery(const std::string & pkgName,uint16_t subscribeId)96 int32_t DmDiscoveryManager::StopDeviceDiscovery(const std::string &pkgName, uint16_t subscribeId)
97 {
98 if (pkgName.empty()) {
99 LOGE("Invalid parameter, pkgName is empty.");
100 return ERR_DM_INPUT_PARA_INVALID;
101 }
102 {
103 std::lock_guard<std::mutex> autoLock(locks_);
104 if (!discoveryQueue_.empty()) {
105 discoveryQueue_.pop();
106 }
107 if (!discoveryContextMap_.empty()) {
108 discoveryContextMap_.erase(pkgName);
109 softbusConnector_->UnRegisterSoftbusDiscoveryCallback(pkgName);
110 timer_->DeleteTimer(std::string(DISCOVERY_TIMEOUT_TASK));
111 }
112 }
113 return softbusConnector_->StopDiscovery(subscribeId);
114 }
115
OnDeviceFound(const std::string & pkgName,const DmDeviceInfo & info)116 void DmDiscoveryManager::OnDeviceFound(const std::string &pkgName, const DmDeviceInfo &info)
117 {
118 LOGI("DmDiscoveryManager::OnDeviceFound deviceId = %s", GetAnonyString(info.deviceId).c_str());
119 DmDiscoveryContext dmDiscoveryContext;
120 {
121 std::lock_guard<std::mutex> autoLock(locks_);
122 auto iter = discoveryContextMap_.find(pkgName);
123 if (iter == discoveryContextMap_.end()) {
124 LOGE("subscribeId not found by pkgName %s", GetAnonyString(pkgName).c_str());
125 return;
126 }
127 dmDiscoveryContext = iter->second;
128 }
129 DmDiscoveryFilter filter;
130 DmDeviceFilterPara filterPara;
131 filterPara.isOnline = softbusConnector_->IsDeviceOnLine(info.deviceId);
132 filterPara.range = info.range;
133 if (filter.IsValidDevice(dmDiscoveryContext.filterOp, dmDiscoveryContext.filters, filterPara)) {
134 listener_->OnDeviceFound(pkgName, dmDiscoveryContext.subscribeId, info);
135 }
136 return;
137 }
138
OnDiscoveryFailed(const std::string & pkgName,int32_t subscribeId,int32_t failedReason)139 void DmDiscoveryManager::OnDiscoveryFailed(const std::string &pkgName, int32_t subscribeId, int32_t failedReason)
140 {
141 LOGI("DmDiscoveryManager::OnDiscoveryFailed subscribeId = %d reason = %d", subscribeId, failedReason);
142 StopDeviceDiscovery(pkgName, (uint32_t)subscribeId);
143 listener_->OnDiscoveryFailed(pkgName, (uint32_t)subscribeId, failedReason);
144 }
145
OnDiscoverySuccess(const std::string & pkgName,int32_t subscribeId)146 void DmDiscoveryManager::OnDiscoverySuccess(const std::string &pkgName, int32_t subscribeId)
147 {
148 LOGI("DmDiscoveryManager::OnDiscoverySuccess subscribeId = %d", subscribeId);
149 {
150 std::lock_guard<std::mutex> autoLock(locks_);
151 discoveryContextMap_[pkgName].subscribeId = (uint32_t)subscribeId;
152 }
153 listener_->OnDiscoverySuccess(pkgName, subscribeId);
154 }
155
HandleDiscoveryTimeout(std::string name)156 void DmDiscoveryManager::HandleDiscoveryTimeout(std::string name)
157 {
158 LOGI("DmDiscoveryManager::HandleDiscoveryTimeout");
159 std::string pkgName = "";
160 uint16_t subscribeId = 0;
161 {
162 std::lock_guard<std::mutex> autoLock(locks_);
163 if (discoveryQueue_.empty()) {
164 LOGE("HandleDiscoveryTimeout: discovery queue is empty.");
165 return;
166 }
167 pkgName = discoveryQueue_.front();
168
169 auto iter = discoveryContextMap_.find(pkgName);
170 if (iter == discoveryContextMap_.end()) {
171 LOGE("HandleDiscoveryTimeout: subscribeId not found by pkgName %s", GetAnonyString(pkgName).c_str());
172 return;
173 }
174 subscribeId = discoveryContextMap_[pkgName].subscribeId;
175 }
176 StopDeviceDiscovery(pkgName, subscribeId);
177 }
178 } // namespace DistributedHardware
179 } // namespace OHOS
180