• 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 "advertise_manager.h"
17 
18 #include "dm_constants.h"
19 #include "dm_log.h"
20 #include "dm_publish_info.h"
21 #include "dm_random.h"
22 #include "system_ability_definition.h"
23 
24 namespace OHOS {
25 namespace DistributedHardware {
26 const int32_t AUTO_STOP_ADVERTISE_DEFAULT_TIME = 120;
27 const std::string AUTO_STOP_ADVERTISE_TASK = "AutoStopAdvertisingTask";
28 const int32_t DM_MIN_RANDOM = 1;
29 const int32_t DM_MAX_RANDOM = INT32_MAX;
30 const int32_t DM_INVALID_FLAG_ID = 0;
31 
AdvertiseManager(std::shared_ptr<SoftbusListener> softbusListener)32 AdvertiseManager::AdvertiseManager(std::shared_ptr<SoftbusListener> softbusListener) : softbusListener_(softbusListener)
33 {
34     LOGI("AdvertiseManager constructor.");
35 }
36 
~AdvertiseManager()37 AdvertiseManager::~AdvertiseManager()
38 {
39     LOGI("AdvertiseManager destructor.");
40 }
41 
StartAdvertising(const std::string & pkgName,const std::map<std::string,std::string> & advertiseParam)42 int32_t AdvertiseManager::StartAdvertising(const std::string &pkgName,
43     const std::map<std::string, std::string> &advertiseParam)
44 {
45     if (pkgName.empty()) {
46         LOGE("Invalid parameter, pkgName is empty.");
47         return ERR_DM_INPUT_PARA_INVALID;
48     }
49     LOGI("begin for pkgName = %{public}s.", pkgName.c_str());
50     DmPublishInfo dmPubInfo;
51     ConfigAdvParam(advertiseParam, &dmPubInfo, pkgName);
52     std::string capability = DM_CAPABILITY_OSD;
53     if (advertiseParam.find(PARAM_KEY_DISC_CAPABILITY) != advertiseParam.end()) {
54         capability = advertiseParam.find(PARAM_KEY_DISC_CAPABILITY)->second;
55     }
56     if (capability == DM_CAPABILITY_APPROACH || capability == DM_CAPABILITY_TOUCH) {
57         dmPubInfo.mode = DmDiscoverMode::DM_DISCOVER_MODE_ACTIVE;
58     }
59     if (capability == DM_CAPABILITY_OOP) {
60         dmPubInfo.ranging = false;
61     }
62     std::string customData = "";
63     if (advertiseParam.find(PARAM_KEY_CUSTOM_DATA) != advertiseParam.end()) {
64         customData = advertiseParam.find(PARAM_KEY_CUSTOM_DATA)->second;
65     }
66 
67     int32_t ret = softbusListener_->PublishSoftbusLNN(dmPubInfo, capability, customData);
68     if (ret != DM_OK) {
69         LOGE("failed, softbus publish lnn ret: %{public}d", ret);
70         return ret;
71     }
72 
73     if (advertiseParam.find(PARAM_KEY_AUTO_STOP_ADVERTISE) != advertiseParam.end()) {
74         int32_t stopTime = std::atoi((advertiseParam.find(PARAM_KEY_AUTO_STOP_ADVERTISE)->second).c_str());
75         if ((stopTime <= 0) || (stopTime > AUTO_STOP_ADVERTISE_DEFAULT_TIME)) {
76             LOGE("StartAdvertising error, invalid input auto stop advertise time: %{public}d", stopTime);
77             return DM_OK;
78         }
79         if (timer_ == nullptr) {
80             timer_ = std::make_shared<DmTimer>();
81         }
82         int32_t publishId = dmPubInfo.publishId;
83         timer_->StartTimer(std::string(AUTO_STOP_ADVERTISE_TASK), stopTime,
84             [this, pkgName, publishId] (std::string name) {
85                 AdvertiseManager::HandleAutoStopAdvertise(name, pkgName, publishId);
86             });
87     }
88     return DM_OK;
89 }
90 
ConfigAdvParam(const std::map<std::string,std::string> & advertiseParam,DmPublishInfo * dmPubInfo,const std::string & pkgName)91 void AdvertiseManager::ConfigAdvParam(const std::map<std::string, std::string> &advertiseParam,
92     DmPublishInfo *dmPubInfo, const std::string &pkgName)
93 {
94     if (dmPubInfo == nullptr) {
95         LOGE("ConfigAdvParam failed, dmPubInfo is nullptr.");
96         return;
97     }
98     dmPubInfo->publishId = -1;
99     dmPubInfo->mode = DmDiscoverMode::DM_DISCOVER_MODE_PASSIVE;
100     dmPubInfo->freq = DmExchangeFreq::DM_LOW;
101     dmPubInfo->ranging = true;
102     dmPubInfo->medium = DmExchangeMedium::DM_AUTO;
103 
104     if (advertiseParam.find(PARAM_KEY_META_TYPE) != advertiseParam.end()) {
105         LOGI("StartAdvertising input MetaType=%{public}s", (advertiseParam.find(PARAM_KEY_META_TYPE)->second).c_str());
106     }
107     if (advertiseParam.find(PARAM_KEY_PUBLISH_ID) != advertiseParam.end() &&
108         IsNumberString(advertiseParam.find(PARAM_KEY_PUBLISH_ID)->second)) {
109             int32_t publishId = std::atoi((advertiseParam.find(PARAM_KEY_PUBLISH_ID)->second).c_str());
110             LOGI("PublishId=%{public}d", publishId);
111             dmPubInfo->publishId = GenInnerPublishId(pkgName, publishId);
112     }
113     if (advertiseParam.find(PARAM_KEY_DISC_MODE) != advertiseParam.end()) {
114         dmPubInfo->mode =
115             static_cast<DmDiscoverMode>(std::atoi((advertiseParam.find(PARAM_KEY_DISC_MODE)->second).c_str()));
116     }
117     if (advertiseParam.find(PARAM_KEY_DISC_FREQ) != advertiseParam.end()) {
118         dmPubInfo->freq =
119             static_cast<DmExchangeFreq>(std::atoi((advertiseParam.find(PARAM_KEY_DISC_FREQ)->second).c_str()));
120     }
121     if (advertiseParam.find(PARAM_KEY_DISC_MEDIUM) != advertiseParam.end()) {
122         if (IsNumberString(advertiseParam.find(PARAM_KEY_DISC_MEDIUM)->second)) {
123             dmPubInfo->medium =
124                 static_cast<DmExchangeMedium>(std::atoi((advertiseParam.find(PARAM_KEY_DISC_MEDIUM)->second).c_str()));
125         }
126     }
127 }
128 
StopAdvertising(const std::string & pkgName,int32_t publishId)129 int32_t AdvertiseManager::StopAdvertising(const std::string &pkgName, int32_t publishId)
130 {
131     if (pkgName.empty()) {
132         LOGE("Invalid parameter, pkgName is empty.");
133         return ERR_DM_INPUT_PARA_INVALID;
134     }
135     LOGI("begin for pkgName = %{public}s, publishId = %{public}d.", pkgName.c_str(), publishId);
136     int32_t innerPublishId = GetAndRemoveInnerPublishId(pkgName, publishId);
137     if (innerPublishId == DM_INVALID_FLAG_ID) {
138         LOGE("Failed: cannot find pkgName in cache map.");
139         return ERR_DM_INPUT_PARA_INVALID;
140     }
141     return softbusListener_->StopPublishSoftbusLNN(innerPublishId);
142 }
143 
HandleAutoStopAdvertise(const std::string & timerName,const std::string & pkgName,int32_t publishId)144 void AdvertiseManager::HandleAutoStopAdvertise(const std::string &timerName, const std::string &pkgName,
145     int32_t publishId)
146 {
147     LOGI("auto stop advertise task timeout, timerName=%{public}s", timerName.c_str());
148     StopAdvertising(pkgName, publishId);
149 }
150 
GenInnerPublishId(const std::string & pkgName,int32_t publishId)151 int32_t AdvertiseManager::GenInnerPublishId(const std::string &pkgName, int32_t publishId)
152 {
153     int32_t tempPublishId = DM_INVALID_FLAG_ID;
154     {
155         std::lock_guard<std::mutex> autoLock(pubMapLock_);
156         CHECK_SIZE_RETURN(pkgName2PubIdMap_, DM_INVALID_FLAG_ID);
157         CHECK_SIZE_RETURN(publishIdSet_, DM_INVALID_FLAG_ID);
158         if (pkgName2PubIdMap_[pkgName].find(publishId) != pkgName2PubIdMap_[pkgName].end()) {
159             return pkgName2PubIdMap_[pkgName][publishId];
160         }
161         if (pkgName2PubIdMap_.find(pkgName) == pkgName2PubIdMap_.end()) {
162             pkgName2PubIdMap_[pkgName] = std::map<int32_t, int32_t>();
163         }
164         bool isExist = false;
165         do {
166             tempPublishId = GenRandInt(DM_MIN_RANDOM, DM_MAX_RANDOM);
167             if (publishIdSet_.find(tempPublishId) != publishIdSet_.end() ||
168                 tempPublishId == DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID) {
169                 LOGE("The tempPublishId: %{public}d is exist.", tempPublishId);
170                 isExist = true;
171             } else {
172                 isExist = false;
173             }
174         } while (isExist);
175         publishIdSet_.emplace(tempPublishId);
176         pkgName2PubIdMap_[pkgName][publishId] = tempPublishId;
177     }
178     return tempPublishId;
179 }
180 
GetAndRemoveInnerPublishId(const std::string & pkgName,int32_t publishId)181 int32_t AdvertiseManager::GetAndRemoveInnerPublishId(const std::string &pkgName, int32_t publishId)
182 {
183     int32_t tempPublishId = DM_INVALID_FLAG_ID;
184     {
185         std::lock_guard<std::mutex> autoLock(pubMapLock_);
186         if (pkgName2PubIdMap_.find(pkgName) != pkgName2PubIdMap_.end() &&
187             pkgName2PubIdMap_[pkgName].find(publishId) != pkgName2PubIdMap_[pkgName].end()) {
188                 tempPublishId = pkgName2PubIdMap_[pkgName][publishId];
189                 pkgName2PubIdMap_[pkgName].erase(publishId);
190                 publishIdSet_.erase(tempPublishId);
191         }
192         if (pkgName2PubIdMap_[pkgName].empty()) {
193             pkgName2PubIdMap_.erase(pkgName);
194         }
195     }
196     return tempPublishId;
197 }
198 
ClearPublishIdCache(const std::string & pkgName)199 void AdvertiseManager::ClearPublishIdCache(const std::string &pkgName)
200 {
201     if (pkgName.empty()) {
202         LOGE("Invalid parameter, pkgName is empty.");
203         return;
204     }
205     LOGI("Begin for pkgName = %{public}s.", pkgName.c_str());
206     std::lock_guard<std::mutex> autoLock(pubMapLock_);
207     for (auto iter : pkgName2PubIdMap_[pkgName]) {
208         softbusListener_->StopPublishSoftbusLNN(iter.second);
209         publishIdSet_.erase(iter.second);
210     }
211     pkgName2PubIdMap_.erase(pkgName);
212 }
213 } // namespace DistributedHardware
214 } // namespace OHOS
215