瀏覽代碼

fix #149, remove magic values

Julius Pfrommer 10 年之前
父節點
當前提交
70d5d88da9
共有 4 個文件被更改,包括 83 次插入99 次删除
  1. 4 5
      src/server/ua_server.c
  2. 73 85
      src/server/ua_server_binary.c
  3. 5 8
      src/server/ua_services_attribute.c
  4. 1 1
      tools/generate_builtin.py

+ 4 - 5
src/server/ua_server.c

@@ -492,16 +492,15 @@ UA_Server * UA_Server_new() {
 
     // todo: make this variable point to a member of the serverstatus
     UA_VariableNode *state = UA_VariableNode_new();
-    UA_ServerState stateEnum = UA_SERVERSTATE_RUNNING;
+    UA_ServerState *stateEnum = UA_ServerState_new();
+    *stateEnum = UA_SERVERSTATE_RUNNING;
     COPYNAMES(state, "State");
     state->nodeId    = UA_NODEIDS[UA_SERVER_SERVERSTATUS_STATE];
     state->nodeClass = UA_NODECLASS_VARIABLE;
     state->value.vt = &UA_TYPES[UA_SERVERSTATE];
-    state->value.storage.data.arrayDimensionsLength = 1; // added to ensure encoding in readreponse
     state->value.storage.data.arrayLength = 1;
-    state->value.storage.data.dataPtr = &stateEnum; // points into the other object.
-    state->value.storageType = UA_VARIANT_DATA_NODELETE;
+    state->value.storage.data.dataPtr = stateEnum; // points into the other object.
+    state->value.storageType = UA_VARIANT_DATA;
     UA_NodeStore_insert(server->nodestore, (const UA_Node**)&state, UA_FALSE);
-
     return server;
 }

+ 73 - 85
src/server/ua_server_binary.c

@@ -76,59 +76,51 @@ static void processOpen(UA_Connection *connection, UA_Server *server, const UA_B
     UA_SequenceHeader seqHeader;
     UA_SequenceHeader_decodeBinary(msg, pos, &seqHeader);
 
-    UA_ExpandedNodeId requestType;
-    UA_ExpandedNodeId_decodeBinary(msg, pos, &requestType);
+    UA_NodeId requestType;
+    UA_NodeId_decodeBinary(msg, pos, &requestType);
 
-    if(requestType.nodeId.identifier.numeric != 446) {
-        // todo: handle error
+    if(requestType.identifier.numeric != 446) {
+        connection->close(connection);
+        return;
     }
 
     UA_OpenSecureChannelRequest r;
-    UA_OpenSecureChannelRequest_decodeBinary(msg, pos, &r);
-
-    // perform request
     UA_OpenSecureChannelResponse p;
+    UA_OpenSecureChannelRequest_decodeBinary(msg, pos, &r);
     UA_OpenSecureChannelResponse_init(&p);
     Service_OpenSecureChannel(server, connection, &r, &p);
 
-    // response
-    UA_TcpMessageHeader respHeader;
-    respHeader.messageType = UA_MESSAGETYPE_OPN;
-    respHeader.isFinal     = 'F';
-    respHeader.messageSize = 8+4;
-
-    UA_ExpandedNodeId responseType = UA_EXPANDEDNODEIDS[UA_OPENSECURECHANNELRESPONSE];
-    responseType.nodeId.identifier.numeric += UA_ENCODINGOFFSET_BINARY;
+    /* Response */
+    UA_SecureConversationMessageHeader respHeader;
+    respHeader.messageHeader.messageType = UA_MESSAGETYPE_OPN;
+    respHeader.messageHeader.isFinal     = 'F';
+    respHeader.messageHeader.messageSize = 0;
+    respHeader.secureChannelId = p.securityToken.channelId;
 
-    respHeader.messageSize += UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(&asymHeader);
-    respHeader.messageSize += UA_SequenceHeader_calcSizeBinary(&seqHeader);
-    respHeader.messageSize += UA_ExpandedNodeId_calcSizeBinary(&responseType);
-    respHeader.messageSize += UA_OpenSecureChannelResponse_calcSizeBinary(&p);
+    UA_NodeId responseType = UA_NODEIDS[UA_OPENSECURECHANNELRESPONSE];
+    responseType.identifier.numeric += UA_ENCODINGOFFSET_BINARY;
 
-    UA_ByteString resp_msg;
-    UA_Boolean onStack = UA_FALSE;
+    respHeader.messageHeader.messageSize =
+        UA_SecureConversationMessageHeader_calcSizeBinary(&respHeader)
+        + UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(&asymHeader)
+        + UA_SequenceHeader_calcSizeBinary(&seqHeader)
+        + UA_NodeId_calcSizeBinary(&responseType)
+        + UA_OpenSecureChannelResponse_calcSizeBinary(&p);
 
-    if(respHeader.messageSize <= MAX_STACK_MESSAGE) {
-        onStack = UA_TRUE;
-        resp_msg = (UA_ByteString){.length = respHeader.messageSize,
-                                   .data = UA_alloca(respHeader.messageSize)};
-    } else
-        UA_ByteString_newMembers(&resp_msg, respHeader.messageSize);
+    UA_ByteString resp_msg = (UA_ByteString){.length = respHeader.messageHeader.messageSize,
+                                             .data = UA_alloca(respHeader.messageHeader.messageSize)};
 
     UA_UInt32 tmpPos = 0;
-    UA_TcpMessageHeader_encodeBinary(&respHeader, &resp_msg, &tmpPos);
-    UA_UInt32_encodeBinary(&p.securityToken.channelId, &resp_msg, &tmpPos);
+    UA_SecureConversationMessageHeader_encodeBinary(&respHeader, &resp_msg, &tmpPos);
     UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&asymHeader, &resp_msg, &tmpPos); // just mirror back
     UA_SequenceHeader_encodeBinary(&seqHeader, &resp_msg, &tmpPos); // just mirror back
-    UA_ExpandedNodeId_encodeBinary(&responseType, &resp_msg, &tmpPos);
+    UA_NodeId_encodeBinary(&responseType, &resp_msg, &tmpPos);
     UA_OpenSecureChannelResponse_encodeBinary(&p, &resp_msg, &tmpPos);
 
     UA_OpenSecureChannelRequest_deleteMembers(&r);
     UA_OpenSecureChannelResponse_deleteMembers(&p);
     UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymHeader);
     connection->write(connection, (UA_ByteStringArray){ .stringsSize = 1, .strings = &resp_msg });
