UniSet @VERSION@
OPCUAServer.h
1/*
2 * Copyright (c) 2023 Pavel Vainerman.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation, version 2.1.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Lesser Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16// -----------------------------------------------------------------------------
17#ifndef _OPCUAServer_H_
18#define _OPCUAServer_H_
19// -----------------------------------------------------------------------------
20#include <memory>
21#include <atomic>
22#include <regex>
23#include <optional>
24#include <unordered_map>
25#include "open62541pp/open62541pp.hpp"
26#include "UObject_SK.h"
27#include "SMInterface.h"
28#include "SharedMemory.h"
29#include "ThreadCreator.h"
30#include "Extensions.h"
31#include "USingleProcess.h"
32#include "LogServer.h"
33// --------------------------------------------------------------------------
34namespace uniset
35{
36 // -----------------------------------------------------------------------------
166 // -----------------------------------------------------------------------------
169 private USingleProcess,
170 public UObject_SK
171 {
172 public:
173 OPCUAServer(uniset::ObjectId objId, xmlNode* cnode, uniset::ObjectId shmID,
174 const std::shared_ptr<SharedMemory>& ic = nullptr,
175 const std::string& prefix = "opcua");
176
177 virtual ~OPCUAServer();
178
179 virtual CORBA::Boolean exist() override;
180
182 static std::shared_ptr<OPCUAServer> init_opcua_server(int argc, const char* const* argv,
183 uniset::ObjectId shmID,
184 const std::shared_ptr<SharedMemory>& ic = nullptr,
185 const std::string& prefix = "opcua");
186
188 static void help_print();
189
190 using DefaultValueType = int32_t;
191 using DefaultValueUType = uint32_t;
192 static const opcua::DataTypeId DefaultVariableType = { opcua::DataTypeId::Int32 };
193
194 static uint8_t firstBit( DefaultValueUType mask );
195 // offset = firstBit(mask)
196 static DefaultValueUType getBits( DefaultValueUType value, DefaultValueUType mask, uint8_t offset );
197 // if mask = 0 return value
198 static DefaultValueUType setBits( DefaultValueUType value, DefaultValueUType set, DefaultValueUType mask, uint8_t offset );
199 // if mask=0 return set
200 static DefaultValueUType forceSetBits( DefaultValueUType value, DefaultValueUType set, DefaultValueUType mask, uint8_t offset );
201
202 static UA_StatusCode UA_setValueMethod(UA_Server* server, const UA_NodeId* sessionId, void* sessionHandle,
203 const UA_NodeId* methodId, void* methodContext, const UA_NodeId* objectId,
204 void* objectContext, size_t inputSize, const UA_Variant* input, size_t outputSize, UA_Variant* output);
205
206#ifndef DISABLE_REST_API
207 // HTTP API
208 virtual Poco::JSON::Object::Ptr httpHelp( const Poco::URI::QueryParameters& p ) override;
209 virtual Poco::JSON::Object::Ptr httpRequest( const UHttp::HttpRequestContext& ctx ) override;
210 virtual Poco::JSON::Object::Ptr httpGetMyInfo( Poco::JSON::Object::Ptr root ) override;
211
212 // Public HTTP endpoints
213 Poco::JSON::Object::Ptr httpSensors( const Poco::URI::QueryParameters& p );
214 Poco::JSON::Object::Ptr httpGet( const Poco::URI::QueryParameters& p );
215#endif
216
217 protected:
218 OPCUAServer();
219
220 virtual void callback() noexcept override;
221 virtual void sysCommand(const uniset::SystemMessage* sm) override;
222 virtual bool deactivateObject() override;
223 virtual void askSensors(UniversalIO::UIOCommand cmd) override;
224 virtual void sensorInfo(const uniset::SensorMessage* sm) override;
225 virtual std::string getMonitInfo() const override;
226 void serverLoopTerminate();
227 void serverLoop();
228 void updateLoop();
229 void update();
230
231#ifndef DISABLE_REST_API
232 // params
233 virtual Poco::JSON::Object::Ptr httpGetParam( const Poco::URI::QueryParameters& p );
234 virtual Poco::JSON::Object::Ptr httpSetParam( const Poco::URI::QueryParameters& p );
235
236 // status
237 Poco::JSON::Object::Ptr httpStatus();
238 Poco::JSON::Object::Ptr buildLogServerInfo();
239
240 // Защитный флаг: разрешить/запретить /setparam (по аналогии с MBExchange/MBSlave)
241 bool httpEnabledSetParams { true };
242#endif
243 bool initVariable(UniXML::iterator& it);
244 bool readItem(const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec);
245 void readConfiguration();
246
247 std::shared_ptr<SMInterface> shm;
248 std::unique_ptr<ThreadCreator<OPCUAServer>> serverThread;
249 std::unique_ptr<ThreadCreator<OPCUAServer>> updateThread;
250
252 {
253 IOVariable(const opcua::Node<opcua::Server>& n) : node(n) {};
254 opcua::Node<opcua::Server> node;
255 IOController::IOStateList::iterator it;
256 UniversalIO::IOType stype = { UniversalIO::AO };
257
259 DefaultValueType value = { 0 };
260 bool state = { false };
261 DefaultValueUType mask = { 0 };
262 uint8_t offset = { 0 };
263 opcua::DataTypeId vtype = { DefaultVariableType };
264 uint8_t precision = { 0 }; // only for float
265 };
266
267 std::unordered_map<ObjectId, IOVariable> variables;
268 size_t writeCount = { 0 };
269
270 struct IONode
271 {
272 opcua::Node<opcua::Server> node;
273 IONode( const opcua::Node<opcua::Server>& n ): node(n) {};
274 };
275
276 struct IOMethod
277 {
278 IOMethod( uniset::ObjectId _sid) : sid(_sid) {};
279
280 IOController::IOStateList::iterator it;
282 uint8_t precision = { 0 }; // only for float
283 };
284
285 std::unordered_map<uint32_t, IOMethod> methods;
286 size_t methodCount = { 0 };
287
288 private:
289 opcua::Server opcServer;
290 std::unique_ptr<IONode> ioNode = { nullptr };
291 std::string prefix;
292 std::string propPrefix;
293 std::string s_field;
294 std::string s_fvalue;
295 std::optional<std::regex> s_fvalue_re;
296 std::string namePrefix;
297 uniset::timeout_t updateTime_msec = { 100 };
298 std::atomic_bool firstUpdate = false;
299 std::shared_ptr<LogServer> logserv;
300 std::string logserv_host = {""};
301 int logserv_port = {0};
302
303 using folderMap = std::unordered_map<std::string, std::unique_ptr<IONode>>;
304 folderMap foldermap; // список тегов
305 void initFolderMap( uniset::UniXML::iterator it, const std::string& parent_name, std::unique_ptr<IONode>& parent );
306 };
307 // --------------------------------------------------------------------------
309 constexpr std::string_view getLogLevelName(opcua::LogLevel level)
310 {
311 switch (level)
312 {
313 case opcua::LogLevel::Trace:
314 return "trace";
315
316 case opcua::LogLevel::Debug:
317 return "debug";
318
319 case opcua::LogLevel::Info:
320 return "info";
321
322 case opcua::LogLevel::Warning:
323 return "warning";
324
325 case opcua::LogLevel::Error:
326 return "error";
327
328 case opcua::LogLevel::Fatal:
329 return "fatal";
330
331 default:
332 return "unknown";
333 }
334 }
335
337 constexpr std::string_view getLogCategoryName(opcua::LogCategory category)
338 {
339 switch (category)
340 {
341 case opcua::LogCategory::Network:
342 return "network";
343
344 case opcua::LogCategory::SecureChannel:
345 return "channel";
346
347 case opcua::LogCategory::Session:
348 return "session";
349
350 case opcua::LogCategory::Server:
351 return "server";
352
353 case opcua::LogCategory::Client:
354 return "client";
355
356 case opcua::LogCategory::Userland:
357 return "userland";
358
359 case opcua::LogCategory::SecurityPolicy:
360 return "securitypolicy";
361
362 default:
363 return "unknown";
364 }
365 }
366} // end of namespace uniset
367// -----------------------------------------------------------------------------
368#endif // _OPCUAServer_H_
369// -----------------------------------------------------------------------------
Definition UObject_SK.h:30
Definition OPCUAServer.h:171
virtual void callback() noexcept override
Definition OPCUAServer.cc:525
virtual std::string getMonitInfo() const override
Definition OPCUAServer.cc:917
virtual bool deactivateObject() override
Деактивация объекта (переопределяется для необходимых действий при завершении работы)
Definition OPCUAServer.cc:594
static void help_print()
Definition OPCUAServer.cc:616
static std::shared_ptr< OPCUAServer > init_opcua_server(int argc, const char *const *argv, uniset::ObjectId shmID, const std::shared_ptr< SharedMemory > &ic=nullptr, const std::string &prefix="opcua")
Definition OPCUAServer.cc:669
Definition MessageType.h:127
Definition MessageType.h:171
Definition USingleProcess.h:28
Definition UniXML.h:44
Definition Mutex.h:32
Definition AccessConfig.h:30
constexpr std::string_view getLogCategoryName(opcua::LogCategory category)
Get name of log category.
Definition OPCUAServer.h:337
constexpr std::string_view getLogLevelName(opcua::LogLevel level)
Get name of log level.
Definition OPCUAServer.h:309
const ObjectId DefaultObjectId
Definition UniSetTypes.h:71
long ObjectId
Definition UniSetTypes_i.idl:30
Definition OPCUAServer.h:277
Definition OPCUAServer.h:271
Definition OPCUAServer.h:252
Definition UHttpRequestHandler.h:87