Browse Source

Merge branch '0.2'

Julius Pfrommer 8 years ago
parent
commit
8c3d2e19a4

+ 9 - 2
src/client/ua_client.c

@@ -688,12 +688,12 @@ static void
 processServiceResponse(struct ResponseDescription *rd, UA_SecureChannel *channel,
                        UA_MessageType messageType, UA_UInt32 requestId,
                        UA_ByteString *message) {
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
     const UA_NodeId expectedNodeId =
         UA_NODEID_NUMERIC(0, rd->responseType->binaryEncodingId);
     const UA_NodeId serviceFaultNodeId =
         UA_NODEID_NUMERIC(0, UA_TYPES[UA_TYPES_SERVICEFAULT].binaryEncodingId);
 
-    UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_ResponseHeader *respHeader = (UA_ResponseHeader*)rd->response;
     rd->processed = true;
 
@@ -701,7 +701,14 @@ processServiceResponse(struct ResponseDescription *rd, UA_SecureChannel *channel
     size_t offset = 0;
     UA_NodeId responseId;
 
-    if(messageType != UA_MESSAGETYPE_MSG) {
+    if(messageType == UA_MESSAGETYPE_ERR) {
+        UA_TcpErrorMessage *msg = (UA_TcpErrorMessage*)message;
+        UA_LOG_ERROR(rd->client->config.logger, UA_LOGCATEGORY_CLIENT,
+                     "Server replied with an error message: %s %.*s",
+                     UA_StatusCode_name(msg->error), msg->reason.length, msg->reason.data);
+        retval = msg->error;
+        goto finish;
+    } else if(messageType != UA_MESSAGETYPE_MSG) {
         UA_LOG_ERROR(rd->client->config.logger, UA_LOGCATEGORY_CLIENT,
                      "Server replied with the wrong message type");
         retval = UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;

+ 25 - 0
src/server/ua_server_binary.c

@@ -516,6 +516,19 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
     UA_deleteMembers(response, responseType);
 }
 
+/* ERR -> Error from the remote connection */
+static void processERR(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg, size_t *offset) {
+    UA_TcpErrorMessage errorMessage;
+    if (UA_TcpErrorMessage_decodeBinary(msg, offset, &errorMessage) != UA_STATUSCODE_GOOD) {
+        connection->close(connection);
+        return;
+    }
+
+    UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_NETWORK,
+                 "Client replied with an error message: %s %.*s",
+                 UA_StatusCode_name(errorMessage.error), errorMessage.reason.length, errorMessage.reason.data);
+}
+
 /* Takes decoded messages starting at the nodeid of the content type. Only OPN
  * messages start at the asymmetricalgorithmsecurityheader and are not
  * decoded. */
@@ -526,6 +539,13 @@ UA_Server_processSecureChannelMessage(UA_Server *server, UA_SecureChannel *chann
     UA_assert(channel);
     UA_assert(channel->connection);
     switch(messagetype) {
+    case UA_MESSAGETYPE_ERR: {
+        const UA_TcpErrorMessage *msg = (const UA_TcpErrorMessage *) message;
+        UA_LOG_ERROR_CHANNEL(server->config.logger, channel,
+                             "Client replied with an error message: %s %.*s",
+                             UA_StatusCode_name(msg->error), msg->reason.length, msg->reason.data);
+        break;
+    }
     case UA_MESSAGETYPE_HEL:
         UA_LOG_TRACE_CHANNEL(server->config.logger, channel,
                              "Cannot process a HEL on an open channel");
@@ -576,6 +596,11 @@ UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection,
 
         /* Dispatch according to the message type */
         switch(tcpMessageHeader.messageTypeAndChunkType & 0x00ffffff) {
+        case UA_MESSAGETYPE_ERR:
+            UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK,
+                         "Connection %i | Process ERR message", connection->sockfd);
+            processERR(server, connection, message, &offset);
+            break;
         case UA_MESSAGETYPE_HEL:
             UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK,
                          "Connection %i | Process HEL message", connection->sockfd);

+ 2 - 2
src/server/ua_server_worker.c

@@ -610,7 +610,7 @@ UA_UInt16 UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal) {
     /* Get work from the networklayer */
     for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
         UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
-        UA_Job *jobs;
+        UA_Job *jobs = NULL;
         size_t jobsSize;
         /* only the last networklayer waits on the tieout */
         if(i == server->config.networkLayersSize-1)
@@ -665,7 +665,7 @@ UA_UInt16 UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal) {
 UA_StatusCode UA_Server_run_shutdown(UA_Server *server) {
     for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
         UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
-        UA_Job *stopJobs;
+        UA_Job *stopJobs = NULL;
         size_t stopJobsSize = nl->stop(nl, &stopJobs);
         for(size_t j = 0; j < stopJobsSize; ++j)
             processJob(server, &stopJobs[j]);

+ 1 - 0
src/ua_connection.c

@@ -49,6 +49,7 @@ completeChunksUntil(UA_Connection *connection, UA_ByteString * UA_RESTRICT messa
                            ((UA_UInt32)message->data[complete_until+1] << 8) +
                            ((UA_UInt32)message->data[complete_until+2] << 16);
         if(msgtype != ('M' + ('S' << 8) + ('G' << 16)) &&
+           msgtype != ('E' + ('R' << 8) + ('R' << 16)) &&
            msgtype != ('O' + ('P' << 8) + ('N' << 16)) &&
            msgtype != ('H' + ('E' << 8) + ('L' << 16)) &&
            msgtype != ('A' + ('C' << 8) + ('K' << 16)) &&

+ 17 - 0
src/ua_securechannel.c

@@ -361,6 +361,23 @@ UA_SecureChannel_processChunks(UA_SecureChannel *channel, const UA_ByteString *c
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     size_t offset= 0;
     do {
+
+        if (chunks->length > 3 && chunks->data[offset] == 'E' &&
+                chunks->data[offset+1] == 'R' && chunks->data[offset+2] == 'R') {
+            UA_TcpMessageHeader header;
+            retval = UA_TcpMessageHeader_decodeBinary(chunks, &offset, &header);
+            if(retval != UA_STATUSCODE_GOOD)
+                break;
+
+            UA_TcpErrorMessage errorMessage;
+            retval = UA_TcpErrorMessage_decodeBinary(chunks, &offset, &errorMessage);
+            if(retval != UA_STATUSCODE_GOOD)
+                break;
+
+            callback(application, channel, UA_MESSAGETYPE_ERR, 0, (void*)&errorMessage);
+            continue;
+        }
+
         /* Store the initial offset to compute the header length */
         size_t initial_offset = offset;
 

+ 7 - 0
tools/schema/Custom.Opc.Ua.Transport.bsd

@@ -18,6 +18,7 @@
     <opc:EnumeratedValue Name="MSG" Value="0x47534D" />
     <opc:EnumeratedValue Name="OPN" Value="0x4E504F" />
     <opc:EnumeratedValue Name="CLO" Value="0x4F4C43" />
+    <opc:EnumeratedValue Name="ERR" Value="0x525245" />
   </opc:EnumeratedType>
   
   <opc:EnumeratedType Name="ChunkType" LengthInBits="32">
@@ -52,6 +53,12 @@
     <opc:Field Name="MaxMessageSize" TypeName="opc:UInt32" />
 	<opc:Field Name="MaxChunkCount" TypeName="opc:UInt32" />
   </opc:StructuredType>
+
+  <opc:StructuredType Name="TcpErrorMessage">
+    <opc:Documentation>Error Message</opc:Documentation>
+    <opc:Field Name="Error" TypeName="opc:UInt32" />
+    <opc:Field Name="Reason" TypeName="opc:String" />
+  </opc:StructuredType>
   
   <opc:StructuredType Name="SecureConversationMessageHeader">
     <opc:Documentation>Secure Layer Sequence Header</opc:Documentation>

+ 1 - 0
tools/schema/datatypes_transport.txt

@@ -3,6 +3,7 @@ ChunkType
 TcpMessageHeader
 TcpHelloMessage
 TcpAcknowledgeMessage
+TcpErrorMessage
 SecureConversationMessageHeader
 AsymmetricAlgorithmSecurityHeader
 SymmetricAlgorithmSecurityHeader

+ 6 - 3
tools/travis/travis_linux_before_install.sh

@@ -1,21 +1,24 @@
 #!/bin/bash
 set -ev
 
-echo "=== Installing from external package sources ==="
+echo "=== Installing from external package sources ===" && echo -en 'travis_fold:start:before_install.external\\r'
 wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
 echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.9 main" | sudo tee -a /etc/apt/sources.list
 sudo add-apt-repository -y ppa:lttng/ppa
 sudo apt-get update -qq
 sudo apt-get install -y clang-3.9 clang-tidy-3.9
 sudo apt-get install -y liburcu4 liburcu-dev
+echo -en 'travis_fold:end:script.before_install.external\\r'
 
-echo "=== Installing python packages ==="
+echo "=== Installing python packages ===" && echo -en 'travis_fold:start:before_install.python\\r'
 pip install --user cpp-coveralls
 pip install --user sphinx
 pip install --user sphinx_rtd_theme
+echo -en 'travis_fold:end:script.before_install.python\\r'
 
-echo "=== Installed versions are ==="
+echo "=== Installed versions are ===" && echo -en 'travis_fold:start:before_install.versions\\r'
 clang --version
 g++ --version
 cppcheck --version
 valgrind --version
+echo -en 'travis_fold:end:script.before_install.versions\\r'

+ 29 - 13
tools/travis/travis_linux_script.sh

@@ -2,7 +2,7 @@
 set -ev
 
 if [ $ANALYZE = "true" ]; then
-    echo "=== Running static code analysis ==="
+    echo "=== Running static code analysis ===" && echo -en 'travis_fold:start:script.analyze\\r'
     if [ "$CC" = "clang" ]; then
         mkdir -p build
         cd build
@@ -41,10 +41,11 @@ if [ $ANALYZE = "true" ]; then
             exit 1
         fi
     fi
+    echo -en 'travis_fold:end:script.analyze\\r'
 else
     echo "=== Building ==="
 
-    echo "Documentation and certificate build"
+    echo "Documentation and certificate build"  && echo -en 'travis_fold:start:script.build.doc\\r'
     mkdir -p build
     cd build
     cmake -DCMAKE_BUILD_TYPE=Release -DUA_BUILD_EXAMPLES=ON -DUA_BUILD_DOCUMENTATION=ON -DUA_BUILD_SELFSIGNED_CERTIFICATE=ON ..
@@ -55,41 +56,46 @@ else
     cp -r doc_latex ../../
     cp ./examples/server_cert.der ../../
     cd .. && rm build -rf
+    echo -en 'travis_fold:end:script.build.doc\\r'
     
-    echo "Full Namespace 0 Generation"
+    echo "Full Namespace 0 Generation"  && echo -en 'travis_fold:start:script.build.ns0\\r'
     mkdir -p build
     cd build
     cmake -DCMAKE_BUILD_TYPE=Debug -DUA_ENABLE_GENERATE_NAMESPACE0=On -DUA_BUILD_EXAMPLES=ON  ..
     make -j
     cd .. && rm build -rf
+    echo -en 'travis_fold:end:script.build.ns0\\r'
     
     # cross compilation only with gcc
     if [ "$CC" = "gcc" ]; then
-        echo "Cross compile release build for MinGW 32 bit"
+        echo "Cross compile release build for MinGW 32 bit"  && echo -en 'travis_fold:start:script.build.cross_mingw32\\r'
         mkdir -p build && cd build
         cmake -DCMAKE_TOOLCHAIN_FILE=../tools/cmake/Toolchain-mingw32.cmake -DUA_ENABLE_AMALGAMATION=ON -DCMAKE_BUILD_TYPE=Release -DUA_BUILD_EXAMPLES=ON ..
         make -j
         zip -r open62541-win32.zip ../../doc_latex/open62541.pdf ../LICENSE ../AUTHORS ../README.md ./bin/examples/server.exe ./bin/examples/client.exe ./bin/libopen62541.dll.a open62541.h open62541.c
         cp open62541-win32.zip ..
         cd .. && rm build -rf
+    	echo -en 'travis_fold:end:script.build.cross_mingw32\\r'
 
-        echo "Cross compile release build for MinGW 64 bit"
+        echo "Cross compile release build for MinGW 64 bit"  && echo -en 'travis_fold:start:script.build.cross_mingw64\\r'
         mkdir -p build && cd build
         cmake -DCMAKE_TOOLCHAIN_FILE=../tools/cmake/Toolchain-mingw64.cmake -DUA_ENABLE_AMALGAMATION=ON -DCMAKE_BUILD_TYPE=Release -DUA_BUILD_EXAMPLES=ON ..
         make -j
         zip -r open62541-win64.zip ../../doc_latex/open62541.pdf ../LICENSE ../AUTHORS ../README.md ./bin/examples/server.exe ./bin/examples/client.exe ./bin/libopen62541.dll.a open62541.h open62541.c
         cp open62541-win64.zip ..
         cd .. && rm build -rf
+    	echo -en 'travis_fold:end:script.build.cross_mingw64\\r'
 
-        echo "Cross compile release build for 32-bit linux"
+        echo "Cross compile release build for 32-bit linux"  && echo -en 'travis_fold:start:script.build.cross_linux\\r'
         mkdir -p build && cd build
         cmake -DCMAKE_TOOLCHAIN_FILE=../tools/cmake/Toolchain-gcc-m32.cmake -DUA_ENABLE_AMALGAMATION=ON -DCMAKE_BUILD_TYPE=Release -DUA_BUILD_EXAMPLES=ON ..
         make -j
         tar -pczf open62541-linux32.tar.gz ../../doc_latex/open62541.pdf ../LICENSE ../AUTHORS ../README.md ./bin/examples/server ./bin/examples/client ./bin/libopen62541.a open62541.h open62541.c
         cp open62541-linux32.tar.gz ..
         cd .. && rm build -rf
+    	echo -en 'travis_fold:end:script.build.cross_linux\\r'
 
-        echo "Cross compile release build for RaspberryPi"
+        echo "Cross compile release build for RaspberryPi"  && echo -en 'travis_fold:start:script.build.cross_raspi\\r'
         mkdir -p build && cd build
         git clone https://github.com/raspberrypi/tools
         export PATH=$PATH:./tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/
@@ -98,9 +104,10 @@ else
         tar -pczf open62541-raspberrypi.tar.gz ../../doc_latex/open62541.pdf ../LICENSE ../AUTHORS ../README.md ./bin/examples/server ./bin/examples/client ./bin/libopen62541.a open62541.h open62541.c
         cp open62541-raspberrypi.tar.gz ..
         cd .. && rm build -rf
+    	echo -en 'travis_fold:end:script.build.cross_raspi\\r'
     fi
 
-    echo "Compile release build for 64-bit linux"
+    echo "Compile release build for 64-bit linux"  && echo -en 'travis_fold:start:script.build.linux_64\\r'
     mkdir -p build && cd build
     cmake -DCMAKE_BUILD_TYPE=Release -DUA_ENABLE_AMALGAMATION=ON -DUA_BUILD_EXAMPLES=ON ..
     make -j
@@ -109,15 +116,17 @@ else
     cp open62541.h ../.. # copy single file-release
     cp open62541.c ../.. # copy single file-release
     cd .. && rm build -rf
+	echo -en 'travis_fold:end:script.build.linux_64\\r'
 
-    echo "Building the C++ example"
+    echo "Building the C++ example"  && echo -en 'travis_fold:start:script.build.example\\r'
     mkdir -p build && cd build
     cp ../../open62541.* .
     gcc -std=c99 -c open62541.c
     g++ ../examples/server.cpp -I./ open62541.o -lrt -o cpp-server
     cd .. && rm build -rf
+	echo -en 'travis_fold:end:script.build.example\\r'
 
-    echo "Compile multithreaded version"
+    echo "Compile multithreaded version" && echo -en 'travis_fold:start:script.build.multithread\\r'
     mkdir -p build && cd build
     cmake -DUA_ENABLE_MULTITHREADING=ON -DUA_BUILD_EXAMPLES=ON ..
     make -j
@@ -128,21 +137,28 @@ else
     cmake -DUA_ENABLE_DISCOVERY=OFF -DUA_BUILD_EXAMPLES=ON ..
     make -j
     cd .. && rm build -rf
+	echo -en 'travis_fold:end:script.build.multithread\\r'
 
-    echo "Debug build and unit tests (64 bit)"
+    echo "Debug build and unit tests (64 bit)" && echo -en 'travis_fold:start:script.build.unit_test_valgrind\\r'
     mkdir -p build && cd build
     cmake -DCMAKE_BUILD_TYPE=Debug -DUA_BUILD_EXAMPLES=ON -DUA_BUILD_UNIT_TESTS=ON -DUA_ENABLE_COVERAGE=ON -DUA_ENABLE_VALGRIND_UNIT_TESTS=ON ..
     make -j && make test ARGS="-V"
     (valgrind --leak-check=yes --error-exitcode=3 ./bin/examples/server & export pid=$!; sleep 2; kill -INT $pid; wait $pid);
+	echo -en 'travis_fold:end:script.build.unit_test_valgrind\\r'
+
     # without valgrind
-    cmake -DCMAKE_BUILD_TYPE=Debug -DUA_BUILD_EXAMPLES=ON -DUA_BUILD_UNIT_TESTS=ON -DUA_ENABLE_COVERAGE=ON ..
+    echo "Debug build and unit tests without valgrind" && echo -en 'travis_fold:start:script.build.unit_test\\r'
+    cmake -DCMAKE_BUILD_TYPE=Debug -DUA_BUILD_EXAMPLES=ON -DUA_BUILD_UNIT_TESTS=ON -DUA_ENABLE_COVERAGE=ON -DUA_ENABLE_VALGRIND_UNIT_TESTS=OFF ..
     make -j && make test ARGS="-V"
     (./bin/examples/server & export pid=$!; sleep 2; kill -INT $pid; wait $pid);
+	echo -en 'travis_fold:end:script.build.unit_test\\r'
+
     # only run coveralls on main repo, otherwise it fails uploading the files
     echo "-> Current repo: ${TRAVIS_REPO_SLUG}"
     if [ "$CC" = "gcc" ] && [ "${TRAVIS_REPO_SLUG}" = "open62541/open62541" ]; then
-        echo "  Building coveralls for ${TRAVIS_REPO_SLUG}"
+        echo "  Building coveralls for ${TRAVIS_REPO_SLUG}" && echo -en 'travis_fold:start:script.build.coveralls\\r'
         coveralls -E '.*\.h' -E '.*CMakeCXXCompilerId\.cpp' -E '.*CMakeCCompilerId\.c' -r ../ || true # ignore result since coveralls is unreachable from time to time
+        echo -en 'travis_fold:end:script.build.coveralls\\r'
     fi
     cd .. && rm build -rf
 fi