00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "common.h"
00012
00013 #include <gtest/gtest.h>
00014 #include <opc/ua/attribute_ids.h>
00015 #include <opc/ua/object_ids.h>
00016 #include <opc/ua/protocol/attribute.h>
00017 #include <opc/ua/protocol/binary/stream.h>
00018 #include <opc/ua/protocol/endpoints.h>
00019 #include <opc/ua/client/remote_connection.h>
00020 #include <opc/ua/protocol/secure_channel.h>
00021 #include <opc/ua/protocol/session.h>
00022 #include <opc/ua/protocol/view.h>
00023
00024 namespace
00025 {
00026 class OpcBinaryHandshake : public ::testing::Test
00027 {
00028 protected:
00029 virtual void SetUp()
00030 {
00031 }
00032
00033 virtual void TearDown()
00034 {
00035 }
00036 };
00037 }
00038
00039 using namespace OpcUa::Binary;
00040
00041 TEST_F(OpcBinaryHandshake, EstablishConnection)
00042 {
00043 const std::string host = GetHost();
00044 const unsigned port = GetPort();
00045 std::unique_ptr<OpcUa::RemoteConnection> connect = OpcUa::Connect(host, port);
00046 ASSERT_EQ(connect->GetHost(), host);
00047 ASSERT_EQ(connect->GetPort(), port);
00048 }
00049
00050
00051
00052
00053
00054 TEST_F(OpcBinaryHandshake, SayingHello)
00055 {
00056 std::shared_ptr<OpcUa::RemoteConnection> connection(OpcUa::Connect(GetHost(), GetPort()));
00057 OpcUa::Binary::OStream os(connection);
00058 OpcUa::Binary::IStream is(connection);
00059
00060 OpcUa::Binary::Hello hello;
00061 hello.ProtocolVersion = 0;
00062 hello.ReceiveBufferSize = OPCUA_DEFAULT_BUFFER_SIZE;
00063 hello.SendBufferSize = OPCUA_DEFAULT_BUFFER_SIZE;
00064 hello.MaxMessageSize = OPCUA_DEFAULT_BUFFER_SIZE;
00065 hello.MaxChunkCount = 1;
00066 hello.EndpointUrl = GetEndpoint();
00067
00068 OpcUa::Binary::Header hdr(OpcUa::Binary::MT_HELLO, OpcUa::Binary::CHT_SINGLE);
00069 hdr.AddSize(RawSize(hello));
00070
00071 os << hdr << hello << flush;
00072
00073 OpcUa::Binary::Header ackHeader;
00074 is >> ackHeader;
00075 ASSERT_EQ(ackHeader.Type, OpcUa::Binary::MT_ACKNOWLEDGE);
00076 ASSERT_EQ(ackHeader.Chunk, OpcUa::Binary::CHT_SINGLE);
00077
00078 OpcUa::Binary::Acknowledge ack;
00079
00080 ASSERT_EQ(ackHeader.Size, RawSize(ack) + RawSize(ackHeader));
00081
00082 ASSERT_NO_THROW(is >> ack);
00083 }
00084
00085
00086
00087
00088
00089 std::string GetEndpointUrl()
00090 {
00091 std::stringstream s;
00092 s << "opc.tcp://" << GetHost() << ":" << GetPort();
00093 return s.str();
00094 }
00095
00096 TEST_F(OpcBinaryHandshake, OpenSecureChannel_PolicyNone)
00097 {
00098 std::shared_ptr<OpcUa::RemoteConnection> connection(OpcUa::Connect(GetHost(), GetPort()));
00099
00100 OpcUa::Binary::SecureConnectionParams params;
00101 params.EndpointUrl = GetEndpointUrl();
00102 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00103
00104 std::unique_ptr<OpcUa::IOChannel> secureChannel = OpcUa::Binary::CreateSecureChannel(connection, params);
00105 }
00106
00107
00108
00109
00110
00111
00112 TEST_F(OpcBinaryHandshake, GetEndpoints)
00113 {
00114 std::shared_ptr<OpcUa::RemoteConnection> connection(OpcUa::Connect(GetHost(), GetPort()));
00115
00116 OpcUa::Binary::SecureConnectionParams params;
00117 params.EndpointUrl = GetEndpointUrl();
00118 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00119
00120 std::shared_ptr<OpcUa::IOChannel> secureChannel = OpcUa::Binary::CreateSecureChannel(connection, params);
00121
00122 using OpcUa::Binary::flush;
00123
00124 OpcUa::Binary::GetEndpointsRequest request;
00125 request.EndpointUrl = params.EndpointUrl;
00126 OpcUa::Binary::IOStream io(secureChannel);
00127 io << request << flush;
00128
00129 OpcUa::Binary::GetEndpointsResponse response;
00130 ASSERT_NO_THROW(io >> response);
00131 }
00132
00133
00134
00135
00136
00137 EndpointDescription GetEndpoint(OpcUa::Binary::IOStream& stream)
00138 {
00139 OpcUa::Binary::GetEndpointsRequest request;
00140 request.EndpointUrl = GetEndpointUrl();
00141 stream << request << flush;
00142
00143 OpcUa::Binary::GetEndpointsResponse response;
00144 stream >> response;
00145 if (response.Endpoints.empty())
00146 {
00147 throw std::logic_error("Server returned empty list of endpoints");
00148 }
00149 return response.Endpoints.front();
00150 }
00151
00152 TEST_F(OpcBinaryHandshake, GetCreateSession)
00153 {
00154 using namespace OpcUa::Binary;
00155 std::shared_ptr<RemoteConnection> connection(Connect(GetHost(), GetPort()));
00156
00157 SecureConnectionParams params;
00158 params.EndpointUrl = GetEndpointUrl();
00159 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00160
00161 std::shared_ptr<OpcUa::IOChannel> secureChannel = CreateSecureChannel(connection, params);
00162
00163 IOStream stream(secureChannel);
00164 EndpointDescription endpoint = GetEndpoint(stream);
00165
00166 CreateSessionRequest request;
00167 request.ClientDescription.URI = "http://treww.org/libopcua";
00168 request.ClientDescription.ProductURI = "http://treww.org/libopcua";
00169 request.ClientDescription.Name.Encoding = HAS_TEXT;
00170 request.ClientDescription.Name.Text = "libopcuamappings";
00171 request.ClientDescription.Type = ApplicationType::Client;
00172
00173 request.ServerURI = endpoint.ServerDescription.URI;
00174 request.EndpointUrl = endpoint.EndpointUrl;
00175 request.SessionName = "libiocuamappings session test";
00176 request.ClientNonce = std::vector<uint8_t>(32,0);
00177
00178 request.RequestedSessionTimeout = 3600000;
00179 request.MaxResponseMessageSize = 65536;
00180
00181 stream << request << flush;
00182
00183 OpcUa::Binary::CreateSessionResponse response;
00184 ASSERT_NO_THROW(stream >> response);
00185
00186 ASSERT_EQ(response.TypeId.Encoding, EV_FOUR_BYTE);
00187 ASSERT_EQ(response.TypeId.FourByteData.NamespaceIndex, 0);
00188 ASSERT_EQ(response.TypeId.FourByteData.Identifier, OpcUa::CREATE_SESSION_RESPONSE);
00189 }
00190
00191
00192
00193
00194
00195 OpcUa::Binary::CreateSessionResponse CreateSession(OpcUa::Binary::IOStream& stream)
00196 {
00197 EndpointDescription endpoint = GetEndpoint(stream);
00198
00199 CreateSessionRequest request;
00200 request.ClientDescription.URI = "http://treww.org/libopcua";
00201 request.ClientDescription.ProductURI = "http://treww.org/libopcua";
00202 request.ClientDescription.Name.Encoding = HAS_TEXT;
00203 request.ClientDescription.Name.Text = "libopcuamappings";
00204 request.ClientDescription.Type = ApplicationType::Client;
00205
00206 request.ServerURI = endpoint.ServerDescription.URI;
00207 request.EndpointUrl = endpoint.EndpointUrl;
00208 request.SessionName = "libiocuamappings session test";
00209 request.ClientNonce = std::vector<uint8_t>(32,0);
00210
00211 request.RequestedSessionTimeout = 3600000;
00212 request.MaxResponseMessageSize = 65536;
00213
00214 stream << request << flush;
00215
00216 OpcUa::Binary::CreateSessionResponse response;
00217 stream >> response;
00218 return response;
00219 }
00220
00221 TEST_F(OpcBinaryHandshake, ActivateSession)
00222 {
00223 using namespace OpcUa::Binary;
00224 std::shared_ptr<RemoteConnection> connection(Connect(GetHost(), GetPort()));
00225
00226 SecureConnectionParams params;
00227 params.EndpointUrl = GetEndpointUrl();
00228 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00229
00230 std::shared_ptr<OpcUa::IOChannel> secureChannel = CreateSecureChannel(connection, params);
00231
00232 IOStream stream(secureChannel);
00233 CreateSessionResponse session = CreateSession(stream);
00234
00235 ActivateSessionRequest activate;
00236 activate.Header.SessionAuthenticationToken = session.AuthenticationToken;
00237 activate.LocaleIds.push_back("en");
00238 stream << activate << flush;
00239
00240 ActivateSessionResponse response;
00241 stream >> response;
00242
00243 }
00244
00245
00246
00247
00248 TEST_F(OpcBinaryHandshake, CloseSession)
00249 {
00250 using namespace OpcUa::Binary;
00251 std::shared_ptr<RemoteConnection> connection(Connect(GetHost(), GetPort()));
00252
00253 SecureConnectionParams params;
00254 params.EndpointUrl = GetEndpointUrl();
00255 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00256
00257 std::shared_ptr<OpcUa::IOChannel> secureChannel = CreateSecureChannel(connection, params);
00258
00259 IOStream stream(secureChannel);
00260 CreateSessionResponse session = CreateSession(stream);
00261
00262 ActivateSessionRequest activate;
00263 activate.Header.SessionAuthenticationToken = session.AuthenticationToken;
00264 activate.LocaleIds.push_back("en");
00265 stream << activate << flush;
00266
00267 ActivateSessionResponse response;
00268 stream >> response;
00269
00270 CloseSessionRequest closeSession;
00271 closeSession.Header.SessionAuthenticationToken = session.AuthenticationToken;
00272 stream << closeSession << flush;
00273
00274 CloseSessionResponse closeResponse;
00275 stream >> closeResponse;
00276 }
00277
00278
00279
00280
00281
00282 void CloseSession(OpcUa::Binary::IOStream& stream, const OpcUa::Binary::CreateSessionResponse& session)
00283 {
00284 CloseSessionRequest closeSession;
00285 closeSession.Header.SessionAuthenticationToken = session.AuthenticationToken;
00286 stream << closeSession << flush;
00287
00288 CloseSessionResponse closeResponse;
00289 stream >> closeResponse;
00290 }
00291
00292 void ActivateSession(OpcUa::Binary::IOStream& stream, const OpcUa::Binary::CreateSessionResponse& session)
00293 {
00294 using namespace OpcUa::Binary;
00295 ActivateSessionRequest activate;
00296 activate.Header.SessionAuthenticationToken = session.AuthenticationToken;
00297 activate.LocaleIds.push_back("en");
00298 stream << activate << flush;
00299
00300 ActivateSessionResponse response;
00301 stream >> response;
00302 }
00303
00304 TEST_F(OpcBinaryHandshake, Browse)
00305 {
00306 using namespace OpcUa::Binary;
00307 std::shared_ptr<RemoteConnection> connection(Connect(GetHost(), GetPort()));
00308
00309 SecureConnectionParams params;
00310 params.EndpointUrl = GetEndpointUrl();
00311 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00312
00313 std::shared_ptr<OpcUa::IOChannel> secureChannel = CreateSecureChannel(connection, params);
00314
00315 IOStream stream(secureChannel);
00316 CreateSessionResponse session = CreateSession(stream);
00317 ActivateSession(stream, session);
00318
00319 OpcUa::Binary::BrowseRequest browse;
00320 browse.Header.SessionAuthenticationToken = session.AuthenticationToken;
00321 browse.MaxReferenciesPerNode = 2;
00322
00323 BrowseDescription desc;
00324 desc.NodeToBrowse.Encoding = EV_TWO_BYTE;
00325 desc.NodeToBrowse.TwoByteData.Identifier = 84;
00326 desc.Direction = BrowseDirection::FORWARD;
00327 desc.ReferenceTypeId.Encoding = EV_TWO_BYTE;
00328 desc.ReferenceTypeId.TwoByteData.Identifier = 33;
00329 desc.IncludeSubtypes = true;
00330 desc.NodeClasses = NodeClass::Unspecified;
00331 desc.ResultMask = BrowseResultMask::All;
00332 browse.NodesToBrowse.push_back(desc);
00333
00334 stream << browse << flush;
00335
00336 BrowseResponse response;
00337 stream >> response;
00338
00339 EXPECT_TRUE(!response.Results.empty());
00340
00341 BrowseNextRequest browseNext;
00342 browseNext.Header.SessionAuthenticationToken = session.AuthenticationToken;
00343 browseNext.ReleaseContinuationPoints= false;
00344 browseNext.ContinuationPoints.push_back(response.Results[0].ContinuationPoint);
00345
00346 stream << browseNext << flush;
00347
00348 BrowseNextResponse resp;
00349 stream >> resp;
00350
00351 EXPECT_TRUE(!response.Results.empty());
00352
00353 CloseSession(stream, session);
00354 }
00355
00356
00357
00358
00359
00360 TEST_F(OpcBinaryHandshake, Read)
00361 {
00362 using namespace OpcUa;
00363 using namespace OpcUa::Binary;
00364
00365 std::shared_ptr<RemoteConnection> connection(Connect(GetHost(), GetPort()));
00366
00367 SecureConnectionParams params;
00368 params.EndpointUrl = GetEndpointUrl();
00369 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00370
00371 std::shared_ptr<OpcUa::IOChannel> secureChannel = CreateSecureChannel(connection, params);
00372
00373 IOStream stream(secureChannel);
00374 CreateSessionResponse session = CreateSession(stream);
00375 ActivateSession(stream, session);
00376
00377
00378
00379 ReadValueId value;
00380 value.Node.Encoding = EV_FOUR_BYTE;
00381 value.Node.FourByteData.Identifier = static_cast<uint8_t>(ObjectId::RootFolder);
00382 value.Attribute = AttributeId::DisplayName;
00383
00384
00385 OpcUa::Binary::ReadRequest request;
00386 request.Header.SessionAuthenticationToken = session.AuthenticationToken;
00387 request.MaxAge = 0;
00388 request.TimestampsType = TimestampsToReturn::Neither;
00389 request.AttributesToRead.push_back(value);
00390
00391 stream << request << flush;
00392
00393 ReadResponse response;
00394 stream >> response;
00395
00396 EXPECT_TRUE(!response.Results.empty());
00397
00398 CloseSession(stream, session);
00399 }
00400
00401
00402
00403
00404
00405 TEST_F(OpcBinaryHandshake, Write)
00406 {
00407 using namespace OpcUa;
00408 using namespace OpcUa::Binary;
00409
00410 std::shared_ptr<RemoteConnection> connection(Connect(GetHost(), GetPort()));
00411
00412 SecureConnectionParams params;
00413 params.EndpointUrl = GetEndpointUrl();
00414 params.SecurePolicy = "http://opcfoundation.org/UA/SecurityPolicy#None";
00415
00416 std::shared_ptr<OpcUa::IOChannel> secureChannel = CreateSecureChannel(connection, params);
00417
00418 IOStream stream(secureChannel);
00419 CreateSessionResponse session = CreateSession(stream);
00420 ActivateSession(stream, session);
00421
00422 OpcUa::Binary::WriteRequest request;
00423 request.Header.SessionAuthenticationToken = session.AuthenticationToken;
00424
00425 WriteValue value;
00426 value.Node.Encoding = EV_FOUR_BYTE;
00427 value.Node.FourByteData.Identifier = static_cast<uint8_t>(ObjectId::RootFolder);
00428 value.Attribute = AttributeId::DisplayName;
00429 value.Data.Encoding = DATA_VALUE;
00430 value.Data.Value.Type = VariantType::STRING;
00431 value.Data.Value.Value.String.push_back("root");
00432
00433 request.NodesToWrite.push_back(value);
00434
00435 stream << request << flush;
00436
00437 WriteResponse response;
00438 stream >> response;
00439
00440 EXPECT_TRUE(!response.StatusCodes.empty());
00441
00442 CloseSession(stream, session);
00443 }
00444