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     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 
Unload()49 bool 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 
GetInfo(PluginModuleInfo& info)63 bool 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 
GetSampleMode() const79 PluginModule::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 
SetConfigData(const std::string& data)91 void PluginModule::SetConfigData(const std::string& data)
92 {
93     configData_ = data;
94 }
95 
GetConfigData() const96 std::string PluginModule::GetConfigData() const
97 {
98     return configData_;
99 }
100 
SetClockId(clockid_t clockId)101 void 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 
GetClockId() const110 clockid_t PluginModule::GetClockId() const
111 {
112     return clockId_;
113 }
114 
GetPluginName(std::string& pluginName)115 bool 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 
GetBufferSizeHint(uint32_t& bufferSizeHint)125 bool 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 
GetStandaloneFileData()135 bool 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 
GetOutFileName(std::string& outFileName)144 bool 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 
GetPluginVersion(std::string& pluginVersion)154 bool 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 
GetPath()166 std::string PluginModule::GetPath()
167 {
168     return path_;
169 }
170 
GetPluginName()171 std::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 
IsLoaded()182 bool PluginModule::IsLoaded()
183 {
184     return (handle_ != nullptr);
185 }
186 
IsRunning()187 bool PluginModule::IsRunning()
188 {
189     return running_;
190 }
191 
BindFunctions()192 bool 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 
StartSession(const uint8_t* buffer, uint32_t size)217 bool 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 
StopSession()230 bool 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 
ReportBasicData()243 bool 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 
ReportResult(uint8_t* buffer, uint32_t size)255 int32_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 
ReportResultOptimize()275 PluginReportResultOptimizeCallback 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 
RegisterWriter(const BufferWriterPtr writer, bool isProtobufSerialize)295 bool 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 
GetWriter()309 WriterPtr PluginModule::GetWriter()
310 {
311     CHECK_NOTNULL(writerAdapter_, nullptr, "%s:pluginModule nullptr", __func__);
312     return writerAdapter_->GetWriter();
313 }
314