Browse Source

closing session and SC works, refactoring still needed ;)

Stasik0 10 years ago
parent
commit
ee9fba96a6
2 changed files with 71 additions and 31 deletions
  1. 2 20
      examples/client_proper.c
  2. 69 11
      src/client/ua_client.c

+ 2 - 20
examples/client_proper.c

@@ -8,26 +8,6 @@
 #include <stdio.h>
 #include "networklayer_tcp.h"
 
-struct UA_Client {
-    UA_ClientNetworkLayer networkLayer;
-    UA_String endpointUrl;
-    UA_Connection connection;
-
-    UA_UInt32 sequenceNumber;
-    UA_UInt32 requestId;
-
-    /* Secure Channel */
-    UA_ChannelSecurityToken securityToken;
-    UA_ByteString clientNonce;
-    UA_ByteString serverNonce;
-	/* UA_SequenceHeader sequenceHdr; */
-	/* UA_NodeId authenticationToken; */
-
-    /* Session */
-    UA_NodeId sessionId;
-    UA_NodeId authenticationToken;
-};
-
 int main(int argc, char *argv[]) {
 	UA_Client *client = UA_Client_new();
 	UA_ClientNetworkLayer nl = ClientNetworkLayerTCP_new(UA_ConnectionConfig_standard);
@@ -49,5 +29,7 @@ int main(int argc, char *argv[]) {
     printf("the answer is: %i\n", *(UA_Int32*)read_resp.results[0].value.dataPtr);
     UA_ReadRequest_deleteMembers(&read_req);
     UA_ReadResponse_deleteMembers(&read_resp);
+
+    UA_Client_disconnect(client);
     UA_Client_delete(client);
 }

+ 69 - 11
src/client/ua_client.c

@@ -39,6 +39,7 @@ UA_Client * UA_Client_new(void) {
     UA_ByteString_init(&client->clientNonce);
     UA_ByteString_init(&client->serverNonce);
     
+    UA_NodeId_init(&client->authenticationToken);
     return client;
 }
 
@@ -209,13 +210,16 @@ static UA_StatusCode HelAckHandshake(UA_Client *c) {
 
 /** 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 synchronousRequest(const void *request, const UA_DataType *requestType,
-                               void *response, const UA_DataType *responseType, UA_Client *client)
+static void sendReceiveRequest(const void *request, const UA_DataType *requestType,
+                               void *response, const UA_DataType *responseType, UA_Client *client, UA_Boolean sendOnly)
 {
-    UA_ResponseHeader *respHeader = (UA_ResponseHeader*)response;
 
     UA_SecureConversationMessageHeader msgHeader;
-    msgHeader.messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;
+    if(sendOnly){
+    	msgHeader.messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_CLOF;
+    }else{
+    	msgHeader.messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;
+    }
     msgHeader.secureChannelId = client->securityToken.channelId;
 
     UA_SymmetricAlgorithmSecurityHeader symHeader;
@@ -252,6 +256,12 @@ static void synchronousRequest(const void *request, const UA_DataType *requestTy
     UA_ByteStringArray buf = {.stringsSize = 1, .strings = &message};
     retval = client->networkLayer.send(client->networkLayer.nlHandle, buf);
     UA_ByteString_deleteMembers(&message);
+
+    //TODO: rework to get return value
+    if(sendOnly)
+    	return;
+
+    UA_ResponseHeader *respHeader = (UA_ResponseHeader*)response;
     if(retval != UA_STATUSCODE_GOOD) {
         respHeader->serviceResult = retval;
         return;
@@ -288,11 +298,20 @@ static void synchronousRequest(const void *request, const UA_DataType *requestTy
         respHeader->serviceResult = retval;
 }
 
+static void synchronousRequest(const void *request, const UA_DataType *requestType,
+                               void *response, const UA_DataType *responseType, UA_Client *client){
+	sendReceiveRequest(request, requestType, response, responseType, client, UA_FALSE);
+}
+
+static void sendOnlyRequest(const void *request, const UA_DataType *requestType, UA_Client *client){
+	sendReceiveRequest(request, requestType, UA_NULL, UA_NULL, client, UA_TRUE);
+}
+
 static UA_StatusCode ActivateSession(UA_Client *client) {
 	UA_ActivateSessionRequest request;
 	UA_ActivateSessionRequest_init(&request);
 
-    request.requestHeader.requestHandle = 2;
+    request.requestHeader.requestHandle = 2; //TODO: is it a magic number?
     request.requestHeader.authenticationToken = client->authenticationToken;
     request.requestHeader.timestamp = UA_DateTime_now();
     request.requestHeader.timeoutHint = 10000;
@@ -337,6 +356,45 @@ static UA_StatusCode SessionHandshake(UA_Client *client) {
     return response.responseHeader.serviceResult; // not deleted
 }
 
+static UA_StatusCode CloseSession(UA_Client *client) {
+	UA_CloseSessionRequest request;
+	UA_CloseSessionRequest_init(&request);
+
+	request.requestHeader.timestamp = UA_DateTime_now();
+	request.requestHeader.timeoutHint = 10000;
+	request.deleteSubscriptions = UA_TRUE;
+	UA_NodeId_copy(&client->authenticationToken, &request.requestHeader.authenticationToken);
+    UA_CreateSessionResponse response;
+    synchronousRequest(&request, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST],
+                       &response, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE],
+                       client);
+
+    UA_CloseSessionRequest_deleteMembers(&request);
+    UA_CloseSessionResponse_deleteMembers(&response);
+    return response.responseHeader.serviceResult; // not deleted
+}
+
+static UA_StatusCode CloseSecureChannel(UA_Client *client) {
+	UA_CloseSecureChannelRequest request;
+    UA_CloseSecureChannelRequest_init(&request);
+
+    request.requestHeader.requestHandle = 1; //TODO: magic number?
+    request.requestHeader.timestamp = UA_DateTime_now();
+    request.requestHeader.timeoutHint = 10000;
+
+    request.requestHeader.authenticationToken = client->authenticationToken;
+
+    sendOnlyRequest(&request, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST], client);
+
+    return UA_STATUSCODE_GOOD;
+
+}
+
+/*************************/
+/* User-Facing Functions */
+/*************************/
+
+
 UA_StatusCode UA_Client_connect(UA_Client *client, UA_ConnectionConfig conf,
                                 UA_ClientNetworkLayer networkLayer, char *endpointUrl)
 {
@@ -360,19 +418,19 @@ UA_StatusCode UA_Client_connect(UA_Client *client, UA_ConnectionConfig conf,
     return retval;
 }
 
+
 UA_StatusCode UA_EXPORT UA_Client_disconnect(UA_Client *client) {
-    return UA_STATUSCODE_GOOD;
+	UA_StatusCode retval;
+	retval = CloseSession(client);
+    if(retval == UA_STATUSCODE_GOOD)
+        retval = CloseSecureChannel(client);
+    return retval;
 }
 
-/*************************/
-/* User-Facing Functions */
-/*************************/
-
 UA_ReadResponse UA_Client_read(UA_Client *client, UA_ReadRequest *request) {
     UA_ReadResponse response;
     //todo: probably move to synchronousRequest
     UA_NodeId_copy(&client->authenticationToken, &request->requestHeader.authenticationToken);
-
     synchronousRequest(request, &UA_TYPES[UA_TYPES_READREQUEST], &response,
                        &UA_TYPES[UA_TYPES_READRESPONSE], client);
     return response;