Browse Source

definitive way to define client's properties, refers to #219

Stasik0 10 years ago
parent
commit
03cd734988
3 changed files with 126 additions and 114 deletions
  1. 77 77
      examples/client.c
  2. 9 4
      include/ua_client.h
  3. 40 33
      src/client/ua_client.c

+ 77 - 77
examples/client.c

@@ -1,97 +1,97 @@
 #ifdef NOT_AMALGATED
-	#include "ua_types.h"
-	#include "ua_client.h"
-	#include "ua_nodeids.h"
+    #include "ua_types.h"
+    #include "ua_client.h"
+    #include "ua_nodeids.h"
 #else
-	#include "open62541.h"
+    #include "open62541.h"
 #endif
 
 #include <stdio.h>
 #include "networklayer_tcp.h"
 
 int main(int argc, char *argv[]) {
-	UA_Client *client = UA_Client_new();
-	UA_Client_setConfig(client, (UA_ClientConfig){.timeout=500});
-	UA_ClientNetworkLayer nl = ClientNetworkLayerTCP_new(UA_ConnectionConfig_standard);
-	UA_StatusCode retval = UA_Client_connect(client, UA_ConnectionConfig_standard, nl,
-			"opc.tcp://localhost:16664");
-	if(retval != UA_STATUSCODE_GOOD) {
-		UA_Client_delete(client);
-		return retval;
-	}
+    UA_Client *client = UA_Client_new();
+    client->config.timeout=500;
+    UA_ClientNetworkLayer nl = ClientNetworkLayerTCP_new(UA_ConnectionConfig_standard);
+    UA_StatusCode retval = UA_Client_connect(client, UA_ConnectionConfig_standard, nl,
+            "opc.tcp://localhost:16664");
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_Client_delete(client);
+        return retval;
+    }
 
-	// Browse some objects
-	printf("Browsing nodes in objects folder:\n");
+    // Browse some objects
+    printf("Browsing nodes in objects folder:\n");
 
-	UA_BrowseRequest bReq;
-	UA_BrowseRequest_init(&bReq);
-	bReq.requestedMaxReferencesPerNode = 0;
-	bReq.nodesToBrowse = UA_BrowseDescription_new();
-	bReq.nodesToBrowseSize = 1;
-	bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); //browse objects folder
-	bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL;	//return everything
+    UA_BrowseRequest bReq;
+    UA_BrowseRequest_init(&bReq);
+    bReq.requestedMaxReferencesPerNode = 0;
+    bReq.nodesToBrowse = UA_BrowseDescription_new();
+    bReq.nodesToBrowseSize = 1;
+    bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); //browse objects folder
+    bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL;	//return everything
 
-	UA_BrowseResponse bResp = UA_Client_browse(client, &bReq);
-	printf("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME");
-	for (int i = 0; i < bResp.resultsSize; ++i) {
-		for (int j = 0; j < bResp.results[i].referencesSize; ++j) {
-			UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
-			if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC){
-				printf("%-9d %-16d %-16.*s %-16.*s\n", ref->browseName.namespaceIndex, ref->nodeId.nodeId.identifier.numeric, ref->browseName.name.length, ref->browseName.name.data, ref->displayName.text.length, ref->displayName.text.data);
-			}else if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING){
-				printf("%-9d %-16.*s %-16.*s %-16.*s\n", ref->browseName.namespaceIndex, ref->nodeId.nodeId.identifier.string.length, ref->nodeId.nodeId.identifier.string.data, ref->browseName.name.length, ref->browseName.name.data, ref->displayName.text.length, ref->displayName.text.data);
-			}
-			//TODO: distinguish further types
-		}
-	}
-	UA_BrowseRequest_deleteMembers(&bReq);
-	UA_BrowseResponse_deleteMembers(&bResp);
+    UA_BrowseResponse bResp = UA_Client_browse(client, &bReq);
+    printf("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME");
+    for (int i = 0; i < bResp.resultsSize; ++i) {
+        for (int j = 0; j < bResp.results[i].referencesSize; ++j) {
+            UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
+            if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC){
+                printf("%-9d %-16d %-16.*s %-16.*s\n", ref->browseName.namespaceIndex, ref->nodeId.nodeId.identifier.numeric, ref->browseName.name.length, ref->browseName.name.data, ref->displayName.text.length, ref->displayName.text.data);
+            }else if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_STRING){
+                printf("%-9d %-16.*s %-16.*s %-16.*s\n", ref->browseName.namespaceIndex, ref->nodeId.nodeId.identifier.string.length, ref->nodeId.nodeId.identifier.string.data, ref->browseName.name.length, ref->browseName.name.data, ref->displayName.text.length, ref->displayName.text.data);
+            }
+            //TODO: distinguish further types
+        }
+    }
+    UA_BrowseRequest_deleteMembers(&bReq);
+    UA_BrowseResponse_deleteMembers(&bResp);
 