-    if(!onStack)
-        UA_free(resp_msg.data);
 }
 
 static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r) {
@@ -166,7 +158,7 @@ static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r
         UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset);     \
         UA_##TYPE##Request_deleteMembers(&p);                           \
         UA_##TYPE##Response_deleteMembers(&r);                          \
-        responseType = requestType.nodeId.identifier.numeric + 3;       \
+        responseType = requestType.identifier.numeric + 3;       \
     } while(0)
 
 static void processMessage(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
@@ -203,11 +195,11 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
     //UA_SecureChannel_checkRequestId(channel,sequenceHeader.requestId);
 
     // 3) Read the nodeid of the request
-    UA_ExpandedNodeId requestType;
-    CHECK_PROCESS(UA_ExpandedNodeId_decodeBinary(msg, pos, &requestType),; );
-    if(requestType.nodeId.identifierType != UA_NODEIDTYPE_NUMERIC) {
+    UA_NodeId requestType;
+    CHECK_PROCESS(UA_NodeId_decodeBinary(msg, pos, &requestType),; );
+    if(requestType.identifierType != UA_NODEIDTYPE_NUMERIC) {
         // if the nodeidtype is numeric, we do not have to free anything
-        UA_ExpandedNodeId_deleteMembers(&requestType);
+        UA_NodeId_deleteMembers(&requestType);
         return;
     }
 
@@ -221,7 +213,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
     UA_UInt32 sendOffset = 0;
 
     //subtract UA_ENCODINGOFFSET_BINARY for binary encoding
-    switch(requestType.nodeId.identifier.numeric - UA_ENCODINGOFFSET_BINARY) {
+    switch(requestType.identifier.numeric - UA_ENCODINGOFFSET_BINARY) {
     case UA_GETENDPOINTSREQUEST_NS0: {
         UA_GetEndpointsRequest  p;
         UA_GetEndpointsResponse r;
@@ -233,7 +225,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         UA_GetEndpointsResponse_encodeBinary(&r, message, &sendOffset);
         UA_GetEndpointsRequest_deleteMembers(&p);
         UA_GetEndpointsResponse_deleteMembers(&r);
-        responseType = requestType.nodeId.identifier.numeric + 3;
+        responseType = requestType.identifier.numeric + 3;
         break;
     }
 
@@ -248,7 +240,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         UA_CreateSessionResponse_encodeBinary(&r, message, &sendOffset);
         UA_CreateSessionRequest_deleteMembers(&p);
         UA_CreateSessionResponse_deleteMembers(&r);
-        responseType = requestType.nodeId.identifier.numeric + 3;
+        responseType = requestType.identifier.numeric + 3;
         break;
     }
 
@@ -263,7 +255,7 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         UA_ActivateSessionResponse_encodeBinary(&r, message, &sendOffset);
         UA_ActivateSessionRequest_deleteMembers(&p);
         UA_ActivateSessionResponse_deleteMembers(&r);
-        responseType = requestType.nodeId.identifier.numeric + 3;
+        responseType = requestType.identifier.numeric + 3;
         break;
     }
 
@@ -278,14 +270,12 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
         UA_CloseSessionResponse_encodeBinary(&r, message, &sendOffset);
         UA_CloseSessionRequest_deleteMembers(&p);
         UA_CloseSessionResponse_deleteMembers(&r);
-        responseType = requestType.nodeId.identifier.numeric + 3;
+        responseType = requestType.identifier.numeric + 3;
         break;
     }
 
-    case UA_READREQUEST_NS0: {
+    case UA_READREQUEST_NS0:
         INVOKE_SERVICE(Read);
-    }
-        //INVOKE_SERVICE(Read);
         break;
 
     case UA_WRITEREQUEST_NS0:
@@ -299,68 +289,65 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
     case UA_ADDREFERENCESREQUEST_NS0:
         INVOKE_SERVICE(AddReferences);
         break;
-    /* case UA_CREATESUBSCRIPTIONREQUEST_NS0: */
-    /*     INVOKE_SERVICE(CreateSubscription); */
-    /*     break; */
 
     case UA_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_NS0:
         INVOKE_SERVICE(TranslateBrowsePathsToNodeIds);
         break;
 
-    /* case UA_PUBLISHREQUEST_NS0: */
-    /*     INVOKE_SERVICE(Publish); */
-    /*     break; */
-
-    /* case UA_CREATEMONITOREDITEMSREQUEST_NS0: */
-    /*     INVOKE_SERVICE(CreateMonitoredItems); */
-    /*     break; */
-
-    /* case UA_SETPUBLISHINGMODEREQUEST_NS0: */
-    /*     INVOKE_SERVICE(SetPublishingMode); */
-    /*     break; */
-
     default: {
         printf("SL_processMessage - unknown request, namespace=%d, request=%d\n",
-               requestType.nodeId.namespaceIndex, requestType.nodeId.identifier.numeric);
+               requestType.namespaceIndex, requestType.identifier.numeric);
         UA_RequestHeader  p;
         UA_ResponseHeader r;
-        CHECK_PROCESS(UA_RequestHeader_decodeBinary(msg, pos, &p),; );
+        UA_StatusCode retval = UA_RequestHeader_decodeBinary(msg, pos, &p);
+        if(retval != UA_STATUSCODE_GOOD)
+            return;
         UA_ResponseHeader_init(&r);
+        init_response_header(&p, &r);
         r.requestHandle = p.requestHandle;
         r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
         ALLOC_MESSAGE(message, UA_ResponseHeader_calcSizeBinary(&r));
         UA_ResponseHeader_encodeBinary(&r, message, &sendOffset);
         UA_RequestHeader_deleteMembers(&p);
         UA_ResponseHeader_deleteMembers(&r);
-        responseType = UA_RESPONSEHEADER_NS0 + 2;
+        responseType = UA_NODEIDS[UA_RESPONSEHEADER].identifier.numeric + UA_ENCODINGOFFSET_BINARY;
         }
     	break;
     }
