00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "common.h"
00012
00013 #include <opc/ua/protocol/extension_identifiers.h>
00014 #include <opc/ua/protocol/message_identifiers.h>
00015 #include <opc/ua/protocol/binary/stream.h>
00016 #include <opc/ua/protocol/strings.h>
00017 #include <opc/ua/protocol/protocol.h>
00018
00019 #include <algorithm>
00020 #include <stdexcept>
00021
00022
00023
00024
00025
00026
00027
00028 TEST_F(OpcUaBinarySerialization, AttributeId)
00029 {
00030
00031 using namespace OpcUa::Binary;
00032 using OpcUa::AttributeId;
00033
00034 GetStream() << AttributeId::Value << flush;
00035
00036 const std::vector<char> expectedData = {
00037 13,0,0,0
00038 };
00039
00040 ASSERT_EQ(expectedData.size(), RawSize(AttributeId::Value));
00041 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00042 }
00043
00044 TEST_F(OpcUaBinaryDeserialization, AttributeId)
00045 {
00046 using namespace OpcUa::Binary;
00047 using OpcUa::AttributeId;
00048
00049 const std::vector<char> expectedData = {
00050 13,0,0,0
00051 };
00052
00053 GetChannel().SetData(expectedData);
00054
00055 AttributeId id;
00056 GetStream() >> id;
00057
00058 ASSERT_EQ(id, AttributeId::Value);
00059 }
00060
00061
00062
00063
00064
00065
00066
00067 TEST_F(OpcUaBinarySerialization, TimestampsToReturn)
00068 {
00069
00070 using namespace OpcUa;
00071 using namespace OpcUa::Binary;
00072
00073 GetStream() << TimestampsToReturn::Neither << flush;
00074
00075 const std::vector<char> expectedData = {
00076 3,0,0,0
00077 };
00078
00079 ASSERT_EQ(expectedData.size(), RawSize(TimestampsToReturn::Neither));
00080 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00081 }
00082
00083 TEST_F(OpcUaBinaryDeserialization, TimetampsToReturn)
00084 {
00085 using namespace OpcUa;
00086 using namespace OpcUa::Binary;
00087
00088 const std::vector<char> expectedData = {
00089 3,0,0,0
00090 };
00091
00092 GetChannel().SetData(expectedData);
00093
00094 TimestampsToReturn stamps;
00095 GetStream() >> stamps;
00096
00097 ASSERT_EQ(stamps, TimestampsToReturn::Neither);
00098 }
00099
00100
00101
00102
00103
00104 TEST_F(OpcUaBinarySerialization, ReadValueId)
00105 {
00106
00107 using namespace OpcUa;
00108 using namespace OpcUa::Binary;
00109 using OpcUa::AttributeId;
00110
00111 ReadValueId attr;
00112
00113 attr.NodeId.Encoding = EV_TWO_BYTE;
00114 attr.NodeId.TwoByteData.Identifier = 1;
00115 attr.AttributeId = AttributeId::Value;
00116 attr.IndexRange = "1,2";
00117 attr.DataEncoding.NamespaceIndex = 2;
00118 attr.DataEncoding.Name = "test";
00119
00120 GetStream() << attr << flush;
00121
00122 const std::vector<char> expectedData = {
00123 0, 1,
00124 13,0,0,0,
00125 3,0,0,0, '1',',','2',
00126 2,0,
00127 4,0,0,0, 't','e','s','t'
00128 };
00129
00130 ASSERT_EQ(expectedData.size(), RawSize(attr));
00131 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00132 }
00133
00134 TEST_F(OpcUaBinaryDeserialization, ReadValueId)
00135 {
00136 using namespace OpcUa;
00137 using namespace OpcUa::Binary;
00138 using OpcUa::AttributeId;
00139
00140 const std::vector<char> expectedData = {
00141 0, 1,
00142 13,0,0,0,
00143 3,0,0,0, '1',',','2',
00144 2,0,
00145 4,0,0,0, 't','e','s','t'
00146 };
00147
00148 GetChannel().SetData(expectedData);
00149
00150 ReadValueId attr;
00151 GetStream() >> attr;
00152
00153 ASSERT_EQ(attr.NodeId.Encoding, EV_TWO_BYTE);
00154 ASSERT_EQ(attr.NodeId.TwoByteData.Identifier, 1);
00155 ASSERT_EQ(attr.AttributeId, AttributeId::Value);
00156 ASSERT_EQ(attr.DataEncoding.NamespaceIndex, 2);
00157 ASSERT_EQ(attr.DataEncoding.Name, "test");
00158 }
00159
00160
00161
00162
00163
00164 OpcUa::ReadValueId CreateReadValueId()
00165 {
00166 using namespace OpcUa;
00167 OpcUa::ReadValueId attr;
00168
00169 attr.NodeId.Encoding = OpcUa::EV_TWO_BYTE;
00170 attr.NodeId.TwoByteData.Identifier = 1;
00171 attr.AttributeId = OpcUa::AttributeId::Value;
00172 attr.IndexRange = "1,2";
00173 attr.DataEncoding.NamespaceIndex = 2;
00174 attr.DataEncoding.Name = "test";
00175
00176 return attr;
00177 }
00178
00179 TEST_F(OpcUaBinarySerialization, ReadRequest)
00180 {
00181 using namespace OpcUa;
00182 using namespace OpcUa::Binary;
00183
00184 ReadRequest request;
00185
00186 ASSERT_EQ(request.TypeId.Encoding, EV_FOUR_BYTE);
00187 ASSERT_EQ(request.TypeId.FourByteData.NamespaceIndex, 0);
00188 ASSERT_EQ(request.TypeId.FourByteData.Identifier, OpcUa::READ_REQUEST);
00189
00190 FILL_TEST_REQUEST_HEADER(request.Header);
00191
00192 request.Parameters.MaxAge = 1200000;
00193 request.Parameters.TimestampsToReturn = TimestampsToReturn::Neither;
00194
00195 request.Parameters.AttributesToRead.push_back(CreateReadValueId());
00196
00197 GetStream() << request << flush;
00198
00199 const std::vector<char> expectedData = {
00200 1, 0, (char)0x77, 0x2,
00201
00202 TEST_REQUEST_HEADER_BINARY_DATA,
00203
00204 0, 0, 0, 0, (char)0x80, (char)0x4f, (char)0x32, (char)0x41,
00205 3,0,0,0,
00206
00207 1,0,0,0,
00208 0, 1,
00209 13,0,0,0,
00210 3,0,0,0, '1',',','2',
00211 2,0,
00212 4,0,0,0, 't','e','s','t'
00213
00214 };
00215
00216 ASSERT_EQ(expectedData.size(), RawSize(request));
00217 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00218 }
00219
00220 TEST_F(OpcUaBinaryDeserialization, ReadRequest)
00221 {
00222
00223 using namespace OpcUa;
00224 using namespace OpcUa::Binary;
00225
00226 const std::vector<char> expectedData = {
00227 1, 0, (char)0x77, 0x2,
00228
00229 TEST_REQUEST_HEADER_BINARY_DATA,
00230
00231 0, 0, 0, 0, (char)0x80, (char)0x4f, (char)0x32, (char)0x41,
00232 3,0,0,0,
00233
00234 1,0,0,0,
00235 0, 1,
00236 13,0,0,0,
00237 3,0,0,0, '1',',','2',
00238 2,0,
00239 4,0,0,0, 't','e','s','t'
00240
00241 };
00242
00243 GetChannel().SetData(expectedData);
00244 ReadRequest request;
00245 GetStream() >> request;
00246
00247 ASSERT_EQ(request.TypeId.Encoding, EV_FOUR_BYTE);
00248 ASSERT_EQ(request.TypeId.FourByteData.NamespaceIndex, 0);
00249 ASSERT_EQ(request.TypeId.FourByteData.Identifier, OpcUa::READ_REQUEST);
00250
00251 ASSERT_REQUEST_HEADER_EQ(request.Header);
00252
00253 ASSERT_EQ(request.Parameters.MaxAge, 1200000);
00254 ASSERT_EQ(request.Parameters.TimestampsToReturn, TimestampsToReturn::Neither);
00255
00256 ASSERT_EQ(request.Parameters.AttributesToRead.size(), 1);
00257
00258 ReadValueId attr = CreateReadValueId();
00259
00260 ASSERT_EQ(request.Parameters.AttributesToRead[0].NodeId.Encoding, EV_TWO_BYTE);
00261 ASSERT_EQ(request.Parameters.AttributesToRead[0].NodeId.TwoByteData.Identifier, 1);
00262 ASSERT_EQ(request.Parameters.AttributesToRead[0].AttributeId, OpcUa::AttributeId::Value);
00263 ASSERT_EQ(request.Parameters.AttributesToRead[0].DataEncoding.NamespaceIndex, 2);
00264 ASSERT_EQ(request.Parameters.AttributesToRead[0].DataEncoding.Name, "test");
00265
00266 }
00267
00268
00269
00270
00271
00272 TEST_F(OpcUaBinarySerialization, ReadResponse)
00273 {
00274
00275 using namespace OpcUa;
00276 using namespace OpcUa::Binary;
00277
00278 ReadResponse resp;
00279
00280 ASSERT_EQ(resp.TypeId.Encoding, EV_FOUR_BYTE);
00281 ASSERT_EQ(resp.TypeId.FourByteData.NamespaceIndex, 0);
00282 ASSERT_EQ(resp.TypeId.FourByteData.Identifier, OpcUa::READ_RESPONSE);
00283
00284 FILL_TEST_RESPONSE_HEADER(resp.Header);
00285
00286 resp.Results.push_back(OpcUa::DataValue(QualifiedName(1, OpcUa::Names::Root)));
00287
00288 ASSERT_NO_THROW(GetStream() << resp << flush);
00289
00290 char encodingMask = static_cast<char>(OpcUa::DATA_VALUE);
00291 char variantMask = static_cast<char>(OpcUa::VariantType::QUALIFIED_NAME);
00292 const std::vector<char> expectedData = {
00293 1, 0, (char)0x7A, 0x2,
00294
00295 TEST_RESPONSE_HEADER_BINARY_DATA,
00296 1,0,0,0,
00297 encodingMask,
00298 variantMask,
00299 1, 0,
00300 4, 0, 0, 0, 'R','o','o','t',
00301 (char)0xFF,(char)0xFF,(char)0xFF,(char)0xFF
00302 };
00303
00304 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00305 ASSERT_EQ(expectedData.size(), RawSize(resp));
00306 }
00307
00308 TEST_F(OpcUaBinaryDeserialization, ReadResponse_with_QualifiedName_as_value)
00309 {
00310
00311 using namespace OpcUa;
00312 using namespace OpcUa::Binary;
00313
00314 char variantMask = static_cast<uint8_t>(VariantType::QUALIFIED_NAME);
00315 char encodingMask = DATA_VALUE;
00316
00317 const std::vector<char> expectedData = {
00318 1, 0, (char)0x7A, 0x2,
00319
00320 TEST_RESPONSE_HEADER_BINARY_DATA,
00321 1,0,0,0,
00322 encodingMask,
00323 variantMask,
00324 1, 0,
00325 4, 0, 0, 0, 'R','o','o','t',
00326 0,0,0,0
00327 };
00328
00329 GetChannel().SetData(expectedData);
00330 ReadResponse resp;
00331 GetStream() >> resp;
00332
00333 ASSERT_EQ(resp.TypeId.Encoding, EV_FOUR_BYTE);
00334 ASSERT_EQ(resp.TypeId.FourByteData.NamespaceIndex, 0);
00335 ASSERT_EQ(resp.TypeId.FourByteData.Identifier, OpcUa::READ_RESPONSE);
00336
00337 ASSERT_RESPONSE_HEADER_EQ(resp.Header);
00338 ASSERT_EQ(resp.Results.size(), 1);
00339 }
00340
00341
00342 TEST_F(OpcUaBinaryDeserialization, ReadResponse)
00343 {
00344
00345 using namespace OpcUa;
00346 using namespace OpcUa::Binary;
00347
00348 char variantMask = static_cast<uint8_t>(VariantType::BOOLEAN);
00349 char encodingMask =
00350 DATA_VALUE |
00351 DATA_VALUE_STATUS_CODE |
00352 DATA_VALUE_SOURCE_TIMESTAMP |
00353 DATA_VALUE_Server_TIMESTAMP |
00354 DATA_VALUE_SOURCE_PICOSECONDS |
00355 DATA_VALUE_Server_PICOSECONDS;
00356
00357 const std::vector<char> expectedData = {
00358 1, 0, (char)0x7A, 0x2,
00359
00360 TEST_RESPONSE_HEADER_BINARY_DATA,
00361
00362
00363 1,0,0,0,
00364
00365 encodingMask,
00366 variantMask, 1,
00367 1,0,0,0,
00368 2,0,0,0,0,0,0,0,
00369 3,0,
00370 4,0,0,0,0,0,0,0,
00371 5,0,
00372
00373 0,0,0,0
00374 };
00375
00376 GetChannel().SetData(expectedData);
00377 ReadResponse resp;
00378 GetStream() >> resp;
00379
00380 ASSERT_EQ(resp.TypeId.Encoding, EV_FOUR_BYTE);
00381 ASSERT_EQ(resp.TypeId.FourByteData.NamespaceIndex, 0);
00382 ASSERT_EQ(resp.TypeId.FourByteData.Identifier, OpcUa::READ_RESPONSE);
00383
00384 ASSERT_RESPONSE_HEADER_EQ(resp.Header);
00385 ASSERT_EQ(resp.Results.size(), 1);
00386 }
00387
00388
00389
00390
00391
00392 TEST_F(OpcUaBinarySerialization, WriteValue)
00393 {
00394 using namespace OpcUa;
00395 using namespace OpcUa::Binary;
00396
00397 WriteValue value;
00398 value.NodeId.Encoding = EV_FOUR_BYTE;
00399 value.NodeId.FourByteData.Identifier = 1;
00400 value.AttributeId = AttributeId::DisplayName;
00401 value.Value.Encoding = DATA_VALUE;
00402 value.Value.Value = true;
00403
00404 GetStream() << value << flush;
00405
00406 const std::vector<char> expectedData = {
00407 1,0,1,0,
00408 4,0,0,0,
00409 -1,-1,-1,-1,
00410 1, 1, 1
00411 };
00412
00413 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00414 ASSERT_EQ(expectedData.size(), RawSize(value));
00415 }
00416
00417 TEST_F(OpcUaBinaryDeserialization, WriteValue)
00418 {
00419
00420 using namespace OpcUa;
00421 using namespace OpcUa::Binary;
00422
00423 const std::vector<char> expectedData = {
00424 1,0,1,0,
00425 4,0,0,0,
00426 -1,-1,-1,-1,
00427 1, 1, 1
00428 };
00429
00430
00431 GetChannel().SetData(expectedData);
00432 WriteValue value;
00433 GetStream() >> value;
00434
00435 ASSERT_EQ(value.NodeId.Encoding, EV_FOUR_BYTE);
00436 ASSERT_EQ(value.NodeId.FourByteData.Identifier, 1);
00437 ASSERT_EQ(value.AttributeId, AttributeId::DisplayName);
00438 ASSERT_EQ(value.Value.Encoding, DATA_VALUE);
00439 ASSERT_EQ(value.Value.Value.Type(), VariantType::BOOLEAN);
00440 ASSERT_EQ(value.Value.Value.As<bool>(), true);
00441 }
00442
00443
00444
00445
00446
00447
00448 TEST_F(OpcUaBinarySerialization, WriteRequest)
00449 {
00450
00451 using namespace OpcUa;
00452 using namespace OpcUa::Binary;
00453
00454 WriteRequest request;
00455
00456 ASSERT_EQ(request.TypeId.Encoding, EV_FOUR_BYTE);
00457 ASSERT_EQ(request.TypeId.FourByteData.NamespaceIndex, 0);
00458 ASSERT_EQ(request.TypeId.FourByteData.Identifier, OpcUa::WRITE_REQUEST);
00459
00460 FILL_TEST_REQUEST_HEADER(request.Header);
00461
00462 WriteValue value;
00463 value.NodeId.Encoding = EV_FOUR_BYTE;
00464 value.NodeId.FourByteData.Identifier = 1;
00465 value.AttributeId = AttributeId::DisplayName;
00466 value.Value.Encoding = DATA_VALUE;
00467 value.Value.Value = true;
00468
00469 request.Parameters.NodesToWrite.push_back(value);
00470
00471 GetStream() << request << flush;
00472
00473 const std::vector<char> expectedData = {
00474 1, 0, (char)0xA1, 0x2,
00475
00476 TEST_REQUEST_HEADER_BINARY_DATA,
00477
00478 1,0,0,0,
00479
00480 1,0,1,0,
00481 4,0,0,0,
00482 -1,-1,-1,-1,
00483 1, 1, 1
00484 };
00485
00486 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00487 ASSERT_EQ(expectedData.size(), RawSize(request));
00488 }
00489
00490 TEST_F(OpcUaBinaryDeserialization, WriteRequest)
00491 {
00492
00493 using namespace OpcUa;
00494 using namespace OpcUa::Binary;
00495
00496 const std::vector<char> expectedData = {
00497 1, 0, (char)0xA1, 0x2,
00498
00499 TEST_REQUEST_HEADER_BINARY_DATA,
00500
00501 1,0,0,0,
00502 1,0,1,0,
00503 4,0,0,0,
00504 -1,-1,-1,-1,
00505 1, 1, 1
00506 };
00507
00508
00509
00510 GetChannel().SetData(expectedData);
00511 WriteRequest request;
00512 GetStream() >> request;
00513
00514
00515 ASSERT_EQ(request.TypeId.Encoding, EV_FOUR_BYTE);
00516 ASSERT_EQ(request.TypeId.FourByteData.NamespaceIndex, 0);
00517 ASSERT_EQ(request.TypeId.FourByteData.Identifier, OpcUa::WRITE_REQUEST);
00518
00519 ASSERT_REQUEST_HEADER_EQ(request.Header);
00520
00521
00522 ASSERT_EQ(request.Parameters.NodesToWrite.size(), 1);
00523 ASSERT_EQ(request.Parameters.NodesToWrite[0].NodeId.Encoding, EV_FOUR_BYTE);
00524 ASSERT_EQ(request.Parameters.NodesToWrite[0].NodeId.FourByteData.Identifier, 1);
00525 ASSERT_EQ(request.Parameters.NodesToWrite[0].AttributeId, AttributeId::DisplayName);
00526 ASSERT_EQ(request.Parameters.NodesToWrite[0].Value.Encoding, DATA_VALUE);
00527 ASSERT_EQ(request.Parameters.NodesToWrite[0].Value.Value.Type(), VariantType::BOOLEAN);
00528 ASSERT_EQ(request.Parameters.NodesToWrite[0].Value.Value.As<bool>(), true);
00529 }
00530
00531
00532
00533
00534
00535 TEST_F(OpcUaBinarySerialization, WriteResponse)
00536 {
00537 using namespace OpcUa;
00538 using namespace OpcUa::Binary;
00539
00540 WriteResponse resp;
00541
00542 ASSERT_EQ(resp.TypeId.Encoding, EV_FOUR_BYTE);
00543 ASSERT_EQ(resp.TypeId.FourByteData.NamespaceIndex, 0);
00544 ASSERT_EQ(resp.TypeId.FourByteData.Identifier, OpcUa::WRITE_RESPONSE);
00545
00546 FILL_TEST_RESPONSE_HEADER(resp.Header);
00547
00548 resp.Results.push_back(static_cast<StatusCode>(1));
00549
00550 DiagnosticInfo info;
00551 info.EncodingMask = static_cast<DiagnosticInfoMask>(DIM_LOCALIZED_TEXT);
00552 info.LocalizedText = 4;
00553 resp.DiagnosticInfos.push_back(info);
00554
00555 GetStream() << resp << flush;
00556
00557 const std::vector<char> expectedData = {
00558 1, 0, (char)0xA4, 0x2,
00559
00560 TEST_RESPONSE_HEADER_BINARY_DATA,
00561
00562 1,0,0,0, 1,0,0,0,
00563 1,0,0,0, static_cast<DiagnosticInfoMask>(DIM_LOCALIZED_TEXT), 4,0,0,0
00564 };
00565
00566 ASSERT_EQ(expectedData, GetChannel().SerializedData) << PrintData(GetChannel().SerializedData) << std::endl << PrintData(expectedData);
00567 ASSERT_EQ(expectedData.size(), RawSize(resp));
00568 }
00569
00570 TEST_F(OpcUaBinaryDeserialization, WriteResponse)
00571 {
00572 using namespace OpcUa;
00573 using namespace OpcUa::Binary;
00574
00575 const std::vector<char> expectedData = {
00576 1, 0, (char)0xA4, 0x2,
00577
00578 TEST_RESPONSE_HEADER_BINARY_DATA,
00579
00580 1,0,0,0, 1,0,0,0,
00581 1,0,0,0, static_cast<DiagnosticInfoMask>(DIM_LOCALIZED_TEXT), 4,0,0,0
00582 };
00583
00584 GetChannel().SetData(expectedData);
00585 WriteResponse resp;
00586 GetStream() >> resp;
00587
00588
00589 ASSERT_EQ(resp.TypeId.Encoding, EV_FOUR_BYTE);
00590 ASSERT_EQ(resp.TypeId.FourByteData.NamespaceIndex, 0);
00591 ASSERT_EQ(resp.TypeId.FourByteData.Identifier, OpcUa::WRITE_RESPONSE);
00592
00593 ASSERT_RESPONSE_HEADER_EQ(resp.Header);
00594
00595 ASSERT_EQ(resp.Results.size(), 1);
00596 ASSERT_EQ(resp.Results[0], static_cast<OpcUa::StatusCode>(1));
00597
00598 ASSERT_EQ(resp.DiagnosticInfos.size(), 1);
00599 ASSERT_EQ(resp.DiagnosticInfos[0].EncodingMask, static_cast<DiagnosticInfoMask>(DIM_LOCALIZED_TEXT));
00600 ASSERT_EQ(resp.DiagnosticInfos[0].LocalizedText, 4);
00601 }
00602