Prechádzať zdrojové kódy

added PubSubConnection information model representation and methods

Andreas Ebner 6 rokov pred
rodič
commit
72853d143e

+ 6 - 0
include/ua_server_pubsub.h

@@ -100,9 +100,15 @@ _UA_BEGIN_DECLS
  * Take a look on the PubSub Tutorials for mor details about the API usage.
  */
 
+typedef enum {
+    UA_PUBSUB_PUBLISHERID_NUMERIC,
+    UA_PUBSUB_PUBLISHERID_STRING
+} UA_PublisherIdType;
+
 typedef struct {
     UA_String name;
     UA_Boolean enabled;
+    UA_PublisherIdType publisherIdType;
     union { /* std: valid types UInt or String */
         UA_UInt32 numeric;
         UA_String string;

+ 152 - 2
src/pubsub/ua_pubsub_ns0.c

@@ -5,11 +5,14 @@
  * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner)
  */
 
+#include "ua_server_pubsub.h"
+#include "src_generated/ua_types_generated.h"
 #include "ua_server_pubsub.h"
 #include "ua_types.h"
 #include "ua_types.h"
 #include "ua_pubsub_ns0.h"
 #include "ua_pubsub.h"
+#include "src_generated/ua_types_generated_encoding_binary.h"
 
 #ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL /* conditional compilation */
 
@@ -77,8 +80,22 @@ onRead(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
     UA_Variant_init(&value);
     UA_NodeId myNodeId;
 	UA_WriterGroup *writerGroup = NULL;
+    UA_PubSubConnection *pubSubConnection = NULL;
     switch(((UA_NodePropertyContext *) nodeContext)->parentCalssifier){
         case UA_NS0ID_PUBSUBCONNECTIONTYPE:
+            myNodeId = ((UA_NodePropertyContext *) nodeContext)->parentNodeId;
+            pubSubConnection = UA_PubSubConnection_findConnectionbyId(server, myNodeId);
+            switch(((UA_NodePropertyContext *) nodeContext)->elementClassiefier) {
+                case UA_NS0ID_PUBSUBCONNECTIONTYPE_PUBLISHERID:
+                    if(pubSubConnection->config->publisherIdType == UA_PUBSUB_PUBLISHERID_STRING) {
+                        UA_Variant_setScalar(&value, &pubSubConnection->config->publisherId.numeric,
+                                             &UA_TYPES[UA_TYPES_STRING]);
+                    }else
+                        UA_Variant_setScalar(&value, &pubSubConnection->config->publisherId.numeric, &UA_TYPES[UA_TYPES_UINT32]);
+                    break;
+                default:
+                    UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, "Read error! Unknown property.");
+            }
             break;
         case UA_NS0ID_WRITERGROUPTYPE:
             myNodeId = ((UA_NodePropertyContext *) nodeContext)->parentNodeId;
@@ -108,6 +125,7 @@ onWrite(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
 	UA_WriterGroup *writerGroup = NULL;
     switch(((UA_NodePropertyContext *) nodeContext)->parentCalssifier){
         case UA_NS0ID_PUBSUBCONNECTIONTYPE:
+            //no runtime writable attributes
             break;
         case UA_NS0ID_WRITERGROUPTYPE:
             myNodeId = ((UA_NodePropertyContext *) nodeContext)->parentNodeId;
@@ -161,9 +179,8 @@ addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connec
     UA_QUALIFIEDNAME(0, connectionName), UA_NODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE), (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], NULL, &pubSubConnectionNodeId);
     addPubSubObjectNode(server, "Address", connection->identifier.identifier.numeric+1, pubSubConnectionNodeId.identifier.numeric,  UA_NS0ID_HASCOMPONENT, UA_NS0ID_NETWORKADDRESSURLTYPE);
     UA_Server_addNode_finish(server, pubSubConnectionNodeId);
-
     //End lock zone
-    UA_NodeId addressNode, urlNode, interfaceNode;
+    UA_NodeId addressNode, urlNode, interfaceNode, publisherIdNode, connectionPropertieNode, transportProfileUri;
     addressNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "Address"),
                                       UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
                                       UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric));
@@ -171,6 +188,20 @@ addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connec
                                   UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), addressNode);
     interfaceNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "NetworkInterface"),
                                         UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), addressNode);
