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
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
00083 iStream >> hdr;
00084
00085
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
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:
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 }
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 }