1/* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved. 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 "plugin_module.h" 17 18#include <dlfcn.h> 19#include <iostream> 20 21#include "logging.h" 22#include "plugin_module_api.h" 23 24PluginModule::PluginModule(const std::string& path) 25 : handle_(nullptr), running_(false), path_(path), structPtr_(nullptr) {} 26 27PluginModule::~PluginModule() {} 28 29std::string PluginModule::ComputeSha256() 30{ 31 return ""; 32} 33 34bool PluginModule::Load() 35{ 36 if (handle_ != nullptr) { 37 PROFILER_LOG_DEBUG(LOG_CORE, "%s:already open", __func__); 38 return false; 39 } 40 41 handle_ = dlopen(path_.c_str(), RTLD_NODELETE); 42 if (handle_ == nullptr) { 43 PROFILER_LOG_DEBUG(LOG_CORE, "%s:dlopen err:%s.", __func__, dlerror()); 44 return false; 45 } 46 return true; 47} 48 49bool PluginModule::Unload() 50{ 51 PROFILER_LOG_INFO(LOG_CORE, "%s:unload ready!", __func__); 52 if (handle_ != nullptr) { 53 int ret = dlclose(handle_); 54 PROFILER_LOG_INFO(LOG_CORE, "%s:unload plugin ret = %d", __func__, ret); 55 handle_ = nullptr; 56 structPtr_ = nullptr; 57 return true; 58 } 59 60 return false; 61} 62 63bool PluginModule::GetInfo(PluginModuleInfo& info) 64{ 65 if (handle_ != nullptr) { 66 if (structPtr_ == nullptr) { 67 return false; 68 } 69 info.bufferSizeHint = structPtr_->resultBufferSizeHint; 70 info.name.assign(structPtr_->name); 71 info.isStandaloneFileData = structPtr_->isStandaloneFileData; 72 info.outFileName.assign(structPtr_->outFileName); 73 info.pluginVersion.assign(structPtr_->version); 74 return true; 75 } 76 return false; 77} 78 79PluginModule::SampleMode PluginModule::GetSampleMode() const 80{ 81 if (structPtr_ && structPtr_->callbacks) { 82 if (structPtr_->callbacks->onPluginReportResult != nullptr) { 83 return SampleMode::POLLING; 84 } else if (structPtr_->callbacks->onRegisterWriterStruct != nullptr) { 85 return SampleMode::STREAMING; 86 } 87 } 88 return SampleMode::UNKNOWN; 89} 90 91void PluginModule::SetConfigData(const std::string& data) 92{ 93 configData_ = data; 94} 95 96std::string PluginModule::GetConfigData() const 97{ 98 return configData_; 99} 100 101void PluginModule::SetClockId(clockid_t clockId) 102{ 103 clockId_ = clockId; 104 PROFILER_LOG_INFO(LOG_CORE, "SetClockId: plugin=%s, clock=%d", GetPluginName().c_str(), clockId); 105 if (writerAdapter_ != nullptr && writerAdapter_->GetWriter() != nullptr) { 106 writerAdapter_->GetWriter()->SetClockId(clockId); 107 } 108} 109 110clockid_t PluginModule::GetClockId() const 111{ 112 return clockId_; 113} 114 115bool PluginModule::GetPluginName(std::string& pluginName) 116{ 117 if (handle_ != nullptr) { 118 CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr"); 119 pluginName.assign(structPtr_->name); 120 return true; 121 } 122 return false; 123} 124 125bool PluginModule::GetBufferSizeHint(uint32_t& bufferSizeHint) 126{ 127 if (handle_ != nullptr) { 128 CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr"); 129 bufferSizeHint = structPtr_->resultBufferSizeHint; 130 return true; 131 } 132 return false; 133} 134 135bool PluginModule::GetStandaloneFileData() 136{ 137 if (handle_ != nullptr) { 138 CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr"); 139 return structPtr_->isStandaloneFileData; 140 } 141 return false; 142} 143 144bool PluginModule::GetOutFileName(std::string& outFileName) 145{ 146 if (handle_ != nullptr) { 147 CHECK_NOTNULL(structPtr_, false, "structPtr_ is nullptr"); 148 outFileName.assign(structPtr_->outFileName); 149 return true; 150 } 151 return false; 152} 153 154bool PluginModule::GetPluginVersion(std::string& pluginVersion) 155{ 156 if (handle_ != nullptr) { 157 if (structPtr_ == nullptr) { 158 return false; 159 } 160 pluginVersion.assign(structPtr_->version); 161 return true; 162 } 163 return false; 164} 165 166std::string PluginModule::GetPath() 167{ 168 return path_; 169} 170 171std::string PluginModule::GetPluginName() 172{ 173 if (pluginName_ == "") { 174 if (handle_ != nullptr) { 175 CHECK_NOTNULL(structPtr_, "", "structPtr_ is nullptr"); 176 pluginName_.assign(structPtr_->name); 177 } 178 } 179 return pluginName_; 180} 181 182bool PluginModule::IsLoaded() 183{ 184 return (handle_ != nullptr); 185} 186 187bool PluginModule::IsRunning() 188{ 189 return running_; 190} 191 192bool PluginModule::BindFunctions() 193{ 194 CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__); 195 if (structPtr_ == nullptr) { 196 structPtr_ = static_cast<PluginModuleStruct*>(dlsym(handle_, "g_pluginModule")); 197 if (structPtr_ == nullptr) { 198 PROFILER_LOG_DEBUG(LOG_CORE, "%s:structPtr_ == nullptr", __func__); 199 return false; 200 } 201 } 202 203 if (structPtr_->callbacks == nullptr) { 204 PROFILER_LOG_DEBUG(LOG_CORE, "%s:structPtr_->callbacks == nullptr", __func__); 205 return false; 206 } 207 208 if ((structPtr_->callbacks->onPluginSessionStart == nullptr) || 209 (structPtr_->callbacks->onPluginSessionStop == nullptr)) { 210 PROFILER_LOG_DEBUG(LOG_CORE, "%s:onPluginSessionStart == nullptr", __func__); 211 return false; 212 } 213 214 return true; 215} 216 217bool PluginModule::StartSession(const uint8_t* buffer, uint32_t size) 218{ 219 PROFILER_LOG_DEBUG(LOG_CORE, "StartSession"); 220 CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__); 221 if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) { 222 if (structPtr_->callbacks->onPluginSessionStart) { 223 running_ = true; 224 return (structPtr_->callbacks->onPluginSessionStart(buffer, size) == 0); 225 } 226 } 227 return false; 228} 229 230bool PluginModule::StopSession() 231{ 232 PROFILER_LOG_INFO(LOG_CORE, "%s:stop Session ready!", __func__); 233 CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__); 234 if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) { 235 if (structPtr_->callbacks->onPluginSessionStop != nullptr) { 236 running_ = false; 237 return (structPtr_->callbacks->onPluginSessionStop() == 0); 238 } 239 } 240 return false; 241} 242 243bool PluginModule::ReportBasicData() 244{ 245 PROFILER_LOG_INFO(LOG_CORE, "%s:report basic data ready!", __func__); 246 CHECK_NOTNULL(handle_, false, "%s:plugin not load", __func__); 247 if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) { 248 if (structPtr_->callbacks->onReportBasicDataCallback != nullptr) { 249 return (structPtr_->callbacks->onReportBasicDataCallback() == 0); 250 } 251 } 252 return false; 253} 254 255int32_t PluginModule::ReportResult(uint8_t* buffer, uint32_t size) 256{ 257 CHECK_NOTNULL(handle_, -1, "%s:plugin not load", __func__); 258 if (first_) { 259 lastTime_ = std::chrono::steady_clock::now(); 260 first_ = false; 261 } else { 262 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); 263 lastTime_ = t1; 264 } 265 266 if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) { 267 if (structPtr_->callbacks->onPluginReportResult != nullptr) { 268 return structPtr_->callbacks->onPluginReportResult(buffer, size); 269 } 270 } 271 272 return -1; 273} 274 275PluginReportResultOptimizeCallback PluginModule::ReportResultOptimize() 276{ 277 CHECK_NOTNULL(handle_, nullptr, "%s:plugin not open", __func__); 278 if (first_) { 279 lastTime_ = std::chrono::steady_clock::now(); 280 first_ = false; 281 } else { 282 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); 283 lastTime_ = t1; 284 } 285 286 if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) { 287 if (structPtr_->callbacks->onPluginReportResultOptimize != nullptr) { 288 return structPtr_->callbacks->onPluginReportResultOptimize; 289 } 290 } 291 292 return nullptr; 293} 294 295bool PluginModule::RegisterWriter(const BufferWriterPtr writer, bool isProtobufSerialize) 296{ 297 isProtobufSerialize_ = isProtobufSerialize; 298 writerAdapter_ = std::make_shared<WriterAdapter>(isProtobufSerialize); 299 writerAdapter_->SetWriter(writer); 300 CHECK_NOTNULL(writer, true, "%s:bufferWriter is null, update WriterAdapter only!", __func__); 301 if (structPtr_ != nullptr && structPtr_->callbacks != nullptr) { 302 if (structPtr_->callbacks->onRegisterWriterStruct != nullptr) { 303 return structPtr_->callbacks->onRegisterWriterStruct(writerAdapter_->GetStruct()); 304 } 305 } 306 return true; 307} 308 309WriterPtr PluginModule::GetWriter() 310{ 311 CHECK_NOTNULL(writerAdapter_, nullptr, "%s:pluginModule nullptr", __func__); 312 return writerAdapter_->GetWriter(); 313} 314