+    publisherIdNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "PublisherId"),
+                                        UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY),
+                                        UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric));
+    connectionPropertieNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "ConnectionProperties"),
+                                                 UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY),
+                                                 UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric));
+    transportProfileUri = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "TransportProfileUri"),
+                                          UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
+                                          UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric));
+
+    retVal |= writePubSubNs0VariableArray(server, connectionPropertieNode.identifier.numeric,
+                                          connection->config->connectionProperties,
+                                          connection->config->connectionPropertiesSize,
+                                          &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
 
     UA_NetworkAddressUrlDataType *networkAddressUrlDataType = ((UA_NetworkAddressUrlDataType *) connection->config->address.data);
     UA_Variant value;
@@ -179,16 +210,120 @@ addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connec
     UA_Server_writeValue(server, urlNode, value);
     UA_Variant_setScalar(&value, &networkAddressUrlDataType->networkInterface, &UA_TYPES[UA_TYPES_STRING]);
     UA_Server_writeValue(server, interfaceNode, value);
+    UA_Variant_setScalar(&value, &connection->config->transportProfileUri, &UA_TYPES[UA_TYPES_STRING]);
+    UA_Server_writeValue(server, transportProfileUri, value);
+
+    UA_NodePropertyContext *connectionPublisherIdContext = (UA_NodePropertyContext *) UA_malloc(sizeof(UA_NodePropertyContext));
+    connectionPublisherIdContext->parentNodeId = connection->identifier;
+    connectionPublisherIdContext->parentCalssifier = UA_NS0ID_PUBSUBCONNECTIONTYPE;
+    connectionPublisherIdContext->elementClassiefier = UA_NS0ID_PUBSUBCONNECTIONTYPE_PUBLISHERID;
+    UA_ValueCallback valueCallback;
+    valueCallback.onRead = onRead;
+    valueCallback.onWrite = NULL;
+    retVal |= addVariableValueSource(server, valueCallback, publisherIdNode, connectionPublisherIdContext);
+
+#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS
+    retVal |= UA_Server_addReference(server, connection->identifier,
+                                     UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
+                                     UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP), true);
+    retVal |= UA_Server_addReference(server, connection->identifier,
+                                     UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
+                                     UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP), true);
+    retVal |= UA_Server_addReference(server, connection->identifier,
+                                     UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
+                                     UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP), true);
+#endif
     return retVal;
 }
 
