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