Browse Source

removing merging server_rpi into server_datasource
server_datasource will be compiled as a 2nd example server

Stasik0 10 years ago
parent
commit
75355fa40f
4 changed files with 210 additions and 298 deletions
  1. 3 3
      .travis.yml
  2. 7 19
      CMakeLists.txt
  3. 200 82
      examples/server_datasource.c
  4. 0 194
      examples/server_rpi.c

+ 3 - 3
.travis.yml

@@ -36,20 +36,20 @@ script:
 - cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake -DCMAKE_BUILD_TYPE=Release
   -DEXAMPLESERVER=ON ..
 - make -j
-- zip open62541-win32.zip exampleServer.exe libopen62541.dll libopen62541.a libopen62541.dll.a
+- zip open62541-win32.zip README.md exampleServer_datasource.exe libopen62541.dll libopen62541.a libopen62541.dll.a
 - cp open62541-win32.zip ..
 - cd .. && rm build -rf && mkdir -p build && cd build
 - echo "Cross compile release build for 32-bit linux"
 - cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-gcc-m32.cmake -DCMAKE_BUILD_TYPE=Release
   -DEXAMPLESERVER=ON ..
 - make -j
-- tar -pczf open62541-linux32.tar.gz exampleServer libopen62541.so libopen62541.a
+- tar -pczf open62541-linux32.tar.gz README.md exampleServer_datasource libopen62541.so libopen62541.a
 - cp open62541-linux32.tar.gz ..
 - cd .. && rm build -rf && mkdir -p build && cd build
 - echo "Compile release build for 64-bit linux"
 - cmake -DCMAKE_BUILD_TYPE=Release -DEXAMPLESERVER=ON ..
 - make -j
-- tar -pczf open62541-linux64.tar.gz exampleServer libopen62541.so libopen62541.a
+- tar -pczf open62541-linux64.tar.gz README.md exampleServer_datasource libopen62541.so libopen62541.a
 - cp open62541-linux64.tar.gz ..
 - cd .. && rm build -rf && mkdir -p build && cd build
 - echo "Upgrade to gcc 4.8"

+ 7 - 19
CMakeLists.txt

@@ -168,38 +168,26 @@ endif()
 option(EXAMPLESERVER "Build a test server" OFF)
 if(EXAMPLESERVER)
     add_executable(exampleServer examples/server.c examples/networklayer_tcp.c examples/logger_stdout.c ${exported_headers} ${generated_headers})
+    add_executable(exampleServer_datasource examples/server_datasource.c examples/networklayer_tcp.c examples/logger_stdout.c ${exported_headers} ${generated_headers})
     target_link_libraries(exampleServer open62541-static)
+    target_link_libraries(exampleServer_datasource open62541-static)
     if(WIN32)
         target_link_libraries(exampleServer ws2_32)
+        target_link_libraries(exampleServer_datasource ws2_32)
     else()
         target_link_libraries(exampleServer rt)
+        target_link_libraries(exampleServer_datasource rt)
     endif()
     if(MULTITHREADING)
         target_link_libraries(exampleServer urcu-cds urcu urcu-common pthread)
