00001 /****************************************************************************** 00002 * Copyright (C) 2014-2014 by Sintef Raufoss Manufacturing * 00003 * olivier.roulet@gmail.com * 00004 * * 00005 * This library is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU Lesser General Public License as * 00007 * published by the Free Software Foundation; version 3 of the License. * 00008 * * 00009 * This library is distributed in the hope that it will be useful, * 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00012 * GNU Lesser General Public License for more details. * 00013 * * 00014 * You should have received a copy of the GNU Lesser General Public License * 00015 * along with this library; if not, write to the * 00016 * Free Software Foundation, Inc., * 00017 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00018 ******************************************************************************/ 00019 00020 00021 #pragma once 00022 00023 #include <opc/ua/node.h> 00024 #include <opc/ua/services/services.h> 00025 #include <opc/ua/subscription.h> 00026 #include <opc/ua/client/binary_client.h> 00027 #include <opc/ua/server_operations.h> 00028 00029 #include <thread> 00030 #include <condition_variable> 00031 #include <chrono> 00032 #include <atomic> 00033 00034 00035 namespace OpcUa 00036 { 00037 00038 class KeepAliveThread 00039 { 00040 public: 00042 // Send keepalive request to server so it does not disconnect us 00043 KeepAliveThread(bool debug=false) : StopRequest(false), Running(false), Debug(debug) {} 00044 void Start( Services::SharedPtr server, Node node, Duration period); 00045 void Stop(); 00046 00047 private: 00048 void Run(); 00049 mutable std::thread Thread; 00050 Node NodeToRead; 00051 Services::SharedPtr Server; 00052 Duration Period = 1200000; 00053 std::atomic<bool> StopRequest; 00054 std::atomic<bool> Running; 00055 std::condition_variable Condition; 00056 std::mutex Mutex; 00057 bool Debug = false; 00058 }; 00059 00060 00061 class UaClient 00062 { 00063 public: 00073 UaClient(bool debug=false) : KeepAlive(debug), Debug(debug) {} 00074 ~UaClient(); 00075 00076 UaClient(const UaClient&&) = delete; 00077 UaClient(const UaClient&) = delete; 00078 UaClient& operator=(const UaClient&) = delete; 00079 00081 void SetSessionName(const std::string& str) { SessionName = str; } 00082 std::string GetSessionName() const { return SessionName; } 00083 00085 // a connection will be made to server to get endpoint description 00086 // an endpoint description will be selected and then a connection will attempted 00087 void Connect(const std::string& endpoint); 00088 00090 // EndpointDescription can be defined by hand or gotten through 00091 // a call to GetServerEndpoints() 00092 void Connect(const EndpointDescription&); 00093 00095 // close communication with OPC-UA server, close all threads and subscriptions 00096 void Disconnect(); 00097 00099 // abort communication with OPC-UA server, close all threads and subcsriptions 00100 // Like Disconnect() but without CloseSession() call, which is not possible on faulty connection anyway 00101 void Abort(); 00102 00104 std::vector<EndpointDescription> GetServerEndpoints(const std::string& endpoint); 00105 00107 EndpointDescription SelectEndpoint(const std::string&); 00108 00110 std::vector<EndpointDescription> GetServerEndpoints(); 00111 std::string GetEndpoint() const { return Endpoint.EndpointUrl; } 00112 00114 std::string GetApplicationURI() const { return ApplicationUri; } 00115 void SetApplicationURI(std::string uri) { ApplicationUri = uri; } 00116 std::string GetProductURI() const { return ProductUri; } 00117 void SetProductURI(std::string uri) { ProductUri = uri; } 00118 00120 // anyway freeopcua currently only support MessageSecurityMode::None 00121 void SetSecurityPolicy(std::string sec) {SecurityPolicy = sec;} 00122 std::string GetSecurityPolicy() const { return SecurityPolicy; } 00123 00125 // Deduce index from order or call GetNamespaceIndex(uri) 00126 std::vector<std::string> GetServerNamespaces(); 00127 uint32_t GetNamespaceIndex(std::string uri); 00128 00130 // you can also access a standard node from addressspace using 00131 // ObjectId, for example: 00132 // Node mynode = GetNode(ObjectId::Server); 00133 // using a string is also possible: 00134 // Node mynode = GetNode("ns=3;i=55"); 00135 Node GetNode(const NodeId& nodeid) const; 00136 Node GetNode(const std::string& nodeid) const; 00137 00139 Node GetRootNode() const; 00140 Node GetObjectsNode() const; 00141 Node GetServerNode() const; 00142 00143 void DeleteNodes(std::vector<OpcUa::Node>& nodes, bool recursive=false); 00144 00146 // returned object can then be used to subscribe 00147 // to datachange or custom events from server 00148 std::unique_ptr<Subscription> CreateSubscription(unsigned int period, SubscriptionHandler& client); 00149 00151 ServerOperations CreateServerOperations(); 00152 00153 private: 00154 void OpenSecureChannel(); 00155 void CloseSecureChannel(); 00156 00157 std::vector<OpcUa::Node> AddChilds(std::vector<OpcUa::Node> nodes); 00158 00159 EndpointDescription Endpoint; 00160 // defined some sensible defaults that should let us connect to most servers 00161 std::string SessionName = "Open source OPC-UA Client Session"; 00162 std::string ApplicationUri = "urn:freeopcua:client"; 00163 std::string ProductUri = "urn:freeopcua.github.no:client"; 00164 std::string SecurityPolicy = "none"; 00165 KeepAliveThread KeepAlive; 00166 uint32_t SecureChannelId; 00167 bool Debug = false; 00168 uint32_t DefaultTimeout = 3600000; 00169 00170 protected: 00171 Services::SharedPtr Server; 00172 00173 }; 00174 00175 } // namespace OpcUa