+
     // 5) Build the header
-    UA_NodeId response_nodeid = { .namespaceIndex     = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
-                                  .identifier.numeric = responseType }; // add 2 for binary encoding
+    UA_SecureConversationMessageHeader respHeader;
+    respHeader.messageHeader.messageType = UA_MESSAGETYPE_MSG;
+    respHeader.messageHeader.isFinal     = 'F';
+    respHeader.messageHeader.messageSize = 0;
+    respHeader.secureChannelId = channel->securityToken.channelId;
 
-    UA_UInt32 headerSize = 8 + 16 + // message header + 4*32bit secure channel information
-        UA_NodeId_calcSizeBinary(&response_nodeid); // the nodeid of a service is always numeric
-    *header = (UA_ByteString){.length = headerSize, .data = UA_alloca(headerSize)};
+    UA_SymmetricAlgorithmSecurityHeader symSecHeader;
+    symSecHeader.tokenId = channel->securityToken.tokenId;
 
-    // header
-    UA_TcpMessageHeader respHeader;
-    respHeader.messageType = UA_MESSAGETYPE_MSG;
-    respHeader.isFinal     = 'F';
-    respHeader.messageSize = header->length + message->length;
+    UA_SequenceHeader seqHeader;
+    seqHeader.sequenceNumber = channel->sequenceNumber;
+    seqHeader.requestId = channel->requestId;
 
