You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@nifi.apache.org by GitBox <gi...@apache.org> on 2019/09/30 22:41:01 UTC

[GitHub] [nifi-minifi-cpp] arpadboda commented on a change in pull request #635: MINIFICPP-819 - OPC Unified Architecture Support

arpadboda commented on a change in pull request #635: MINIFICPP-819 - OPC Unified Architecture Support
URL: https://github.com/apache/nifi-minifi-cpp/pull/635#discussion_r329725783
 
 

 ##########
 File path: extensions/opc/src/opc.cpp
 ##########
 @@ -0,0 +1,461 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//OPC includes
+#include "opc.h"
+
+//MiNiFi includes
+#include "utils/StringUtils.h"
+#include "logging/Logger.h"
+#include "Exception.h"
+
+//Standard includes
+#include <stdlib.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include <string>
+
+namespace org {
+namespace apache {
+namespace nifi {
+namespace minifi {
+namespace opc {
+
+/*
+ * The following functions are only used internally in OPC lib, not to be exported
+ */
+
+void add_value_to_variant(UA_Variant *variant, std::string& value) {
+  UA_String ua_value = UA_STRING(&value[0]);
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_STRING]);
+}
+
+void add_value_to_variant(UA_Variant *variant, const char* value) {
+  std::string strvalue(value);
+  add_value_to_variant(variant, strvalue);
+}
+
+void add_value_to_variant(UA_Variant *variant, int64_t value) {
+  UA_Int64 ua_value = value;
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_INT64]);
+}
+
+void add_value_to_variant(UA_Variant *variant, uint64_t value) {
+  UA_UInt64 ua_value = value;
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_UINT64]);
+}
+
+void add_value_to_variant(UA_Variant *variant, int32_t value) {
+  UA_Int32 ua_value = value;
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_INT32]);
+}
+
+void add_value_to_variant(UA_Variant *variant, uint32_t value) {
+  UA_UInt32 ua_value = value;
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_UINT32]);
+}
+
+void add_value_to_variant(UA_Variant *variant, bool value) {
+  UA_Boolean ua_value = value;
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_BOOLEAN]);
+}
+
+void add_value_to_variant(UA_Variant *variant, float value) {
+  UA_Float ua_value = value;
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_FLOAT]);
+}
+
+void add_value_to_variant(UA_Variant *variant, double value) {
+  UA_Double ua_value = value;
+  UA_Variant_setScalarCopy(variant, &ua_value, &UA_TYPES[UA_TYPES_DOUBLE]);
+}
+
+/*
+ * End of internal functions
+ */
+
+
+template <typename T>
+UA_StatusCode update_node(ClientPtr& clientPtr, const UA_NodeId nodeId, T value) {
+  UA_Variant *variant = UA_Variant_new();
+  add_value_to_variant(variant, value);
+  UA_StatusCode sc = UA_Client_writeValueAttribute(clientPtr.get(), nodeId, variant);
+  UA_Variant_delete(variant);
+  return sc;
+};
+
+template UA_StatusCode update_node<int64_t>(ClientPtr& clientPtr, const UA_NodeId nodeId, int64_t value);
+template UA_StatusCode update_node<uint64_t>(ClientPtr& clientPtr, const UA_NodeId nodeId, uint64_t value);
+template UA_StatusCode update_node<int32_t>(ClientPtr& clientPtr, const UA_NodeId nodeId, int32_t value);
+template UA_StatusCode update_node<uint32_t>(ClientPtr& clientPtr, const UA_NodeId nodeId, uint32_t value);
+template UA_StatusCode update_node<float>(ClientPtr& clientPtr, const UA_NodeId nodeId, float value);
+template UA_StatusCode update_node<double>(ClientPtr& clientPtr, const UA_NodeId nodeId, double value);
+template UA_StatusCode update_node<bool>(ClientPtr& clientPtr, const UA_NodeId nodeId, bool value);
+template UA_StatusCode update_node<const char *>(ClientPtr& clientPtr, const UA_NodeId nodeId, const char * value);
+template UA_StatusCode update_node<std::string>(ClientPtr& clientPtr, const UA_NodeId nodeId, std::string value);
+
+template <typename T>
+UA_StatusCode add_node(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, T value, OPCNodeDataType dt, UA_NodeId *receivedNodeId)
+{
+  //UA_NODEID_NUMERIC(1, 0)
+  UA_VariableAttributes attr = UA_VariableAttributes_default;
+  add_value_to_variant(&attr.value, value);
+  char local[6] = "en-US";
+  attr.displayName = UA_LOCALIZEDTEXT(local, const_cast<char*>(browseName.c_str()));
+  return UA_Client_addVariableNode(clientPtr.get(),
+      targetNodeId,
+      parentNodeId,
+      UA_NODEID_NUMERIC(0, OPCNodeDataTypeToTypeID(dt)),
+      UA_QUALIFIEDNAME(1, const_cast<char*>(browseName.c_str())),
+      UA_NODEID_NULL,
+      attr, receivedNodeId);
+}
+
+template UA_StatusCode add_node<int64_t>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, int64_t value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<uint64_t>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, uint64_t value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<int32_t>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, int32_t value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<uint32_t>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, uint32_t value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<float>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, float value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<double>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, double value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<bool>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, bool value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<const char *>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, const char * value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+template UA_StatusCode add_node<std::string>(ClientPtr& clientPtr, const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, std::string value, OPCNodeDataType dt, UA_NodeId *receivedNodeId);
+
+int32_t OPCNodeDataTypeToTypeID(OPCNodeDataType dt) {
+  switch(dt)
+  {
+    case OPCNodeDataType::Boolean:
+      return UA_NS0ID_BOOLEAN;
+    case OPCNodeDataType::Int32:
+      return UA_NS0ID_INT32;
+    case OPCNodeDataType::UInt32:
+      return UA_NS0ID_UINT32;
+    case OPCNodeDataType::Int64:
+      return UA_NS0ID_INT64;
+    case OPCNodeDataType::UInt64:
+      return UA_NS0ID_UINT64;
+    case OPCNodeDataType::Float:
+      return UA_NS0ID_FLOAT;
+    case OPCNodeDataType::Double:
+      return UA_NS0ID_DOUBLE;
+    case OPCNodeDataType::String:
+      return UA_NS0ID_STRING;
+    default:
+      throw Exception(OPC_EXCEPTION, "Data type is not supported");
+  }
+}
+
+void disconnect(UA_Client *client) {
+  if(client == nullptr) {
+    return;
+  }
+  if(UA_Client_getState(client) != UA_CLIENTSTATE_DISCONNECTED) {
+    UA_Client_disconnect(client);
+  }
+  UA_Client_delete(client);
+}
+
+void setCertificates(ClientPtr& clientPtr, const std::vector<char>& certBuffer, const std::vector<char>& keyBuffer) {
+  UA_ClientConfig *cc = UA_Client_getConfig(clientPtr.get());
+  cc->securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
+
+  UA_ByteString certByteString = UA_BYTESTRING_ALLOC(certBuffer.data());
+  UA_ByteString keyByteString = UA_BYTESTRING_ALLOC(keyBuffer.data());
+
+  UA_ClientConfig_setDefaultEncryption(cc, certByteString, keyByteString,
 
 Review comment:
   Yep, added logging and return for failure case, thanks!

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services