+#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS
+static UA_StatusCode
+addPubSubConnectionAction(UA_Server *server,
+                          const UA_NodeId *sessionId, void *sessionHandle,
+                          const UA_NodeId *methodId, void *methodContext,
+                          const UA_NodeId *objectId, void *objectContext,
+                          size_t inputSize, const UA_Variant *input,
+                          size_t outputSize, UA_Variant *output){
+    UA_PubSubConnectionDataType pubSubConnectionDataType = *((UA_PubSubConnectionDataType *) input[0].data);
+    UA_NetworkAddressUrlDataType networkAddressUrlDataType;
+    memset(&networkAddressUrlDataType, 0, sizeof(networkAddressUrlDataType));
+    UA_ExtensionObject eo = pubSubConnectionDataType.address;
+    if(eo.encoding == UA_EXTENSIONOBJECT_ENCODED_BYTESTRING){
+        size_t offset = 0;
+        UA_NetworkAddressUrlDataType_decodeBinary(&eo.content.encoded.body, &offset, &networkAddressUrlDataType);
+        if(networkAddressUrlDataType.url.length > 512)
+            return UA_STATUSCODE_BADOUTOFMEMORY;
+        UA_STACKARRAY(char, buffer, sizeof(char) * networkAddressUrlDataType.url.length +1);
+        memcpy(buffer, networkAddressUrlDataType.url.data, networkAddressUrlDataType.url.length);
+        buffer[networkAddressUrlDataType.url.length] = '\0';
+        printf("%s\n", buffer);
+    }
+
+    UA_PubSubConnectionConfig connectionConfig;
+    memset(&connectionConfig, 0, sizeof(UA_PubSubConnectionConfig));
+    connectionConfig.transportProfileUri = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp");
+    connectionConfig.name = pubSubConnectionDataType.name;
+    UA_Variant_setScalar(&connectionConfig.address, &networkAddressUrlDataType,
+                         &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]);
+    if(pubSubConnectionDataType.publisherId.type == &UA_TYPES[UA_TYPES_UINT32]){
+        connectionConfig.publisherId.numeric = * ((UA_UInt32 *) pubSubConnectionDataType.publisherId.data);
+    } else {
+        connectionConfig.publisherIdType = UA_PUBSUB_PUBLISHERID_STRING;
+        connectionConfig.publisherId.string = * ((UA_String *) pubSubConnectionDataType.publisherId.data);
+    }
+    //call API function and create the connection
+    UA_NodeId connectionId;
+    if(UA_Server_addPubSubConnection(server, &connectionConfig, &connectionId) != UA_STATUSCODE_GOOD){
+        //error handling
+    };
+    for(size_t i = 0; i < pubSubConnectionDataType.writerGroupsSize; i++){
+        //UA_PubSubConnection_addWriterGroup(server, UA_NODEID_NULL, NULL, NULL);
+    };
+    for(size_t i = 0; i < pubSubConnectionDataType.readerGroupsSize; i++){
+        //UA_PubSubConnection_addReaderGroup(server, NULL, NULL, NULL);
+    };
+    UA_NetworkAddressUrlDataType_deleteMembers(&networkAddressUrlDataType);
+    //set ouput value
+    UA_Variant_setScalar(output, &connectionId, &UA_TYPES[UA_TYPES_NODEID]);
+    return UA_STATUSCODE_GOOD;
+}
+#endif
+
 UA_StatusCode
 removePubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connection){
     UA_StatusCode retVal = UA_STATUSCODE_GOOD;
+#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS
+    retVal |= UA_Server_deleteReference(server, connection->identifier, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true,
+                                        UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP),
+                                        false);
+    retVal |= UA_Server_deleteReference(server, connection->identifier, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true,
+                                        UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP),
+                                        false);
+    retVal |= UA_Server_deleteReference(server, connection->identifier, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true,
+                                        UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP),
+                                        false);
+#endif
     retVal |= UA_Server_deleteNode(server, connection->identifier, true);
     return retVal;
 }
 
+#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS
+static UA_StatusCode
+removeConnectionAction(UA_Server *server,
+                       const UA_NodeId *sessionId, void *sessionHandle,
+                       const UA_NodeId *methodId, void *methodContext,
+                       const UA_NodeId *objectId, void *objectContext,
+                       size_t inputSize, const UA_Variant *input,
+                       size_t outputSize, UA_Variant *output){
+    UA_StatusCode retVal = UA_STATUSCODE_GOOD;
+    UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data);
+    retVal |= UA_Server_removePubSubConnection(server, nodeToRemove);
+    if(retVal == UA_STATUSCODE_BADNOTFOUND)
+        retVal = UA_STATUSCODE_BADNODEIDUNKNOWN;
+    return retVal;
+}
+#endif
+
 /*************************************************/
 /*                PublishedDataSet               */
 /*************************************************/
@@ -359,6 +494,21 @@ UA_Server_initPubSubNS0(UA_Server *server) {
     retVal |= writePubSubNs0VariableArray(server, UA_NS0ID_PUBLISHSUBSCRIBE_SUPPORTEDTRANSPORTPROFILES,
                                     profileArray,
                                     1, &UA_TYPES[UA_TYPES_STRING]);
+
+#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS
+    retVal |= UA_Server_setMethodNode_callback(server,
+                                               UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION), addPubSubConnectionAction);
+    retVal |= UA_Server_setMethodNode_callback(server,
+                                               UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION), removeConnectionAction);
+
+#else
+    retVal |= UA_Server_deleteReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true,
+                                        UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION),
+                                        false);
+    retVal |= UA_Server_deleteReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true,
+                                        UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION),
+                                        false);
+#endif
     UA_NodeTypeLifecycle liveCycle;
     liveCycle.constructor = NULL;
     liveCycle.destructor = connectionTypeDestructor;

+ 14 - 21
tests/pubsub/check_pubsub_informationmodel_methods.c

@@ -8,8 +8,9 @@
 #include <string.h>
 #include <math.h>
 #include <src_generated/ua_types_generated.h>