+        target_link_libraries(exampleServer_datasource urcu-cds urcu urcu-common pthread)
     endif()
     if ((CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") AND (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR CMAKE_BUILD_TYPE STREQUAL "Release"))
     	add_custom_command(TARGET exampleServer POST_BUILD
     		COMMAND ${CMAKE_STRIP} $<TARGET_FILE:exampleServer>
 		)
-	endif()
-endif()
-
-# build rpi example server
-option(EXAMPLESERVER_RPI "Build a Raspberry Pi specific test server" OFF)
-if(EXAMPLESERVER_RPI)
-    add_executable(exampleServerRpi examples/server_rpi.c examples/networklayer_tcp.c examples/logger_stdout.c ${exported_headers} ${generated_headers})
-    target_link_libraries(exampleServerRpi open62541-static pthread)
-    if(WIN32)
-        target_link_libraries(exampleServerRpi ws2_32)
-    else()
-        target_link_libraries(exampleServerRpi rt)
-    endif()
-    if(MULTITHREADING)
-        target_link_libraries(exampleServerRpi urcu-cds urcu urcu-common)
-    endif()
-    if ((CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") AND (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR CMAKE_BUILD_TYPE STREQUAL "Release"))
-    	add_custom_command(TARGET exampleServerRpi POST_BUILD
-    		COMMAND ${CMAKE_STRIP} $<TARGET_FILE:exampleServerRpi>
+		add_custom_command(TARGET exampleServer_datasource POST_BUILD
+    		COMMAND ${CMAKE_STRIP} $<TARGET_FILE:exampleServer_datasource>
 		)
 	endif()
 endif()

+ 200 - 82
examples/server_datasource.c

@@ -9,7 +9,9 @@
 #include <stdlib.h> 
 #include <signal.h>
 #define __USE_XOPEN2K
+#ifdef UA_MULTITHREADING
 #include <pthread.h>
+#endif
 
 // provided by the open62541 lib
 #include "ua_server.h"
@@ -18,120 +20,236 @@
 #include "logger_stdout.h"
 #include "networklayer_tcp.h"
 
+/****************************/
+/* Server-related variables */
+/****************************/
+
+UA_Boolean running = 1;
+UA_Logger logger;
+
 /*************************/
 /* Read-only data source */
 /*************************/
 static UA_StatusCode readTimeData(const void *handle, UA_Boolean sourceTimeStamp, UA_DataValue *value) {
-    UA_DateTime *currentTime = UA_DateTime_new();
-    if(!currentTime)
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-    *currentTime = UA_DateTime_now();
-    value->value.type = &UA_TYPES[UA_TYPES_DATETIME];
-    value->value.arrayLength = 1;
-    value->value.dataPtr = currentTime;
-    value->value.arrayDimensionsSize = -1;
-    value->value.arrayDimensions = NULL;
-    value->hasVariant = UA_TRUE;
-    if(sourceTimeStamp) {
-        value->hasSourceTimestamp = UA_TRUE;
-        value->sourceTimestamp = *currentTime;
-    }
-    return UA_STATUSCODE_GOOD;
+	UA_DateTime *currentTime = UA_DateTime_new();
+	if(!currentTime)
+		return UA_STATUSCODE_BADOUTOFMEMORY;
+	*currentTime = UA_DateTime_now();
+	value->value.type = &UA_TYPES[UA_TYPES_DATETIME];
+	value->value.arrayLength = 1;
+	value->value.dataPtr = currentTime;
+	value->value.arrayDimensionsSize = -1;
+	value->value.arrayDimensions = NULL;
+	value->hasVariant = UA_TRUE;
+	if(sourceTimeStamp) {
+		value->hasSourceTimestamp = UA_TRUE;
+		value->sourceTimestamp = *currentTime;
+	}
+	return UA_STATUSCODE_GOOD;
 }
 
 static void releaseTimeData(const void *handle, UA_DataValue *value) {
-    UA_DateTime_delete((UA_DateTime*)value->value.dataPtr);
+	UA_DateTime_delete((UA_DateTime*)value->value.dataPtr);
 }
 
-/**************************/
-/* Read/write data source */
-/**************************/
-UA_Int32 deviceStatus = 0;
-pthread_rwlock_t deviceStatusLock;
+/*****************************/
+/* Read-only CPU temperature */
+/*      Only on Linux        */
+/*****************************/
+FILE* temperatureFile = NULL;
+static UA_StatusCode readTemperature(const void *handle, UA_Boolean sourceTimeStamp, UA_DataValue *value) {
+	UA_Double* currentTemperature = UA_Double_new();
+
+	if(!currentTemperature)
+		return UA_STATUSCODE_BADOUTOFMEMORY;
+
+	fseek(temperatureFile, 0, SEEK_SET);
+
+	if(fscanf(temperatureFile, "%lf", currentTemperature) != 1){
+		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "Can not parse temperature");
+		exit(1);
+	}
+
+	*currentTemperature /= 1000.0;
+
+	value->value.type = &UA_TYPES[UA_TYPES_DOUBLE];
+	value->value.arrayLength = 1;
+	value->value.dataPtr = currentTemperature;
+	value->value.arrayDimensionsSize = -1;
+	value->value.arrayDimensions = NULL;
+	value->hasVariant = UA_TRUE;
+	return UA_STATUSCODE_GOOD;
+}
 
-static void printDeviceStatus(UA_Server *server, void *data) {
-    printf("Device Status: %i\n", deviceStatus);
+static void releaseTemperature(const void *handle, UA_DataValue *value) {
+	UA_Double_delete((UA_Double*)value->value.dataPtr);
 }
 
-static UA_StatusCode readDeviceStatus(const void *handle, UA_Boolean sourceTimeStamp, UA_DataValue *value) {
-    /* In order to reduce blocking time, we could alloc memory for every read
+/*************************/
+/* Read-write status led */
+/*************************/
+#ifdef UA_MULTITHREADING
+pthread_rwlock_t writeLock;
+#endif
+FILE* triggerFile = NULL;
+FILE* ledFile = NULL;
+UA_Boolean ledStatus = 0;
+
+static UA_StatusCode readLedStatus(const void *handle, UA_Boolean sourceTimeStamp, UA_DataValue *value) {
+	/* In order to reduce blocking time, we could alloc memory for every read
        and return a copy of the data. */
-    pthread_rwlock_rdlock(&deviceStatusLock);
-    value->value.type = &UA_TYPES[UA_TYPES_INT32];
-    value->value.arrayLength = 1;
-    value->value.dataPtr = &deviceStatus;
-    value->value.arrayDimensionsSize = -1;
-    value->value.arrayDimensions = NULL;
-    value->hasVariant = UA_TRUE;
-    if(sourceTimeStamp) {
-        value->sourceTimestamp = UA_DateTime_now();
-        value->hasSourceTimestamp = UA_TRUE;
-    }
-    return UA_STATUSCODE_GOOD;
+#ifdef UA_MULTITHREADING
+	pthread_rwlock_rdlock(&writeLock);
+#endif
+	value->value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
+	value->value.arrayLength = 1;
+	value->value.dataPtr = &ledStatus;
+	value->value.arrayDimensionsSize = -1;
+	value->value.arrayDimensions = NULL;
+	value->hasVariant = UA_TRUE;
+	if(sourceTimeStamp) {
+		value->sourceTimestamp = UA_DateTime_now();
+		value->hasSourceTimestamp = UA_TRUE;
+	}
+	return UA_STATUSCODE_GOOD;
 }
 
-static void releaseDeviceStatus(const void *handle, UA_DataValue *value) {
-    /* If we allocated memory for a specific read, free the content of the
+static void releaseLedStatus(const void *handle, UA_DataValue *value) {
+	/* If we allocated memory for a specific read, free the content of the
        variantdata. */
-    value->value.arrayLength = -1;
-    value->value.dataPtr = NULL;
-    pthread_rwlock_unlock(&deviceStatusLock);
+	value->value.arrayLength = -1;
+	value->value.dataPtr = NULL;
+#ifdef UA_MULTITHREADING
+	pthread_rwlock_unlock(&writeLock);
+#endif
 }
 
-static UA_StatusCode writeDeviceStatus(const void *handle, const UA_Variant *data) {
-    pthread_rwlock_wrlock(&deviceStatusLock);
-    if(data->dataPtr)
-        deviceStatus = *(UA_Int32*)data->dataPtr;
-    pthread_rwlock_unlock(&deviceStatusLock);
-    return UA_STATUSCODE_GOOD;
+static UA_StatusCode writeLedStatus(const void *handle, const UA_Variant *data) {
+#ifdef UA_MULTITHREADING
+	pthread_rwlock_wrlock(&writeLock);
+#endif
+	if(data->dataPtr)
+		ledStatus = *(UA_Boolean*)data->dataPtr;
+
+	if(triggerFile)
+		fseek(triggerFile, 0, SEEK_SET);
+
+	if(ledFile){
+		if(ledStatus == 1){
+			fprintf(ledFile, "%s", "1");
+		} else {
+			fprintf(ledFile, "%s", "0");
+		}
+		fflush(ledFile);
+	}
+#ifdef UA_MULTITHREADING
+	pthread_rwlock_unlock(&writeLock);
+#endif
+	return UA_STATUSCODE_GOOD;
 }
 
-UA_Boolean running = 1;
+static void printLedStatus(UA_Server *server, void *data) {
+	UA_LOG_INFO(logger, UA_LOGGERCATEGORY_SERVER, ledStatus ? "LED is on" : "LED is off");
+}
 
 static void stopHandler(int sign) {
-    printf("Received Ctrl-C\n");
+	printf("Received Ctrl-C\n");
 	running = 0;
 }
 
 int main(int argc, char** argv) {
 	signal(SIGINT, stopHandler); /* catches ctrl-c */
-    pthread_rwlock_init(&deviceStatusLock, 0);
+#ifdef UA_MULTITHREADING
+	pthread_rwlock_init(&writeLock, 0);
+#endif
 
 	UA_Server *server = UA_Server_new();
-    UA_Server_addNetworkLayer(server, ServerNetworkLayerTCP_new(UA_ConnectionConfig_standard, 16664));
+	logger = Logger_Stdout_new();
+	UA_Server_setLogger(server, logger);
+	UA_Server_addNetworkLayer(server, ServerNetworkLayerTCP_new(UA_ConnectionConfig_standard, 16664));
 
-    // add node with the datetime data source
-    UA_DataSource dateDataSource = (UA_DataSource)
-        {.handle = NULL,
-         .read = readTimeData,
-         .release = releaseTimeData,
-         .write = NULL};
-    UA_QualifiedName dateName;
-    UA_QUALIFIEDNAME_ASSIGN(dateName, "the time");
-    UA_Server_addDataSourceVariableNode(server, dateDataSource, &UA_NODEID_NULL, &dateName,
-                                        &UA_NODEID_STATIC(0, UA_NS0ID_OBJECTSFOLDER),
-                                        &UA_NODEID_STATIC(0, UA_NS0ID_ORGANIZES));
-
-    // print the status every 2 sec
-    UA_WorkItem work = {.type = UA_WORKITEMTYPE_METHODCALL,
-                        .work.methodCall = {.method = printDeviceStatus, .data = NULL} };
-    UA_Server_addRepeatedWorkItem(server, &work, 20000000, NULL);
-
-    // add node with the device status data source
-    UA_DataSource deviceStatusDataSource = (UA_DataSource)
+	// print the status every 2 sec
+	UA_WorkItem work = {.type = UA_WORKITEMTYPE_METHODCALL,
+			.work.methodCall = {.method = printLedStatus, .data = NULL} };
+	UA_Server_addRepeatedWorkItem(server, &work, 20000000, NULL);
+
+	// add node with the datetime data source
+	UA_DataSource dateDataSource = (UA_DataSource)
         {.handle = NULL,
-         .read = readDeviceStatus,
-         .release = releaseDeviceStatus,
-         .write = writeDeviceStatus};
-    UA_QualifiedName statusName;
-    UA_QUALIFIEDNAME_ASSIGN(statusName, "device status");
-    UA_Server_addDataSourceVariableNode(server, deviceStatusDataSource, &UA_NODEID_NULL, &statusName,
-                              &UA_NODEID_STATIC(0, UA_NS0ID_OBJECTSFOLDER),
-                              &UA_NODEID_STATIC(0, UA_NS0ID_ORGANIZES));
-
-    UA_StatusCode retval = UA_Server_run(server, 1, &running);
+		.read = readTimeData,
+		.release = releaseTimeData,
+		.write = NULL};
+	UA_QualifiedName dateName;
+	UA_QUALIFIEDNAME_ASSIGN(dateName, "current time");
+	UA_Server_addDataSourceVariableNode(server, dateDataSource, &UA_NODEID_NULL, &dateName,
+			&UA_NODEID_STATIC(0, UA_NS0ID_OBJECTSFOLDER),
+			&UA_NODEID_STATIC(0, UA_NS0ID_ORGANIZES));
+
+	if(!(temperatureFile = fopen("/sys/class/thermal/thermal_zone0/temp", "r"))){
+		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "[Linux specific] Can not open temperature file, no temperature node will be added");
+	} else {
+		// add node with the datetime data source
+		UA_DataSource temperatureDataSource = (UA_DataSource)
+    	    {.handle = NULL,
+			.read = readTemperature,
+			.release = releaseTemperature,
+			.write = NULL};
+		UA_QualifiedName ledName;
+		UA_QUALIFIEDNAME_ASSIGN(ledName, "cpu temperature");
+		UA_Server_addDataSourceVariableNode(server, temperatureDataSource, &UA_NODEID_NULL, &ledName,
+				&UA_NODEID_STATIC(0, UA_NS0ID_OBJECTSFOLDER),
+				&UA_NODEID_STATIC(0, UA_NS0ID_ORGANIZES));
+	}
+
+	if (	!(triggerFile = fopen("/sys/class/leds/led0/trigger", "w"))
+		|| 	!(ledFile = fopen("/sys/class/leds/led0/brightness", "w"))) {
+		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "[Raspberry Pi specific] Can not open trigger or LED file (try to run server with sudo if on a Raspberry PI)");
+		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "An LED node will be added but no physical LED will be operated");
+	} else {
+		//setting led mode to manual
+		fprintf(triggerFile, "%s", "none");
+		fflush(triggerFile);
+
+		//turning off led initially
+		fprintf(ledFile, "%s", "1");
+		fflush(ledFile);
+	}
+
+	// add node with the LED status data source
+	UA_DataSource ledStatusDataSource = (UA_DataSource)
+   		{.handle = NULL,
+		.read = readLedStatus,
+		.release = releaseLedStatus,
+		.write = writeLedStatus};
+	UA_QualifiedName statusName;
+	UA_QUALIFIEDNAME_ASSIGN(statusName, "status LED");
+	UA_Server_addDataSourceVariableNode(server, ledStatusDataSource, &UA_NODEID_NULL, &statusName,
+			&UA_NODEID_STATIC(0, UA_NS0ID_OBJECTSFOLDER),
+			&UA_NODEID_STATIC(0, UA_NS0ID_ORGANIZES));
+
+	//start server
+	UA_StatusCode retval = UA_Server_run(server, 1, &running); //blocks until running=false
+
+	//ctrl-c received -> clean up
 	UA_Server_delete(server);
-    pthread_rwlock_destroy(&deviceStatusLock);
+
+	if(temperatureFile)
+		fclose(temperatureFile);
+
+	if(triggerFile){
+		fseek(triggerFile, 0, SEEK_SET);
+		//setting led mode to default
+		fprintf(triggerFile, "%s", "mmc0");
+		fclose(triggerFile);
+	}
+
+	if(ledFile){
+		fclose(ledFile);
+	}
+
+#ifdef UA_MULTITHREADING
+	pthread_rwlock_destroy(&writeLock);
+#endif
 
 	return retval;
 }

+ 0 - 194
examples/server_rpi.c

@@ -1,194 +0,0 @@
-/*
- * This work is licensed under a Creative Commons CCZero 1.0 Universal License.
- * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
- */
-#include <time.h>
-#include "ua_types.h"
-
-#include <stdio.h>
-#include <stdlib.h> 
-#include <signal.h>
-#define __USE_XOPEN2K
-#include <pthread.h>
-
-// provided by the open62541 lib
-#include "ua_server.h"
-
-// provided by the user, implementations available in the /examples folder
-#include "logger_stdout.h"
-#include "networklayer_tcp.h"
-
-UA_Boolean running = 1;
-UA_Logger logger;
-
-/*************************/
-/* Read-only temperature */
-/*************************/
-FILE* temperatureFile = NULL;
-static UA_StatusCode readTemperature(const void *handle, UA_Boolean sourceTimeStamp, UA_DataValue *value) {
-	UA_Double* currentTemperature = UA_Double_new();
-
-	if(!currentTemperature)
-		return UA_STATUSCODE_BADOUTOFMEMORY;
-
-	if (fseek(temperatureFile, 0, SEEK_SET))
-	{
-		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "Error seeking to start of file");
-		exit(1);
-	}
-
-	if(fscanf(temperatureFile, "%lf", currentTemperature) != 1){
-		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "Can not parse temperature");
-		exit(1);
-	}
-
-	*currentTemperature /= 1000.0;
-
-	value->value.type = &UA_TYPES[UA_TYPES_DOUBLE];
-	value->value.arrayLength = 1;
-	value->value.dataPtr = currentTemperature;
-	value->value.arrayDimensionsSize = -1;
-	value->value.arrayDimensions = NULL;
-	value->hasVariant = UA_TRUE;
-	return UA_STATUSCODE_GOOD;
-}
-
-static void releaseTemperature(const void *handle, UA_DataValue *value) {
-	UA_Double_delete((UA_Double*)value->value.dataPtr);
-}
-
-/*************************/
-/* Read-write status led */
-/*************************/
-pthread_rwlock_t ledStatusLock;
-FILE* triggerFile = NULL;
-FILE* ledFile = NULL;
-UA_Boolean ledStatus = 0;
-
-static UA_StatusCode readLedStatus(const void *handle, UA_Boolean sourceTimeStamp, UA_DataValue *value) {
-    /* In order to reduce blocking time, we could alloc memory for every read
-       and return a copy of the data. */
-    pthread_rwlock_rdlock(&ledStatusLock);
-    value->value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
-    value->value.arrayLength = 1;
-    value->value.dataPtr = &ledStatus;
-    value->value.arrayDimensionsSize = -1;
-    value->value.arrayDimensions = NULL;
-    value->hasVariant = UA_TRUE;
-    if(sourceTimeStamp) {
-        value->sourceTimestamp = UA_DateTime_now();
-        value->hasSourceTimestamp = UA_TRUE;
-    }
-    return UA_STATUSCODE_GOOD;
-}
-
-static void releaseLedStatus(const void *handle, UA_DataValue *value) {
-    /* If we allocated memory for a specific read, free the content of the
-       variantdata. */
-    value->value.arrayLength = -1;
-    value->value.dataPtr = NULL;
-    pthread_rwlock_unlock(&ledStatusLock);
-}
-
-static UA_StatusCode writeLedStatus(const void *handle, const UA_Variant *data) {
-    pthread_rwlock_wrlock(&ledStatusLock);
-    if(data->dataPtr)
-        ledStatus = *(UA_Boolean*)data->dataPtr;
-
-	if (fseek(triggerFile, 0, SEEK_SET))
-	{
-		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "Error seeking to start of led file");
-	}
-    if(ledStatus == 1){
-    	fprintf(ledFile, "%s", "1");
-    } else {
-    	fprintf(ledFile, "%s", "0");
-    }
-    fflush(ledFile);
-
-    pthread_rwlock_unlock(&ledStatusLock);
-    return UA_STATUSCODE_GOOD;
-}
-
-static void stopHandler(int sign) {
-	UA_LOG_INFO(logger, UA_LOGGERCATEGORY_SERVER, "Received Ctrl-C");
-	running = 0;
-}
-
-int main(int argc, char** argv) {
-
-	signal(SIGINT, stopHandler); /* catches ctrl-c */
-	pthread_rwlock_init(&ledStatusLock, 0);
-
-	UA_Server *server = UA_Server_new();
-	logger = Logger_Stdout_new();
-	UA_Server_setLogger(server, logger);
-	UA_Server_addNetworkLayer(server, ServerNetworkLayerTCP_new(UA_ConnectionConfig_standard, 16664));
-
-	if(!(temperatureFile = fopen("/sys/class/thermal/thermal_zone0/temp", "r"))){
-		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "[Linux specific] Can not open temperature file, no temperature node will be added");
-	} else {
-		// add node with the datetime data source
-		UA_DataSource temperatureDataSource = (UA_DataSource)
-	        				{.handle = NULL,
-							.read = readTemperature,
-							.release = releaseTemperature,
-							.write = NULL};
-		UA_QualifiedName dateName;
-		UA_QUALIFIEDNAME_ASSIGN(dateName, "cpu temperature");
-		UA_Server_addDataSourceVariableNode(server, temperatureDataSource, &UA_NODEID_NULL, &dateName,
-				&UA_NODEID_STATIC(0, UA_NS0ID_OBJECTSFOLDER),
-				&UA_NODEID_STATIC(0, UA_NS0ID_ORGANIZES));
-	}
-
-	if (	!(triggerFile = fopen("/sys/class/leds/led0/trigger", "w"))
-			|| 	!(ledFile = fopen("/sys/class/leds/led0/brightness", "w"))) {
-		UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "[Raspberry Pi specific] Can not open trigger or led file, no led node will be added (try to run server from sudo)");
-	} else {
-		//setting led mode to manual
-		fprintf(triggerFile, "%s", "none");
-		fflush(triggerFile);
-
-		//turning off led initially
-		fprintf(ledFile, "%s", "1");
-		fflush(ledFile);
-
-		// add node with the device status data source
-		UA_DataSource ledStatusDataSource = (UA_DataSource)
-		        		{.handle = NULL,
-						.read = readLedStatus,
-						.release = releaseLedStatus,
-						.write = writeLedStatus};
-		UA_QualifiedName statusName;
-		UA_QUALIFIEDNAME_ASSIGN(statusName, "status led");
-		UA_Server_addDataSourceVariableNode(server, ledStatusDataSource, &UA_NODEID_NULL, &statusName,
-				&UA_NODEID_STATIC(0, UA_NS0ID_OBJECTSFOLDER),
-				&UA_NODEID_STATIC(0, UA_NS0ID_ORGANIZES));
-	}
-
-
-	UA_StatusCode retval = UA_Server_run(server, 1, &running);
-	UA_Server_delete(server);
-
-	if(temperatureFile)
-		fclose(temperatureFile);
-
-	if(triggerFile){
-		if (fseek(triggerFile, 0, SEEK_SET))
-		{
-			UA_LOG_WARNING(logger, UA_LOGGERCATEGORY_USERLAND, "Error seeking to start of led file");
-		}
-
-		//setting led mode to default
-		fprintf(triggerFile, "%s", "mmc0");
-		fclose(triggerFile);
-	}
-
-	if(ledFile){
-		fclose(ledFile);
-	}
-
-    pthread_rwlock_destroy(&ledStatusLock);
-
-	return retval;
-}