-	UA_Int32 value = 0;
-	// Read node's value
-	printf("\nReading the value of node (1, \"the.answer\"):\n");
-	UA_ReadRequest rReq;
-	UA_ReadRequest_init(&rReq);
-	rReq.nodesToRead = UA_ReadValueId_new();
-	rReq.nodesToReadSize = 1;
-	rReq.nodesToRead[0].nodeId = UA_NODEID_STRING_ALLOC(1, "the.answer"); /* assume this node exists */
-	rReq.nodesToRead[0].attributeId = UA_ATTRIBUTEID_VALUE;
+    UA_Int32 value = 0;
+    // Read node's value
+    printf("\nReading the value of node (1, \"the.answer\"):\n");
+    UA_ReadRequest rReq;
+    UA_ReadRequest_init(&rReq);
+    rReq.nodesToRead = UA_ReadValueId_new();
+    rReq.nodesToReadSize = 1;
+    rReq.nodesToRead[0].nodeId = UA_NODEID_STRING_ALLOC(1, "the.answer"); /* assume this node exists */
+    rReq.nodesToRead[0].attributeId = UA_ATTRIBUTEID_VALUE;
 
-	UA_ReadResponse rResp = UA_Client_read(client, &rReq);
-	if(rResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD &&
-	   rResp.resultsSize > 0 && rResp.results[0].hasValue &&
-	   rResp.results[0].value.data /* an empty array returns a null-ptr */ &&
-	   rResp.results[0].value.type == &UA_TYPES[UA_TYPES_INT32]){
-		value = *(UA_Int32*)rResp.results[0].value.data;
-		printf("the value is: %i\n", value);
-	}
+    UA_ReadResponse rResp = UA_Client_read(client, &rReq);
+    if(rResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD &&
+            rResp.resultsSize > 0 && rResp.results[0].hasValue &&
+            rResp.results[0].value.data /* an empty array returns a null-ptr */ &&
+            rResp.results[0].value.type == &UA_TYPES[UA_TYPES_INT32]){
+        value = *(UA_Int32*)rResp.results[0].value.data;
+        printf("the value is: %i\n", value);
+    }
 
-	UA_ReadRequest_deleteMembers(&rReq);
-	UA_ReadResponse_deleteMembers(&rResp);
+    UA_ReadRequest_deleteMembers(&rReq);
+    UA_ReadResponse_deleteMembers(&rResp);
 
-	value++;
-	// Write node's value
-	printf("\nWriting a value of node (1, \"the.answer\"):\n");
-	UA_WriteRequest wReq;
-	UA_WriteRequest_init(&wReq);
-	wReq.nodesToWrite = UA_WriteValue_new();
-	wReq.nodesToWriteSize = 1;
-	wReq.nodesToWrite[0].nodeId = UA_NODEID_STRING_ALLOC(1, "the.answer"); /* assume this node exists */
-	wReq.nodesToWrite[0].attributeId = UA_ATTRIBUTEID_VALUE;
-	wReq.nodesToWrite[0].value.hasValue = UA_TRUE;
-	wReq.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_INT32];
-	wReq.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; //do not free the integer on deletion
-	wReq.nodesToWrite[0].value.value.data = &value;
+    value++;
+    // Write node's value
+    printf("\nWriting a value of node (1, \"the.answer\"):\n");
+    UA_WriteRequest wReq;
+    UA_WriteRequest_init(&wReq);
+    wReq.nodesToWrite = UA_WriteValue_new();
+    wReq.nodesToWriteSize = 1;
+    wReq.nodesToWrite[0].nodeId = UA_NODEID_STRING_ALLOC(1, "the.answer"); /* assume this node exists */
+    wReq.nodesToWrite[0].attributeId = UA_ATTRIBUTEID_VALUE;
+    wReq.nodesToWrite[0].value.hasValue = UA_TRUE;
+    wReq.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_INT32];
+    wReq.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; //do not free the integer on deletion
+    wReq.nodesToWrite[0].value.value.data = &value;
 
