binary_serialize_attribute.cpp
Go to the documentation of this file.
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 // AttributeId
00025 // //TODO Add check for ivalid attributeId deserialization. It must throw.
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 // TimestampsToReturn
00064 // TODO Add test for invalid Timestamps to return deserialization.
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 // ReadValueId
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 // ReadRequest
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, // TypeId
00201   // RequestHeader
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, // TypeId
00228   // RequestHeader
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 // ReadResponse
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, // TypeId
00294   // RequestHeader
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, // TypeId
00319       // RequestHeader
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, // TypeId
00359   // RequestHeader
00360   TEST_RESPONSE_HEADER_BINARY_DATA,
00361 
00362   // Results
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 // WriteValue
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, // Node
00408   4,0,0,0, // AttributeId
00409   -1,-1,-1,-1, // NumericRange  
00410   1, 1, 1 // NodesToWrite
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, // Node
00425   4,0,0,0, // AttributeId
00426   -1,-1,-1,-1, // NumericRange  
00427   1, 1, 1 // NodesToWrite
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 // WriteRequest
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, // TypeId
00475   // RequestHeader
00476   TEST_REQUEST_HEADER_BINARY_DATA,
00477 
00478   1,0,0,0,
00479 
00480   1,0,1,0, // Node
00481   4,0,0,0, // AttributeId
00482   -1,-1,-1,-1, // NumericRange  
00483   1, 1, 1 // NodesToWrite
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, // TypeId
00498   // RequestHeader
00499   TEST_REQUEST_HEADER_BINARY_DATA,
00500 
00501   1,0,0,0,
00502   1,0,1,0, // Node
00503   4,0,0,0, // AttributeId
00504   -1,-1,-1,-1, // NumericRange  
00505   1, 1, 1 // Value
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 // WriteResponse
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, // TypeId
00559   // RequestHeader
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, // TypeId
00577   // RequestHeader
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 


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