-    UA_UInt32 rpos = 0;
-    UA_TcpMessageHeader_encodeBinary(&respHeader, header, &rpos);
+    UA_NodeId response_nodeid = { .namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
+                                  .identifier.numeric = responseType };
+
+    UA_UInt32 headerSize =
+        UA_SecureConversationMessageHeader_calcSizeBinary(&respHeader)
+        + UA_SymmetricAlgorithmSecurityHeader_calcSizeBinary(&symSecHeader)
+        + UA_SequenceHeader_calcSizeBinary(&seqHeader)
+        + UA_NodeId_calcSizeBinary(&response_nodeid);
 
-    UA_UInt32_encodeBinary(&channel->securityToken.channelId, header, &rpos); // channel id
-    UA_UInt32_encodeBinary(&channel->securityToken.tokenId, header, &rpos); // algorithm security header
-    UA_UInt32_encodeBinary(&channel->sequenceNumber, header, &rpos); // encode sequence header
-    UA_UInt32_encodeBinary(&channel->requestId, header, &rpos); // request id
-    UA_NodeId_encodeBinary(&response_nodeid, header, &rpos); // add payload type
-    // sign data
+    *header = (UA_ByteString){.length = headerSize, .data = UA_alloca(headerSize)};
+    respHeader.messageHeader.messageSize = header->length + message->length;
+
+    UA_UInt32 rpos = 0;
+    UA_SecureConversationMessageHeader_encodeBinary(&respHeader, header, &rpos);
+    UA_SymmetricAlgorithmSecurityHeader_encodeBinary(&symSecHeader, header, &rpos);
+    UA_SequenceHeader_encodeBinary(&seqHeader, header, &rpos);
+    UA_NodeId_encodeBinary(&response_nodeid, header, &rpos);
 
-    // encrypt data
+    // todo: sign & encrypt
 
     // 6) Send it over the wire.
     UA_ByteStringArray responseBufArray;
@@ -374,16 +361,17 @@ static void processMessage(UA_Connection *connection, UA_Server *server, const U
 
 static void processClose(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg,
                          UA_UInt32 *pos) {
-    // just read in the sequenceheader
     UA_UInt32 secureChannelId;
     UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
 
-	//the two last parameter is ignored since no answer is needed
+    if(!connection->channel || connection->channel->securityToken.channelId != secureChannelId)
+        return;
+
 	Service_CloseSecureChannel(server, secureChannelId);
 }
 
 void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) {
-    UA_UInt32 pos    = 0;
+    UA_UInt32 pos = 0;
     UA_TcpMessageHeader tcpMessageHeader;
     do {
         if(UA_TcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader) != UA_STATUSCODE_GOOD) {

+ 5 - 8
src/server/ua_services_attribute.c

@@ -186,14 +186,11 @@ void Service_Read(UA_Server *server, UA_Session *session, const UA_ReadRequest *
         return;
     }
 
-    // if allocated on the stack from the "outside"
-    if(response->resultsSize <= 0) {
-        UA_StatusCode retval = UA_Array_new((void**)&response->results,
-                                            request->nodesToReadSize, &UA_TYPES[UA_DATAVALUE]);
-        if(retval) {
-            response->responseHeader.serviceResult = retval;
-            return;
-        }
+    UA_StatusCode retval = UA_Array_new((void**)&response->results, request->nodesToReadSize,
+                                        &UA_TYPES[UA_DATAVALUE]);
+    if(retval != UA_STATUSCODE_GOOD) {
+        response->responseHeader.serviceResult = retval;
+        return;
     }
 
     /* ### Begin External Namespaces */

+ 1 - 1
tools/generate_builtin.py

@@ -197,7 +197,7 @@ def createStructured(element):
     else:
         for n,t in membermap.iteritems():
             if t in fixed_size:
-                printc('\t + sizeof(%(t)s) // %(n)s')
+                printc('\t + ' + str(fixed_size[t]) + ' // %(n)s')
             elif t.find("*") != -1:
                 printc('\t + UA_Array_calcSizeBinary(ptr->%(n)sSize,&UA_TYPES[' +
                        t[0:t.find("*")].upper() + "],ptr->%(n)s)")