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
22namespace OHOS {
23namespace DistributedHardware {
24const int32_t AUTO_STOP_ADVERTISE_DEFAULT_TIME = 120;
25const std::string AUTO_STOP_ADVERTISE_TASK = "AutoStopAdvertisingTask";
26
27AdvertiseManager::AdvertiseManager(std::shared_ptr<SoftbusListener> softbusListener) : softbusListener_(softbusListener)
28{
29    LOGI("AdvertiseManager constructor.");
30}
31
32AdvertiseManager::~AdvertiseManager()
33{
34    LOGI("AdvertiseManager destructor.");
35}
36
37int32_t AdvertiseManager::StartAdvertising(const std::string &pkgName,
38    const std::map<std::string, std::string> &advertiseParam)
39{
40    LOGI("AdvertiseManager::StartAdvertising begin for pkgName = %{public}s.", pkgName.c_str());
41    if (pkgName.empty()) {
42        LOGE("Invalid parameter, pkgName is empty.");
43        return ERR_DM_INPUT_PARA_INVALID;
44    }
45    DmPublishInfo dmPubInfo;
46    ConfigAdvParam(advertiseParam, &dmPubInfo);
47    std::string capability = DM_CAPABILITY_OSD;
48    if (advertiseParam.find(PARAM_KEY_DISC_CAPABILITY) != advertiseParam.end()) {
49        capability = advertiseParam.find(PARAM_KEY_DISC_CAPABILITY)->second;
50    }
51    if (capability == DM_CAPABILITY_APPROACH || capability == DM_CAPABILITY_TOUCH) {
52        dmPubInfo.mode = DmDiscoverMode::DM_DISCOVER_MODE_ACTIVE;
53    }
54    std::string customData = "";
55    if (advertiseParam.find(PARAM_KEY_CUSTOM_DATA) != advertiseParam.end()) {
56        customData = advertiseParam.find(PARAM_KEY_CUSTOM_DATA)->second;
57    }
58
59    int32_t ret = softbusListener_->PublishSoftbusLNN(dmPubInfo, capability, customData);
60    if (ret != DM_OK) {
61        LOGE("StartAdvertising failed, softbus publish lnn ret: %{public}d", ret);
62        return ret;
63    }
64
65    if (advertiseParam.find(PARAM_KEY_AUTO_STOP_ADVERTISE) != advertiseParam.end()) {
66        int32_t stopTime = std::atoi((advertiseParam.find(PARAM_KEY_AUTO_STOP_ADVERTISE)->second).c_str());
67        if ((stopTime <= 0) || (stopTime > AUTO_STOP_ADVERTISE_DEFAULT_TIME)) {
68            LOGE("StartAdvertising error, invalid input auto stop advertise time: %{public}d", stopTime);
69            return DM_OK;
70        }
71        if (timer_ == nullptr) {
72            timer_ = std::make_shared<DmTimer>();
73        }
74        int32_t publishId = dmPubInfo.publishId;
75        timer_->StartTimer(std::string(AUTO_STOP_ADVERTISE_TASK), stopTime,
76            [this, pkgName, publishId] (std::string name) {
77                AdvertiseManager::HandleAutoStopAdvertise(name, pkgName, publishId);
78            });
79    }
80    return DM_OK;
81}
82
83void AdvertiseManager::ConfigAdvParam(const std::map<std::string, std::string> &advertiseParam,
84    DmPublishInfo *dmPubInfo)
85{
86    if (dmPubInfo == nullptr) {
87        LOGE("ConfigAdvParam failed, dmPubInfo is nullptr.");
88        return;
89    }
90    dmPubInfo->publishId = -1;
91    dmPubInfo->mode = DmDiscoverMode::DM_DISCOVER_MODE_PASSIVE;
92    dmPubInfo->freq = DmExchangeFreq::DM_LOW;
93    dmPubInfo->ranging = true;
94
95    if (advertiseParam.find(PARAM_KEY_META_TYPE) != advertiseParam.end()) {
96        LOGI("StartAdvertising input MetaType=%{public}s", (advertiseParam.find(PARAM_KEY_META_TYPE)->second).c_str());
97    }
98    if (advertiseParam.find(PARAM_KEY_PUBLISH_ID) != advertiseParam.end()) {
99        dmPubInfo->publishId = std::atoi((advertiseParam.find(PARAM_KEY_PUBLISH_ID)->second).c_str());
100    }
101    if (advertiseParam.find(PARAM_KEY_DISC_MODE) != advertiseParam.end()) {
102        dmPubInfo->mode =
103            static_cast<DmDiscoverMode>(std::atoi((advertiseParam.find(PARAM_KEY_DISC_MODE)->second).c_str()));
104    }
105    if (advertiseParam.find(PARAM_KEY_DISC_FREQ) != advertiseParam.end()) {
106        dmPubInfo->freq =
107            static_cast<DmExchangeFreq>(std::atoi((advertiseParam.find(PARAM_KEY_DISC_FREQ)->second).c_str()));
108    }
109}
110
111int32_t AdvertiseManager::StopAdvertising(const std::string &pkgName, int32_t publishId)
112{
113    LOGI("AdvertiseManager::StopDiscovering begin for pkgName = %{public}s.", pkgName.c_str());
114    if (pkgName.empty()) {
115        LOGE("Invalid parameter, pkgName is empty.");
116        return ERR_DM_INPUT_PARA_INVALID;
117    }
118    return softbusListener_->StopPublishSoftbusLNN(publishId);
119}
120
121void AdvertiseManager::HandleAutoStopAdvertise(const std::string &timerName, const std::string &pkgName,
122    int32_t publishId)
123{
124    LOGI("HandleAutoStopAdvertise, auto stop advertise task timeout, timerName=%{public}s", timerName.c_str());
125    StopAdvertising(pkgName, publishId);
126}
127} // namespace DistributedHardware
128} // namespace OHOS
129