opcua_protocol_addon.cpp
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 #include "opcua_protocol.h"
00013 
00014 #include "opc_tcp_processor.h"
00015 #include "endpoints_parameters.h"
00016 #include "tcp_server.h"
00017 
00018 #include <opc/ua/protocol/utils.h>
00019 #include <opc/common/uri_facade.h>
00020 #include <opc/common/addons_core/addon_manager.h>
00021 #include <opc/ua/protocol/endpoints.h>
00022 #include <opc/ua/protocol/input_from_buffer.h>
00023 #include <opc/ua/server/addons/opcua_protocol.h>
00024 #include <opc/ua/server/addons/endpoints_services.h>
00025 #include <opc/ua/server/addons/services_registry.h>
00026 
00027 #include <stdexcept>
00028 
00029 
00030 namespace
00031 {
00032 
00033   using namespace OpcUa;
00034   using namespace OpcUa::Binary;
00035   using namespace OpcUa::Server;
00036 
00037   class OpcTcp : public OpcUa::Server::IncomingConnectionProcessor
00038   {
00039   public:
00040     OpcTcp(OpcUa::Services::SharedPtr services, bool debug)
00041       : Server(services)
00042       , Debug(debug)
00043     {
00044     }
00045 
00046     virtual void Process(OpcUa::IOChannel::SharedPtr clientChannel)
00047     {
00048       if (!clientChannel)
00049       {
00050         if (Debug) std::cerr << "opc_tcp_processor| Empty channel passed to endpoints opc binary protocol processor." << std::endl;
00051         return;
00052       }
00053 
00054       if (Debug) std::clog << "opc_tcp_processor| Hello client!" << std::endl;
00055 
00056       std::auto_ptr<OpcTcpMessages> messageProcessor(new OpcTcpMessages(Server, *clientChannel, Debug));
00057 
00058       for(;;)
00059       {
00060         ProcessData(*clientChannel, *messageProcessor);
00061       }
00062     }
00063 
00064     virtual void StopProcessing(OpcUa::IOChannel::SharedPtr clientChannel)
00065     {
00066     }
00067 
00068   private:
00069     void ProcessData(OpcUa::IOChannel& clientChannel, OpcUa::Server::OpcTcpMessages& messageProcessor)
00070     {
00071       using namespace OpcUa::Binary;
00072 
00073       IStreamBinary iStream(clientChannel);
00074       ProcessChunk(iStream, messageProcessor);
00075     }
00076 
00077     // TODO implement collecting full message from chunks before processing.
00078     void ProcessChunk(IStreamBinary& iStream, OpcTcpMessages& messageProcessor)
00079     {
00080       if (Debug) std::cout << "opc_tcp_processor| Processing new chunk." << std::endl;
00081       Header hdr;
00082       // Receive message header.
00083       iStream >> hdr;
00084 
00085       // Receive full message.
00086       std::vector<char> buffer(hdr.MessageSize());
00087       OpcUa::Binary::RawBuffer buf(&buffer[0], buffer.size());
00088       iStream >> buf;
00089       if (Debug)
00090       {
00091         std::clog << "opc_tcp_processor| Received message." << std::endl;
00092         PrintBlob(buffer);
00093       }
00094 
00095       // restrict server size code only with current message.
00096       OpcUa::InputFromBuffer messageChannel(&buffer[0], buffer.size());
00097       IStreamBinary messageStream(messageChannel);
00098       messageProcessor.ProcessMessage(hdr.Type, messageStream);
00099 
00100       if (messageChannel.GetRemainSize())
00101       {
00102         std::cerr << "opc_tcp_processor| ERROR!!! Message from client has been processed partially." << std::endl;
00103       }
00104     }
00105 
00106   private:
00107     OpcUa::Services::SharedPtr Server;
00108     bool Debug;
00109   };
00110 
00111   class OpcUaProtocol : public OpcUa::Server::OpcUaProtocol
00112   {
00113   public:
00114     DEFINE_CLASS_POINTERS(OpcUaProtocol);
00115 
00116   public:
00117     OpcUaProtocol(OpcUa::Server::TcpServer& tcpServer, bool debug)
00118       : TcpAddon(tcpServer)
00119       , Debug(debug)
00120     {
00121     }
00122 
00123     virtual void StartEndpoints(const std::vector<EndpointDescription>& endpoints, OpcUa::Services::SharedPtr server) override
00124     {
00125       for (const EndpointDescription endpoint : endpoints)
00126       {
00127         const Common::Uri uri(endpoint.EndpointUrl);
00128         if (uri.Scheme() == "opc.tcp")
00129         {
00130           std::shared_ptr<IncomingConnectionProcessor> processor(new OpcTcp(server, Debug));
00131           TcpParameters tcpParams;
00132           tcpParams.Port = uri.Port();
00133           if (Debug) std::clog << "opc_tcp_processor| Starting listen port " << tcpParams.Port << std::endl;
00134           TcpAddon.Listen(tcpParams, processor);
00135           Ports.push_back(tcpParams);
00136         }
00137       }
00138     }
00139 
00140     virtual void StopEndpoints() override
00141     {
00142       for (const TcpParameters& params : Ports)
00143       {
00144         TcpAddon.StopListen(params);
00145       }
00146     }
00147 
00148   private:
00149     OpcUa::Server::TcpServer& TcpAddon;
00150     std::vector<TcpParameters> Ports;
00151     bool Debug;
00152   };
00153 
00154 
00155   class OpcUaProtocolAddon : public Common::Addon
00156   {
00157   public:
00158     OpcUaProtocolAddon()
00159       : Debug(false)
00160     {
00161     }
00162 
00163   public: // Common::Addon
00164     virtual void Initialize(Common::AddonsManager& addons, const Common::AddonParameters& params) override;
00165     virtual void Stop() override;
00166 
00167   private:
00168     void ApplyAddonParameters(const Common::AddonParameters& params);
00169     void PublishApplicationsInformation(std::vector<OpcUa::ApplicationDescription> applications, std::vector<OpcUa::EndpointDescription> endpoints, const Common::AddonsManager& addons) const;
00170 
00171   private:
00172     OpcUa::Server::ServicesRegistry::SharedPtr InternalServer;
00173     OpcUa::Server::TcpServer::SharedPtr TcpServer;
00174     OpcUa::Server::OpcUaProtocol::SharedPtr Protocol;
00175     bool Debug;
00176   };
00177 
00178   void OpcUaProtocolAddon::Initialize(Common::AddonsManager& addons, const Common::AddonParameters& params)
00179   {
00180     ApplyAddonParameters(params);
00181     const std::vector<OpcUa::Server::ApplicationData> applications = OpcUa::ParseEndpointsParameters(params.Groups, Debug);
00182     for (OpcUa::Server::ApplicationData d: applications) {
00183       std::cout << "Endpoint is: " << d.Endpoints.front().EndpointUrl << std::endl;
00184     }
00185 
00186     std::vector<OpcUa::ApplicationDescription> applicationDescriptions;
00187     std::vector<OpcUa::EndpointDescription> endpointDescriptions;
00188     for (const OpcUa::Server::ApplicationData application : applications)
00189     {
00190       applicationDescriptions.push_back(application.Application);
00191       endpointDescriptions.insert(endpointDescriptions.end(), application.Endpoints.begin(), application.Endpoints.end());
00192     }
00193     OpcUa::Server::EndpointsRegistry::SharedPtr endpointsAddon = addons.GetAddon<OpcUa::Server::EndpointsRegistry>(OpcUa::Server::EndpointsRegistryAddonId);
00194     if (!endpointsAddon)
00195     {
00196       std::cerr << "Cannot save information about endpoints. Endpoints services addon didn't' registered." << std::endl;
00197       return;
00198     }
00199     endpointsAddon->AddEndpoints(endpointDescriptions);
00200     endpointsAddon->AddApplications(applicationDescriptions);
00201 
00202     InternalServer = addons.GetAddon<OpcUa::Server::ServicesRegistry>(OpcUa::Server::ServicesRegistryAddonId);
00203 
00204     TcpServer = OpcUa::Server::CreateTcpServer();
00205     Protocol.reset(new OpcUaProtocol(*TcpServer, Debug));
00206     Protocol->StartEndpoints(endpointDescriptions, InternalServer->GetServer());
00207   }
00208 
00209   void OpcUaProtocolAddon::Stop()
00210   {
00211     Protocol.reset();
00212     TcpServer.reset();
00213     InternalServer.reset();
00214   }
00215 
00216   void OpcUaProtocolAddon::ApplyAddonParameters(const Common::AddonParameters& params)
00217   {
00218     for (const Common::Parameter parameter : params.Parameters)
00219     {
00220       if (parameter.Name == "debug" && !parameter.Value.empty() && parameter.Value != "0")
00221       {
00222         Debug = true;
00223         std::cout << "Enabled debug mode in the binary protocol addon." << std::endl;
00224       }
00225     }
00226   }
00227 
00228   void OpcUaProtocolAddon::PublishApplicationsInformation(std::vector<OpcUa::ApplicationDescription> applications, std::vector<OpcUa::EndpointDescription> endpoints, const Common::AddonsManager& addons) const
00229   {
00230     OpcUa::Server::EndpointsRegistry::SharedPtr endpointsAddon = addons.GetAddon<OpcUa::Server::EndpointsRegistry>(OpcUa::Server::EndpointsRegistryAddonId);
00231     if (!endpointsAddon)
00232     {
00233       std::cerr << "Cannot save information about endpoints. Endpoints services addon didn't' registered." << std::endl;
00234       return;
00235     }
00236     endpointsAddon->AddEndpoints(endpoints);
00237     endpointsAddon->AddApplications(applications);
00238   }
00239 
00240 } // namespace
00241 
00242 
00243 namespace OpcUa
00244 {
00245   namespace Server
00246   {
00247     Common::Addon::UniquePtr OpcUaProtocolAddonFactory::CreateAddon()
00248     {
00249       return Common::Addon::UniquePtr(new ::OpcUaProtocolAddon());
00250     }
00251 
00252 
00253     OpcUaProtocol::UniquePtr CreateOpcUaProtocol(TcpServer& tcpServer, bool debug)
00254     {
00255       return OpcUaProtocol::UniquePtr(new ::OpcUaProtocol(tcpServer, debug));
00256     }
00257 
00258   }
00259 }


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:56