-#include <ua_types.h>
-#include <src_generated/ua_types_generated_encoding_binary.h>
+#include "src_generated/ua_types_generated.h"
+#include "ua_types.h"
+#include "src_generated/ua_types_generated_encoding_binary.h"
 #include "ua_types.h"
 #include "ua_server_pubsub.h"
 #include "src_generated/ua_types_generated.h"
@@ -85,20 +86,6 @@ findSingleChildNode(UA_QualifiedName targetName,
     return resultNodeId;
 }
 
-/*
-static UA_StatusCode startServer(void){
-    config = UA_ServerConfig_new_default();
-    config->pubsubTransportLayers = (UA_PubSubTransportLayer *) UA_malloc(sizeof(UA_PubSubTransportLayer));
-    if(!config->pubsubTransportLayers) {
-        UA_ServerConfig_delete(config);
-    }
-    config->pubsubTransportLayers[0] = UA_PubSubTransportLayerUDPMP();
-    config->pubsubTransportLayersSize++;
-    server = UA_Server_new(config);
-    return UA_Server_run_startup(server);
-
-}*/
-
 START_TEST(AddNewPubSubConnectionUsingTheInformationModelMethod){
     UA_StatusCode retVal;
     UA_Client *client = UA_Client_new(UA_ClientConfig_default);
@@ -122,12 +109,22 @@ START_TEST(AddNewPubSubConnectionUsingTheInformationModelMethod){
 
     UA_ExtensionObject eo;
     eo.encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING;
-    UA_NetworkAddressUrlDataType networkAddressDataType = {UA_STRING_NULL, UA_STRING("opc.udp://224.0.0.22:4840/")};
+    UA_NetworkAddressUrlDataType networkAddressDataType = {UA_STRING("eth0"), UA_STRING("opc.udp://224.0.0.22:4840/")};
     UA_ByteString_allocBuffer(&eo.content.encoded.body, UA_NetworkAddressUrlDataType_calcSizeBinary(&networkAddressDataType));
     UA_Byte *bufPos = eo.content.encoded.body.data;
     UA_NetworkAddressUrlDataType_encodeBinary(&networkAddressDataType, &bufPos, &(eo.content.encoded.body.data[eo.content.encoded.body.length]));
     eo.content.encoded.typeId = UA_NODEID_NUMERIC(0, UA_TYPES_NETWORKADDRESSURLDATATYPE);
     pubSubConnection.address = eo;
+    pubSubConnection.connectionPropertiesSize = 2;
+    UA_KeyValuePair connectionOptions[2];
+    memset(connectionOptions, 0, sizeof(UA_KeyValuePair)* 2);
+    connectionOptions[0].key = UA_QUALIFIEDNAME(0, "ttl");
+    UA_UInt32 ttl = 10;
+    UA_Variant_setScalar(&connectionOptions[0].value, &ttl, &UA_TYPES[UA_TYPES_UINT32]);
+    connectionOptions[1].key = UA_QUALIFIEDNAME(0, "loopback");
+    UA_Boolean loopback = UA_FALSE;
+    UA_Variant_setScalar(&connectionOptions[1].value, &loopback, &UA_TYPES[UA_TYPES_UINT32]);
+    pubSubConnection.connectionProperties = connectionOptions;
 
     UA_Variant inputArguments;
     UA_Variant_init(&inputArguments);
@@ -166,14 +163,10 @@ START_TEST(AddNewPubSubConnectionUsingTheInformationModelMethod){
     ck_assert_int_eq(UA_Server_readValue(server, connectionPublisherId, &serverPubSubConnectionValues),
                      UA_STATUSCODE_GOOD);
     ck_assert_uint_eq(*((UA_UInt32 *) serverPubSubConnectionValues.data), publisherIdValue);
-    //TODO create nd add a connection with string pulisherId
-
-
 
     } END_TEST
 
 int main(void) {
-    //startServer(); //TODO CHECK IF SERVER IS RUNNING
     TCase *tc_add_pubsub_informationmodel_methods_connection = tcase_create("PubSub connection delete and creation using the information model methods");
     tcase_add_checked_fixture(tc_add_pubsub_informationmodel_methods_connection, setup, teardown);
     tcase_add_test(tc_add_pubsub_informationmodel_methods_connection, AddNewPubSubConnectionUsingTheInformationModelMethod);

+ 178 - 10
tools/schema/Opc.Ua.NodeSet2.PubSubMinimal.xml

@@ -14,8 +14,8 @@
     <References>
 
       <!--      <Reference ReferenceType="HasComponent">i=17296</Reference>  SetSecurityKeys
-            <Reference ReferenceType="HasComponent">i=15844</Reference> Status
             <Reference ReferenceType="HasComponent">i=18715</Reference> Diagnostics SupportedTransportProfiles-->
+      <Reference ReferenceType="HasComponent">i=15844</Reference> <!--Status-->
       <Reference ReferenceType="i=14476">i=14417</Reference>
       <Reference ReferenceType="HasProperty">i=17479</Reference>
       <Reference ReferenceType="HasComponent">i=14434</Reference>
@@ -355,6 +355,23 @@
       <Reference ReferenceType="HasComponent" IsForward="false">i=14416</Reference>
     </References>
   </UAObject>
+  <UAObject NodeId="i=15844" BrowseName="Status" ParentNodeId="i=14416">
+    <DisplayName>Status</DisplayName>
+    <References>
+      <Reference ReferenceType="HasComponent">i=15845</Reference>
+      <Reference ReferenceType="HasTypeDefinition">i=14643</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=14416</Reference>
+    </References>
+  </UAObject>
+  <UAVariable NodeId="i=15845" BrowseName="State" ParentNodeId="i=15844" DataType="i=14647">
+    <DisplayName>State</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=15844</Reference>
+    </References>
+  </UAVariable>
   <UAObjectType NodeId="i=14509" BrowseName="PublishedDataSetType">
     <DisplayName>PublishedDataSetType</DisplayName>
       <References>
@@ -410,6 +427,51 @@
       <Field Name="SimpleDataTypes" DataType="i=15005" ValueRank="1" />-->
     </Definition>
   </UADataType>
+  <UADataType NodeId="i=14647" BrowseName="PubSubState">
+    <DisplayName>PubSubState</DisplayName>
+    <References>
+      <Reference ReferenceType="HasProperty">i=14648</Reference>
+      <Reference ReferenceType="HasSubtype" IsForward="false">i=29</Reference>
+    </References>
+    <Definition Name="PubSubState">
+      <Field Name="Disabled" Value="0" />
+      <Field Name="Paused" Value="1" />
+      <Field Name="Operational" Value="2" />
+      <Field Name="Error" Value="3" />
+    </Definition>
+  </UADataType>
+  <UAVariable NodeId="i=14648" BrowseName="EnumStrings" ParentNodeId="i=14647" DataType="LocalizedText" ValueRank="1">
+    <DisplayName>EnumStrings</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=14647</Reference>
+    </References>
+    <Value>
+      <ListOfLocalizedText xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
+        <LocalizedText>
+          <Locale>
+          </Locale>
+          <Text>Disabled</Text>
+        </LocalizedText>
+        <LocalizedText>
+          <Locale>
+          </Locale>
+          <Text>Paused</Text>
+        </LocalizedText>
+        <LocalizedText>
+          <Locale>
+          </Locale>
+          <Text>Operational</Text>
+        </LocalizedText>
+        <LocalizedText>
+          <Locale>
+          </Locale>
+          <Text>Error</Text>
+        </LocalizedText>
+      </ListOfLocalizedText>
+    </Value>
+  </UAVariable>
   <UADataType NodeId="i=14523" BrowseName="DataSetMetaDataType">
     <DisplayName>DataSetMetaDataType</DisplayName>
     <References>
@@ -719,12 +781,31 @@
       <Field Name="PublisherId" />
       <Field Name="TransportProfileUri" DataType="i=12" />
       <Field Name="Address" DataType="i=22" />
-      <!--      <Field Name="ConnectionProperties" DataType="i=14533" ValueRank="1" />
-            <Field Name="TransportSettings" DataType="i=22" />
+      <Field Name="ConnectionProperties" DataType="i=14533" ValueRank="1" />
+      <!--      <Field Name="TransportSettings" DataType="i=22" />
             <Field Name="WriterGroups" DataType="i=15480" ValueRank="1" />
             <Field Name="ReaderGroups" DataType="i=15520" ValueRank="1" />-->
     </Definition>
   </UADataType>
+  <UADataType NodeId="i=14533" BrowseName="KeyValuePair">
+    <DisplayName>KeyValuePair</DisplayName>
+    <References>
+      <Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
+    </References>
+    <Definition Name="KeyValuePair">
+      <Field Name="Key" DataType="i=20" />
+      <Field Name="Value" />
+    </Definition>
+  </UADataType>
+  <UADataType NodeId="i=16313" BrowseName="AdditionalParametersType" ReleaseStatus="Draft">
+    <DisplayName>AdditionalParametersType</DisplayName>
+    <References>
+      <Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
+    </References>
+    <Definition Name="AdditionalParametersType">
+      <Field Name="Parameters" DataType="i=14533" ValueRank="1" />
+    </Definition>
+  </UADataType>
   <UADataType NodeId="i=15581" BrowseName="PublishedDataItemsDataType">
     <DisplayName>PublishedDataItemsDataType</DisplayName>
     <References>
@@ -766,16 +847,25 @@
       <Reference ReferenceType="HasComponent">i=17427</Reference> <!--AddWriterGroup-->
       <Reference ReferenceType="HasComponent">i=14225</Reference> <!--RemoveGroup-->
       <Reference ReferenceType="HasComponent">i=17465</Reference> <!--AddReaderGroup-->
+      <Reference ReferenceType="HasProperty">i=17485</Reference>  <!--ConnectionProperties-->
+      <Reference ReferenceType="HasComponent">i=14600</Reference> <!--Status -->
+      <Reference ReferenceType="HasComponent">i=17203</Reference> <!--TransportSettings-->
+
 
       <!--
-            <Reference ReferenceType="HasProperty">i=17485</Reference> ConnectionProperties
-            <Reference ReferenceType="HasComponent">i=17203</Reference> TransportSettings
             <Reference ReferenceType="HasComponent">i=17325</Reference> ReaderGroupName
-            <Reference ReferenceType="HasComponent">i=14600</Reference> Status
             <Reference ReferenceType="HasComponent">i=19241</Reference> Diagnostics -->
       <Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
     </References>
   </UAObjectType>
+  <UAVariable NodeId="i=17485" BrowseName="ConnectionProperties" ParentNodeId="i=14209" DataType="i=14533" ValueRank="1">
+    <DisplayName>ConnectionProperties</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=14209</Reference>
+    </References>
+  </UAVariable>
   <UAObject NodeId="i=14221" BrowseName="Address" ParentNodeId="i=14209">
     <DisplayName>Address</DisplayName>
     <References>
@@ -823,6 +913,14 @@
       <Reference ReferenceType="HasComponent" IsForward="false">i=21147</Reference>
     </References>
   </UAVariable>
+  <UAObject NodeId="i=17203" BrowseName="TransportSettings" ParentNodeId="i=14209">
+    <DisplayName>TransportSettings</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=17721</Reference>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=14209</Reference>
+    </References>
+  </UAObject>
   <UAObject NodeId="i=17310" BrowseName="&lt;WriterGroupName&gt;" SymbolicName="WriterGroupName_Placeholder" ParentNodeId="i=14209">
     <DisplayName>&lt;WriterGroupName&gt;</DisplayName>
     <References>
@@ -841,6 +939,23 @@
             <Reference ReferenceType="HasComponent" IsForward="false">i=14209</Reference>-->
     </References>
   </UAObject>
+  <UAObject NodeId="i=14600" BrowseName="Status" ParentNodeId="i=14209">
+    <DisplayName>Status</DisplayName>
+    <References>
+      <Reference ReferenceType="HasComponent">i=14601</Reference>
+      <Reference ReferenceType="HasTypeDefinition">i=14643</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=14209</Reference>
+    </References>
+  </UAObject>
+  <UAVariable NodeId="i=14601" BrowseName="State" ParentNodeId="i=14600" DataType="i=14647">
+    <DisplayName>State</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=14600</Reference>
+    </References>
+  </UAVariable>
   <UAMethod NodeId="i=17427" BrowseName="AddWriterGroup" ParentNodeId="i=14209">
     <DisplayName>AddWriterGroup</DisplayName>
     <References>
@@ -1007,6 +1122,12 @@
       </ListOfExtensionObject>
     </Value>
   </UAVariable>
+  <UAObjectType NodeId="i=17721" BrowseName="ConnectionTransportType" IsAbstract="true">
+    <DisplayName>ConnectionTransportType</DisplayName>
+    <References>
+      <Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
+    </References>
+  </UAObjectType>
   <UAObjectType NodeId="i=14232" BrowseName="PubSubGroupType">
     <DisplayName>PubSubGroupType</DisplayName>
     <References>
@@ -1139,6 +1260,37 @@
       <Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
     </References>
   </UAObjectType>
+  <UAObjectType NodeId="i=14643" BrowseName="PubSubStatusType">
+    <DisplayName>PubSubStatusType</DisplayName>
+    <References>
+      <Reference ReferenceType="HasComponent">i=14644</Reference>
+      <Reference ReferenceType="HasComponent">i=14645</Reference>
+      <Reference ReferenceType="HasComponent">i=14646</Reference>
+      <Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
+    </References>
+  </UAObjectType>
+  <UAVariable NodeId="i=14644" BrowseName="State" ParentNodeId="i=14643" DataType="i=14647">
+    <DisplayName>State</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=14643</Reference>
+    </References>
+  </UAVariable>
+  <UAMethod NodeId="i=14645" BrowseName="Enable" ParentNodeId="i=14643">
+    <DisplayName>Enable</DisplayName>
+    <References>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=14643</Reference>
+    </References>
+  </UAMethod>
+  <UAMethod NodeId="i=14646" BrowseName="Disable" ParentNodeId="i=14643">
+    <DisplayName>Disable</DisplayName>
+    <References>
+      <Reference ReferenceType="HasModellingRule">i=80</Reference>
+      <Reference ReferenceType="HasComponent" IsForward="false">i=14643</Reference>
+    </References>
+  </UAMethod>
   <UAVariableType NodeId="i=16309" BrowseName="SelectionListType" DataType="i=862" ValueRank="-2">
     <DisplayName>SelectionListType</DisplayName>
     <References>
@@ -1188,15 +1340,31 @@
       <Reference ReferenceType="i=14476" IsForward="false">i=14416</Reference>
       <Reference ReferenceType="HasComponent">i=14423</Reference>
       <Reference ReferenceType="HasComponent">i=17292</Reference> <!--TransportProfileUri-->
+      <Reference ReferenceType="HasProperty">i=14418</Reference>  <!--PublisherId -->
+      <Reference ReferenceType="HasProperty">i=17478</Reference>  <!--ConnectionProperties -->
+
     </References>
 
     <!--<References>
-      <Reference ReferenceType="HasProperty">i=14418</Reference> PublisherId
-
-      <Reference ReferenceType="HasProperty">i=17478</Reference> ConnectionProperties
       <Reference ReferenceType="HasComponent">i=14419</Reference> Status
     </References>-->
   </UAObject>
+    <UAVariable NodeId="i=14418" BrowseName="PublisherId" ParentNodeId="i=14417">
+    <DisplayName>PublisherId</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=14417</Reference>
+    </References>
+  </UAVariable>
+  <UAVariable NodeId="i=17478" BrowseName="ConnectionProperties" ParentNodeId="i=14417" DataType="i=14533" ValueRank="1">
+    <DisplayName>ConnectionProperties</DisplayName>
+    <References>
+      <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
+      <Reference ReferenceType="HasModellingRule">i=78</Reference>
+      <Reference ReferenceType="HasProperty" IsForward="false">i=14417</Reference>
+    </References>
+  </UAVariable>
   <UAObject NodeId="i=14423" BrowseName="Address" ParentNodeId="i=14417">
     <DisplayName>Address</DisplayName>
     <References>
@@ -1223,7 +1391,7 @@
             <Reference ReferenceType="HasComponent">i=17405</Reference> Status
             <Reference ReferenceType="HasComponent">i=17409</Reference> Diagnostics-->
       <Reference ReferenceType="HasProperty">i=17481</Reference>
-      <Reference ReferenceType="HasComponent">i=17366</Reference>
+      <Reference ReferenceType="HasComponent">i=17366</Reference> <!-- addConnection -->
       <Reference ReferenceType="HasComponent">i=17369</Reference>
       <Reference ReferenceType="HasComponent">i=17371</Reference>
       <Reference ReferenceType="HasComponent" IsForward="false">i=2253</Reference>

+ 1 - 0
tools/schema/datatypes_pubsub.txt

@@ -24,3 +24,4 @@ WriterGroupDataType
 ReaderGroupDataType
 DataSetWriterDataType
 DataSetReaderDataType
+PubSubState