106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci
1606f6ba60Sopenharmony_ci#include "plugin_module.h"
1706f6ba60Sopenharmony_ci
1806f6ba60Sopenharmony_ci#include <dlfcn.h>
1906f6ba60Sopenharmony_ci#include <iostream>
2006f6ba60Sopenharmony_ci
2106f6ba60Sopenharmony_ci#include "logging.h"
2206f6ba60Sopenharmony_ci#include "plugin_module_api.h"
2306f6ba60Sopenharmony_ci
2406f6ba60Sopenharmony_ciPluginModule::PluginModule(const std::string& path)
2506f6ba60Sopenharmony_ci    : handle_(nullptr), running_(false), path_(path), structPtr_(nullptr) {}
2606f6ba60Sopenharmony_ci
2706f6ba60Sopenharmony_ciPluginModule::~PluginModule() {}
2806f6ba60Sopenharmony_ci
2906f6ba60Sopenharmony_cistd::string PluginModule::ComputeSha256()
3006f6ba60Sopenharmony_ci{
3106f6ba60Sopenharmony_ci    return "";
3206f6ba60Sopenharmony_ci}
3306f6ba60Sopenharmony_ci
3406f6ba60Sopenharmony_cibool PluginModule::Load()
3506f6ba60Sopenharmony_ci{
3606f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
3706f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "%s:already open", __func__);
3806f6ba60Sopenharmony_ci        return false;
3906f6ba60Sopenharmony_ci    }
4006f6ba60Sopenharmony_ci
4106f6ba60Sopenharmony_ci    handle_ = dlopen(path_.c_str(), RTLD_NODELETE);
4206f6ba60Sopenharmony_ci    if (handle_ == nullptr) {
4306f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "%s:dlopen err:%s.", __func__, dlerror());
4406f6ba60Sopenharmony_ci        return false;
4506f6ba60Sopenharmony_ci    }
4606f6ba60Sopenharmony_ci    return true;
4706f6ba60Sopenharmony_ci}
4806f6ba60Sopenharmony_ci
4906f6ba60Sopenharmony_cibool PluginModule::Unload()
5006f6ba60Sopenharmony_ci{
5106f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "%s:unload ready!", __func__);
5206f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
5306f6ba60Sopenharmony_ci        int ret = dlclose(handle_);
5406f6ba60Sopenharmony_ci        PROFILER_LOG_INFO(LOG_CORE, "%s:unload plugin ret = %d", __func__, ret);
5506f6ba60Sopenharmony_ci        handle_ = nullptr;
5606f6ba60Sopenharmony_ci        structPtr_ = nullptr;
5706f6ba60Sopenharmony_ci        return true;
5806f6ba60Sopenharmony_ci    }
5906f6ba60Sopenharmony_ci
6006f6ba60Sopenharmony_ci    return false;
6106f6ba60Sopenharmony_ci}
6206f6ba60Sopenharmony_ci
6306f6ba60Sopenharmony_cibool PluginModule::GetInfo(PluginModuleInfo& info)
6406f6ba60Sopenharmony_ci{
6506f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
6606f6ba60Sopenharmony_ci        if (structPtr_ == nullptr) {
6706f6ba60Sopenharmony_ci            return false;
6806f6ba60Sopenharmony_ci        }
6906f6ba60Sopenharmony_ci        info.bufferSizeHint = structPtr_->resultBufferSizeHint;
7006f6ba60Sopenharmony_ci        info.name.assign(structPtr_->name);
7106f6ba60Sopenharmony_ci        info.isStandaloneFileData = structPtr_->isStandaloneFileData;
7206f6ba60Sopenharmony_ci        info.outFileName.assign(structPtr_->outFileName);
7306f6ba60Sopenharmony_ci        info.pluginVersion.assign(structPtr_->version);
7406f6ba60Sopenharmony_ci        return true;
7506f6ba60Sopenharmony_ci    }
7606f6ba60Sopenharmony_ci    return false;
7706f6ba60Sopenharmony_ci}
7806f6ba60Sopenharmony_ci
7906f6ba60Sopenharmony_ciPluginModule::SampleMode PluginModule::GetSampleMode() const
8006f6ba60Sopenharmony_ci{
8106f6ba60Sopenharmony_ci    if (structPtr_ && structPtr_->callbacks) {
8206f6ba60Sopenharmony_ci        if (structPtr_->callbacks->onPluginReportResult != nullptr) {
8306f6ba60Sopenharmony_ci            return SampleMode::POLLING;
8406f6ba60Sopenharmony_ci        } else if (structPtr_->callbacks->onRegisterWriterStruct != nullptr) {
8506f6ba60Sopenharmony_ci            return SampleMode::STREAMING;
8606f6ba60Sopenharmony_ci        }
8706f6ba60Sopenharmony_ci    }
8806f6ba60Sopenharmony_ci    return SampleMode::UNKNOWN;
8906f6ba60Sopenharmony_ci}
9006f6ba60Sopenharmony_ci
9106f6ba60Sopenharmony_civoid PluginModule::SetConfigData(const std::string& data)
9206f6ba60Sopenharmony_ci{
9306f6ba60Sopenharmony_ci    configData_ = data;
9406f6ba60Sopenharmony_ci}
9506f6ba60Sopenharmony_ci
9606f6ba60Sopenharmony_cistd::string PluginModule::GetConfigData() const
9706f6ba60Sopenharmony_ci{
9806f6ba60Sopenharmony_ci    return configData_;
9906f6ba60Sopenharmony_ci}
10006f6ba60Sopenharmony_ci
10106f6ba60Sopenharmony_civoid PluginModule::SetClockId(clockid_t clockId)
10206f6ba60Sopenharmony_ci{
10306f6ba60Sopenharmony_ci    clockId_ = clockId;
10406f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "SetClockId: plugin=%s, clock=%d", GetPluginName().c_str(), clockId);
10506f6ba60Sopenharmony_ci    if (writerAdapter_ != nullptr && writerAdapter_->GetWriter() != nullptr) {
10606f6ba60Sopenharmony_ci        writerAdapter_->GetWriter()->SetClockId(clockId);
10706f6ba60Sopenharmony_ci    }
10806f6ba60Sopenharmony_ci}
10906f6ba60Sopenharmony_ci
11006f6ba60Sopenharmony_ciclockid_t PluginModule::GetClockId() const
11106f6ba60Sopenharmony_ci{
11206f6ba60Sopenharmony_ci    return clockId_;
11306f6ba60Sopenharmony_ci}
11406f6ba60Sopenharmony_ci
11506f6ba60Sopenharmony_cibool PluginModule::GetPluginName(std::string& pluginName)
11606f6ba60Sopenharmony_ci{
11706f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
11806f6ba60Sopenharmony_ci        CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr");
11906f6ba60Sopenharmony_ci        pluginName.assign(structPtr_->name);
12006f6ba60Sopenharmony_ci        return true;
12106f6ba60Sopenharmony_ci    }
12206f6ba60Sopenharmony_ci    return false;
12306f6ba60Sopenharmony_ci}
12406f6ba60Sopenharmony_ci
12506f6ba60Sopenharmony_cibool PluginModule::GetBufferSizeHint(uint32_t& bufferSizeHint)
12606f6ba60Sopenharmony_ci{
12706f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
12806f6ba60Sopenharmony_ci        CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr");
12906f6ba60Sopenharmony_ci        bufferSizeHint = structPtr_->resultBufferSizeHint;
13006f6ba60Sopenharmony_ci        return true;
13106f6ba60Sopenharmony_ci    }
13206f6ba60Sopenharmony_ci    return false;
13306f6ba60Sopenharmony_ci}
13406f6ba60Sopenharmony_ci
13506f6ba60Sopenharmony_cibool PluginModule::GetStandaloneFileData()
13606f6ba60Sopenharmony_ci{
13706f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
13806f6ba60Sopenharmony_ci        CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr");
13906f6ba60Sopenharmony_ci        return structPtr_->isStandaloneFileData;
14006f6ba60Sopenharmony_ci    }
14106f6ba60Sopenharmony_ci    return false;
14206f6ba60Sopenharmony_ci}
14306f6ba60Sopenharmony_ci
14406f6ba60Sopenharmony_cibool PluginModule::GetOutFileName(std::string& outFileName)
14506f6ba60Sopenharmony_ci{
14606f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
14706f6ba60Sopenharmony_ci        CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr");
14806f6ba60Sopenharmony_ci        outFileName.assign(structPtr_->outFileName);
14906f6ba60Sopenharmony_ci        return true;
15006f6ba60Sopenharmony_ci    }
15106f6ba60Sopenharmony_ci    return false;
15206f6ba60Sopenharmony_ci}
15306f6ba60Sopenharmony_ci
15406f6ba60Sopenharmony_cibool PluginModule::GetPluginVersion(std::string& pluginVersion)
15506f6ba60Sopenharmony_ci{
15606f6ba60Sopenharmony_ci    if (handle_ != nullptr) {
15706f6ba60Sopenharmony_ci        if (structPtr_ == nullptr) {
15806f6ba60Sopenharmony_ci            return false;
15906f6ba60Sopenharmony_ci        }
16006f6ba60Sopenharmony_ci        pluginVersion.assign(structPtr_->version);
16106f6ba60Sopenharmony_ci        return true;
16206f6ba60Sopenharmony_ci    }
16306f6ba60Sopenharmony_ci    return false;
16406f6ba60Sopenharmony_ci}
16506f6ba60Sopenharmony_ci
16606f6ba60Sopenharmony_cistd::string PluginModule::GetPath()
16706f6ba60Sopenharmony_ci{
16806f6ba60Sopenharmony_ci    return path_;
16906f6ba60Sopenharmony_ci}
17006f6ba60Sopenharmony_ci
17106f6ba60Sopenharmony_cistd::string PluginModule::GetPluginName()
17206f6ba60Sopenharmony_ci{
17306f6ba60Sopenharmony_ci    if (pluginName_ == "") {
17406f6ba60Sopenharmony_ci        if (handle_ != nullptr) {
17506f6ba60Sopenharmony_ci            CHECK_NOTNULL(structPtr_, "", "structPtr_ is nullptr");
17606f6ba60Sopenharmony_ci            pluginName_.assign(structPtr_->name);
17706f6ba60Sopenharmony_ci        }
17806f6ba60Sopenharmony_ci    }
17906f6ba60Sopenharmony_ci    return pluginName_;
18006f6ba60Sopenharmony_ci}
18106f6ba60Sopenharmony_ci
18206f6ba60Sopenharmony_cibool PluginModule::IsLoaded()
18306f6ba60Sopenharmony_ci{
18406f6ba60Sopenharmony_ci    return (handle_ != nullptr);
18506f6ba60Sopenharmony_ci}
18606f6ba60Sopenharmony_ci
18706f6ba60Sopenharmony_cibool PluginModule::IsRunning()
18806f6ba60Sopenharmony_ci{
18906f6ba60Sopenharmony_ci    return running_;
19006f6ba60Sopenharmony_ci}
19106f6ba60Sopenharmony_ci
19206f6ba60Sopenharmony_cibool PluginModule::BindFunctions()
19306f6ba60Sopenharmony_ci{
19406f6ba60Sopenharmony_ci    CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__);
19506f6ba60Sopenharmony_ci    if (structPtr_ == nullptr) {
19606f6ba60Sopenharmony_ci        structPtr_ = static_cast<PluginModuleStruct*>(dlsym(handle_, "g_pluginModule"));
19706f6ba60Sopenharmony_ci        if (structPtr_ == nullptr) {
19806f6ba60Sopenharmony_ci            PROFILER_LOG_DEBUG(LOG_CORE, "%s:structPtr_ == nullptr", __func__);
19906f6ba60Sopenharmony_ci            return false;
20006f6ba60Sopenharmony_ci        }
20106f6ba60Sopenharmony_ci    }
20206f6ba60Sopenharmony_ci
20306f6ba60Sopenharmony_ci    if (structPtr_->callbacks == nullptr) {
20406f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "%s:structPtr_->callbacks == nullptr", __func__);
20506f6ba60Sopenharmony_ci        return false;
20606f6ba60Sopenharmony_ci    }
20706f6ba60Sopenharmony_ci
20806f6ba60Sopenharmony_ci    if ((structPtr_->callbacks->onPluginSessionStart == nullptr) ||
20906f6ba60Sopenharmony_ci        (structPtr_->callbacks->onPluginSessionStop == nullptr)) {
21006f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "%s:onPluginSessionStart == nullptr", __func__);
21106f6ba60Sopenharmony_ci        return false;
21206f6ba60Sopenharmony_ci    }
21306f6ba60Sopenharmony_ci
21406f6ba60Sopenharmony_ci    return true;
21506f6ba60Sopenharmony_ci}
21606f6ba60Sopenharmony_ci
21706f6ba60Sopenharmony_cibool PluginModule::StartSession(const uint8_t* buffer, uint32_t size)
21806f6ba60Sopenharmony_ci{
21906f6ba60Sopenharmony_ci    PROFILER_LOG_DEBUG(LOG_CORE, "StartSession");
22006f6ba60Sopenharmony_ci    CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__);
22106f6ba60Sopenharmony_ci    if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
22206f6ba60Sopenharmony_ci        if (structPtr_->callbacks->onPluginSessionStart) {
22306f6ba60Sopenharmony_ci            running_ = true;
22406f6ba60Sopenharmony_ci            return (structPtr_->callbacks->onPluginSessionStart(buffer, size) == 0);
22506f6ba60Sopenharmony_ci        }
22606f6ba60Sopenharmony_ci    }
22706f6ba60Sopenharmony_ci    return false;
22806f6ba60Sopenharmony_ci}
22906f6ba60Sopenharmony_ci
23006f6ba60Sopenharmony_cibool PluginModule::StopSession()
23106f6ba60Sopenharmony_ci{
23206f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "%s:stop Session ready!", __func__);
23306f6ba60Sopenharmony_ci    CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__);
23406f6ba60Sopenharmony_ci    if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
23506f6ba60Sopenharmony_ci        if (structPtr_->callbacks->onPluginSessionStop != nullptr) {
23606f6ba60Sopenharmony_ci            running_ = false;
23706f6ba60Sopenharmony_ci            return (structPtr_->callbacks->onPluginSessionStop() == 0);
23806f6ba60Sopenharmony_ci        }
23906f6ba60Sopenharmony_ci    }
24006f6ba60Sopenharmony_ci    return false;
24106f6ba60Sopenharmony_ci}
24206f6ba60Sopenharmony_ci
24306f6ba60Sopenharmony_cibool PluginModule::ReportBasicData()
24406f6ba60Sopenharmony_ci{
24506f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "%s:report basic data ready!", __func__);
24606f6ba60Sopenharmony_ci    CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__);
24706f6ba60Sopenharmony_ci    if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
24806f6ba60Sopenharmony_ci        if (structPtr_->callbacks->onReportBasicDataCallback != nullptr) {
24906f6ba60Sopenharmony_ci            return (structPtr_->callbacks->onReportBasicDataCallback() == 0);
25006f6ba60Sopenharmony_ci        }
25106f6ba60Sopenharmony_ci    }
25206f6ba60Sopenharmony_ci    return false;
25306f6ba60Sopenharmony_ci}
25406f6ba60Sopenharmony_ci
25506f6ba60Sopenharmony_ciint32_t PluginModule::ReportResult(uint8_t* buffer, uint32_t size)
25606f6ba60Sopenharmony_ci{
25706f6ba60Sopenharmony_ci    CHECK_NOTNULL(handle_, -1, "%s:plugin not load", __func__);
25806f6ba60Sopenharmony_ci    if (first_) {
25906f6ba60Sopenharmony_ci        lastTime_ = std::chrono::steady_clock::now();
26006f6ba60Sopenharmony_ci        first_ = false;
26106f6ba60Sopenharmony_ci    } else {
26206f6ba60Sopenharmony_ci        std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
26306f6ba60Sopenharmony_ci        lastTime_ = t1;
26406f6ba60Sopenharmony_ci    }
26506f6ba60Sopenharmony_ci
26606f6ba60Sopenharmony_ci    if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
26706f6ba60Sopenharmony_ci        if (structPtr_->callbacks->onPluginReportResult != nullptr) {
26806f6ba60Sopenharmony_ci            return structPtr_->callbacks->onPluginReportResult(buffer, size);
26906f6ba60Sopenharmony_ci        }
27006f6ba60Sopenharmony_ci    }
27106f6ba60Sopenharmony_ci
27206f6ba60Sopenharmony_ci    return -1;
27306f6ba60Sopenharmony_ci}
27406f6ba60Sopenharmony_ci
27506f6ba60Sopenharmony_ciPluginReportResultOptimizeCallback PluginModule::ReportResultOptimize()
27606f6ba60Sopenharmony_ci{
27706f6ba60Sopenharmony_ci    CHECK_NOTNULL(handle_, nullptr, "%s:plugin not open", __func__);
27806f6ba60Sopenharmony_ci    if (first_) {
27906f6ba60Sopenharmony_ci        lastTime_ = std::chrono::steady_clock::now();
28006f6ba60Sopenharmony_ci        first_ = false;
28106f6ba60Sopenharmony_ci    } else {
28206f6ba60Sopenharmony_ci        std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
28306f6ba60Sopenharmony_ci        lastTime_ = t1;
28406f6ba60Sopenharmony_ci    }
28506f6ba60Sopenharmony_ci
28606f6ba60Sopenharmony_ci    if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
28706f6ba60Sopenharmony_ci        if (structPtr_->callbacks->onPluginReportResultOptimize != nullptr) {
28806f6ba60Sopenharmony_ci            return structPtr_->callbacks->onPluginReportResultOptimize;
28906f6ba60Sopenharmony_ci        }
29006f6ba60Sopenharmony_ci    }
29106f6ba60Sopenharmony_ci
29206f6ba60Sopenharmony_ci    return nullptr;
29306f6ba60Sopenharmony_ci}
29406f6ba60Sopenharmony_ci
29506f6ba60Sopenharmony_cibool PluginModule::RegisterWriter(const BufferWriterPtr writer, bool isProtobufSerialize)
29606f6ba60Sopenharmony_ci{
29706f6ba60Sopenharmony_ci    isProtobufSerialize_ = isProtobufSerialize;
29806f6ba60Sopenharmony_ci    writerAdapter_ = std::make_shared<WriterAdapter>(isProtobufSerialize);
29906f6ba60Sopenharmony_ci    writerAdapter_->SetWriter(writer);
30006f6ba60Sopenharmony_ci    CHECK_NOTNULL(writer, true, "%s:bufferWriter is null, update WriterAdapter only!", __func__);
30106f6ba60Sopenharmony_ci    if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) {
30206f6ba60Sopenharmony_ci        if (structPtr_->callbacks->onRegisterWriterStruct != nullptr) {
30306f6ba60Sopenharmony_ci            return structPtr_->callbacks->onRegisterWriterStruct(writerAdapter_->GetStruct());
30406f6ba60Sopenharmony_ci        }
30506f6ba60Sopenharmony_ci    }
30606f6ba60Sopenharmony_ci    return true;
30706f6ba60Sopenharmony_ci}
30806f6ba60Sopenharmony_ci
30906f6ba60Sopenharmony_ciWriterPtr PluginModule::GetWriter()
31006f6ba60Sopenharmony_ci{
31106f6ba60Sopenharmony_ci    CHECK_NOTNULL(writerAdapter_, nullptr, "%s:pluginModule nullptr", __func__);
31206f6ba60Sopenharmony_ci    return writerAdapter_->GetWriter();
31306f6ba60Sopenharmony_ci}
314