-	UA_WriteResponse wResp = UA_Client_write(client, &wReq);
-	if(wResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
-			printf("the new value is: %i\n", value);
+    UA_WriteResponse wResp = UA_Client_write(client, &wReq);
+    if(wResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
+        printf("the new value is: %i\n", value);
 
-	UA_WriteRequest_deleteMembers(&wReq);
-	UA_WriteResponse_deleteMembers(&wResp);
+    UA_WriteRequest_deleteMembers(&wReq);
+    UA_WriteResponse_deleteMembers(&wResp);
 
-	UA_Client_disconnect(client);
-	UA_Client_delete(client);
-	return UA_STATUSCODE_GOOD;
+    UA_Client_disconnect(client);
+    UA_Client_delete(client);
+    return UA_STATUSCODE_GOOD;
 }
 

+ 9 - 4
include/ua_client.h

@@ -25,18 +25,23 @@ typedef struct {
     UA_StatusCode (*awaitResponse)(void *handle, UA_ByteString *response, UA_UInt32 timeout);
 } UA_ClientNetworkLayer;
 
-struct UA_Client;
-typedef struct UA_Client UA_Client;
+/*
+ * The client struct contains the client config as the first parameter, so it can be successfully cast to UA_ClientConfig
+ */
+struct UA_Client_private;
+typedef struct UA_Client_private UA_Client_private;
 
 typedef struct UA_ClientConfig {
 	UA_Int32 timeout; //sync resonse timeout
 } UA_ClientConfig;
 
+typedef struct UA_Client {
+	UA_ClientConfig config;
+} UA_Client;
+
 UA_Client UA_EXPORT * UA_Client_new(void);
 void UA_Client_delete(UA_Client* client);
 
-UA_StatusCode UA_EXPORT UA_Client_setConfig(UA_Client* client, UA_ClientConfig config);
-
 UA_StatusCode UA_EXPORT UA_Client_connect(UA_Client *client, UA_ConnectionConfig conf,
                                           UA_ClientNetworkLayer networkLayer, char *endpointUrl);
 

+ 40 - 33
src/client/ua_client.c

@@ -4,8 +4,13 @@
 #include "ua_types_encoding_binary.h"
 #include "ua_transport_generated.h"
 
-struct UA_Client {
-    /* Connection */
+struct UA_Client_private {
+	/*** public ***/
+    /* Config */
+    UA_ClientConfig config;
+
+    /*** private ***/
+	/* Connection */
     UA_ClientNetworkLayer networkLayer;
     UA_String endpointUrl;
     UA_Connection connection;
@@ -23,13 +28,10 @@ struct UA_Client {
     /* Session */
     UA_NodeId sessionId;
     UA_NodeId authenticationToken;
-
-    /* Config */
-    UA_ClientConfig config;
 };
 
 UA_Client * UA_Client_new(void) {
-    UA_Client *client = UA_malloc(sizeof(UA_Client));
+    UA_Client_private *client = UA_malloc(sizeof(UA_Client_private));
     if(!client)
         return UA_NULL;
     UA_String_init(&client->endpointUrl);
@@ -49,16 +51,11 @@ UA_Client * UA_Client_new(void) {
     /* default clientConfig */
     client->config.timeout = 500;
 
-    return client;
+    return (UA_Client*)client;
 }
 
-UA_StatusCode UA_Client_setConfig(UA_Client* client, UA_ClientConfig config) {
-	if(client)
-		client->config = config;
-	return UA_STATUSCODE_GOOD;
-}
-
-void UA_Client_delete(UA_Client* client){
+void UA_Client_delete(UA_Client* clientPublic){
+	UA_Client_private* client = (UA_Client_private*) clientPublic;
     client->networkLayer.destroy(client->networkLayer.nlHandle);
     UA_String_deleteMembers(&client->endpointUrl);
     // client->connection
@@ -71,7 +68,7 @@ void UA_Client_delete(UA_Client* client){
 }
 
 // The tcp connection is established. Now do the handshake
-static UA_StatusCode HelAckHandshake(UA_Client *c) {
+static UA_StatusCode HelAckHandshake(UA_Client_private *c) {
 	UA_TcpMessageHeader messageHeader;
     messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_HELF;
 
@@ -126,7 +123,7 @@ static UA_StatusCode HelAckHandshake(UA_Client *c) {
 	return UA_STATUSCODE_GOOD;
 }
 
-static UA_StatusCode SecureChannelHandshake(UA_Client *client) {
+static UA_StatusCode SecureChannelHandshake(UA_Client_private *client) {
     UA_ByteString_deleteMembers(&client->clientNonce); // if the handshake is repeated
 	UA_ByteString_newMembers(&client->clientNonce, 1);
 	client->clientNonce.data[0] = 0;
@@ -228,7 +225,7 @@ static UA_StatusCode SecureChannelHandshake(UA_Client *client) {
 /** If the request fails, then the response is cast to UA_ResponseHeader (at the beginning of every
     response) and filled with the appropriate error code */
 static void sendReceiveRequest(UA_RequestHeader *request, const UA_DataType *requestType,
-                               void *response, const UA_DataType *responseType, UA_Client *client,
+                               void *response, const UA_DataType *responseType, UA_Client_private *client,
                                UA_Boolean sendOnly)
 {
 	if(response)
@@ -323,11 +320,11 @@ static void sendReceiveRequest(UA_RequestHeader *request, const UA_DataType *req
 }
 
 static void synchronousRequest(void *request, const UA_DataType *requestType,
-                               void *response, const UA_DataType *responseType, UA_Client *client){
+                               void *response, const UA_DataType *responseType, UA_Client_private *client){
 	sendReceiveRequest(request, requestType, response, responseType, client, UA_FALSE);
 }
 
-static UA_StatusCode ActivateSession(UA_Client *client) {
+static UA_StatusCode ActivateSession(UA_Client_private *client) {
 	UA_ActivateSessionRequest request;
 	UA_ActivateSessionRequest_init(&request);
 
@@ -346,8 +343,7 @@ static UA_StatusCode ActivateSession(UA_Client *client) {
     return response.responseHeader.serviceResult; // not deleted
 }
 
-static UA_StatusCode SessionHandshake(UA_Client *client) {
-
+static UA_StatusCode SessionHandshake(UA_Client_private *client) {
     UA_CreateSessionRequest request;
     UA_CreateSessionRequest_init(&request);
 
@@ -377,7 +373,8 @@ static UA_StatusCode SessionHandshake(UA_Client *client) {
     return response.responseHeader.serviceResult; // not deleted
 }
 
-static UA_StatusCode CloseSession(UA_Client *client) {
+static UA_StatusCode CloseSession(UA_Client *clientPublic) {
+	UA_Client_private* client = (UA_Client_private*) clientPublic;
 	UA_CloseSessionRequest request;
 	UA_CloseSessionRequest_init(&request);
 
@@ -395,7 +392,8 @@ static UA_StatusCode CloseSession(UA_Client *client) {
     return response.responseHeader.serviceResult; // not deleted
 }
 
-static UA_StatusCode CloseSecureChannel(UA_Client *client) {
+static UA_StatusCode CloseSecureChannel(UA_Client *clientPublic) {
+	UA_Client_private* client = (UA_Client_private*) clientPublic;
 	UA_CloseSecureChannelRequest request;
     UA_CloseSecureChannelRequest_init(&request);
 
@@ -415,9 +413,10 @@ static UA_StatusCode CloseSecureChannel(UA_Client *client) {
 /*************************/
 
 
-UA_StatusCode UA_Client_connect(UA_Client *client, UA_ConnectionConfig conf,
+UA_StatusCode UA_Client_connect(UA_Client *clientPublic, UA_ConnectionConfig conf,
                                 UA_ClientNetworkLayer networkLayer, char *endpointUrl)
 {
+	UA_Client_private* client = (UA_Client_private*) clientPublic;
     client->endpointUrl = UA_STRING_ALLOC(endpointUrl);
     if(client->endpointUrl.length < 0)
         return UA_STATUSCODE_BADOUTOFMEMORY;
@@ -448,60 +447,68 @@ UA_StatusCode UA_EXPORT UA_Client_disconnect(UA_Client *client) {
 }
 
 UA_ReadResponse UA_Client_read(UA_Client *client, UA_ReadRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_ReadResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_READREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_READRESPONSE], client);
+                       &UA_TYPES[UA_TYPES_READRESPONSE], clientPrivate);
     return response;
 }
 
 UA_WriteResponse UA_Client_write(UA_Client *client, UA_WriteRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_WriteResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_WRITEREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_WRITERESPONSE], client);
+                       &UA_TYPES[UA_TYPES_WRITERESPONSE], clientPrivate);
     return response;
 }
 
 UA_BrowseResponse UA_Client_browse(UA_Client *client, UA_BrowseRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_BrowseResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], client);
+                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], clientPrivate);
     return response;
 }
 
 UA_TranslateBrowsePathsToNodeIdsResponse
     UA_Client_translateTranslateBrowsePathsToNodeIds(UA_Client *client,
                                                      UA_TranslateBrowsePathsToNodeIdsRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_TranslateBrowsePathsToNodeIdsResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], client);
+                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], clientPrivate);
     return response;
 }
 
 UA_AddNodesResponse UA_Client_addNodes(UA_Client *client, UA_AddNodesRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_AddNodesResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], client);
+                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], clientPrivate);
     return response;
 }
 
 UA_AddReferencesResponse UA_Client_addReferences(UA_Client *client, UA_AddReferencesRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_AddReferencesResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], client);
+                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], clientPrivate);
     return response;
 }
 
 UA_DeleteNodesResponse UA_Client_deleteNodes(UA_Client *client, UA_DeleteNodesRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_DeleteNodesResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], client);
+                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], clientPrivate);
     return response;
 }
 
 UA_DeleteReferencesResponse UA_EXPORT
 UA_Client_deleteReferences(UA_Client *client, UA_DeleteReferencesRequest *request) {
+	UA_Client_private* clientPrivate = (UA_Client_private*)client;
     UA_DeleteReferencesResponse response;
     synchronousRequest(request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], &response,
-                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], client);
-    return response;;
+                       &UA_TYPES[UA_TYPES_BROWSERESPONSE], clientPrivate);
+    return response;
 }