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