diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp
index 60f08b88..1bd58698 100644
--- a/datapool/PoolDataSetBase.cpp
+++ b/datapool/PoolDataSetBase.cpp
@@ -64,11 +64,11 @@ ReturnValue_t PoolDataSetBase::read(MutexIF::TimeoutType timeoutType,
     }
     else {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "DataSet::read(): Call made in wrong position. Don't forget to commit"
-                " member datasets!" << std::endl;
+        sif::warning << "PoolDataSetBase::read: Call made in wrong position. Don't forget to "
+                "commit member datasets!" << std::endl;
 #else
-        sif::printError("DataSet::read(): Call made in wrong position. Don't forget to commit"
-                " member datasets!\n");
+        sif::printWarning("PoolDataSetBase::read: Call made in wrong position. Don't forget to "
+                "commit member datasets!\n");
 #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
         result = SET_WAS_ALREADY_READ;
     }
diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp
index 7e5a316c..78618448 100644
--- a/internalError/InternalErrorReporter.cpp
+++ b/internalError/InternalErrorReporter.cpp
@@ -3,19 +3,20 @@
 #include "../ipc/QueueFactory.h"
 #include "../ipc/MutexFactory.h"
 #include "../serviceinterface/ServiceInterface.h"
+#include "../datapool/PoolReadGuard.h"
 
 InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId,
         uint32_t messageQueueDepth): SystemObject(setObjectId),
-		commandQueue(QueueFactory::instance()->
-		        createMessageQueue(messageQueueDepth)),
-		poolManager(this, commandQueue),
-		internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
-		internalErrorDataset(this) {
-	mutex = MutexFactory::instance()->createMutex();
+        commandQueue(QueueFactory::instance()->
+                createMessageQueue(messageQueueDepth)),
+                poolManager(this, commandQueue),
+                internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
+                internalErrorDataset(this) {
+    mutex = MutexFactory::instance()->createMutex();
 }
 
 InternalErrorReporter::~InternalErrorReporter() {
-	MutexFactory::instance()->deleteMutex(mutex);
+    MutexFactory::instance()->deleteMutex(mutex);
 }
 
 void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
@@ -23,126 +24,128 @@ void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
 }
 
 ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
-    internalErrorDataset.read(timeoutType, timeoutMs);
+    CommandMessage message;
+    ReturnValue_t result = commandQueue->receiveMessage(&message);
+    if(result != MessageQueueIF::EMPTY) {
+        poolManager.handleHousekeepingMessage(&message);
+    }
 
-	uint32_t newQueueHits = getAndResetQueueHits();
-	uint32_t newTmHits = getAndResetTmHits();
-	uint32_t newStoreHits = getAndResetStoreHits();
+    uint32_t newQueueHits = getAndResetQueueHits();
+    uint32_t newTmHits = getAndResetTmHits();
+    uint32_t newStoreHits = getAndResetStoreHits();
 
-#if FSFW_VERBOSE_LEVEL == 1
-	if(diagnosticPrintout) {
-	    if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
+#if FSFW_VERBOSE_LEVEL >= 1
+    if(diagnosticPrintout) {
+        if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-	        sif::debug << "InternalErrorReporter::performOperation: Errors "
-	                << "occured!" << std::endl;
-	        sif::debug << "Queue errors: " << newQueueHits << std::endl;
-	        sif::debug << "TM errors: " << newTmHits << std::endl;
-	        sif::debug << "Store errors: " << newStoreHits << std::endl;
+            sif::debug << "InternalErrorReporter::performOperation: Errors "
+                    << "occured!" << std::endl;
+            sif::debug << "Queue errors: " << newQueueHits << std::endl;
+            sif::debug << "TM errors: " << newTmHits << std::endl;
+            sif::debug << "Store errors: " << newStoreHits << std::endl;
 #else
-	        sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
-	        sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
-	        sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
-	        sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
+            sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
+            sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
+            sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
+            sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
 #endif
-	    }
-	}
+        }
+    }
 #endif
 
-	internalErrorDataset.queueHits.value += newQueueHits;
-	internalErrorDataset.storeHits.value += newStoreHits;
-	internalErrorDataset.tmHits.value += newTmHits;
-	internalErrorDataset.setValidity(true, true);
-	internalErrorDataset.commit(timeoutType, timeoutMs);
+    {
+        PoolReadGuard readGuard(&internalErrorDataset);
+        if(readGuard.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
+            internalErrorDataset.queueHits.value += newQueueHits;
+            internalErrorDataset.storeHits.value += newStoreHits;
+            internalErrorDataset.tmHits.value += newTmHits;
+            internalErrorDataset.setValidity(true, true);
+        }
+    }
 
-	poolManager.performHkOperation();
-
-	CommandMessage message;
-	ReturnValue_t result = commandQueue->receiveMessage(&message);
-	if(result != MessageQueueIF::EMPTY) {
-	    poolManager.handleHousekeepingMessage(&message);
-	}
-	return HasReturnvaluesIF::RETURN_OK;
+    poolManager.performHkOperation();
+    return HasReturnvaluesIF::RETURN_OK;
 }
 
 void InternalErrorReporter::queueMessageNotSent() {
-	incrementQueueHits();
+    incrementQueueHits();
 }
 
 void InternalErrorReporter::lostTm() {
-	incrementTmHits();
+    incrementTmHits();
 }
 
 uint32_t InternalErrorReporter::getAndResetQueueHits() {
-	uint32_t value;
-	mutex->lockMutex(timeoutType, timeoutMs);
-	value = queueHits;
-	queueHits = 0;
-	mutex->unlockMutex();
-	return value;
+    uint32_t value;
+    mutex->lockMutex(timeoutType, timeoutMs);
+    value = queueHits;
+    queueHits = 0;
+    mutex->unlockMutex();
+    return value;
 }
 
 uint32_t InternalErrorReporter::getQueueHits() {
-	uint32_t value;
-	mutex->lockMutex(timeoutType, timeoutMs);
-	value = queueHits;
-	mutex->unlockMutex();
-	return value;
+    uint32_t value;
+    mutex->lockMutex(timeoutType, timeoutMs);
+    value = queueHits;
+    mutex->unlockMutex();
+    return value;
 }
 
 void InternalErrorReporter::incrementQueueHits() {
-	mutex->lockMutex(timeoutType, timeoutMs);
-	queueHits++;
-	mutex->unlockMutex();
+    mutex->lockMutex(timeoutType, timeoutMs);
+    queueHits++;
+    mutex->unlockMutex();
 }
 
 uint32_t InternalErrorReporter::getAndResetTmHits() {
-	uint32_t value;
-	mutex->lockMutex(timeoutType, timeoutMs);
-	value = tmHits;
-	tmHits = 0;
-	mutex->unlockMutex();
-	return value;
+    uint32_t value;
+    mutex->lockMutex(timeoutType, timeoutMs);
+    value = tmHits;
+    tmHits = 0;
+    mutex->unlockMutex();
+    return value;
 }
 
 uint32_t InternalErrorReporter::getTmHits() {
-	uint32_t value;
-	mutex->lockMutex(timeoutType, timeoutMs);
-	value = tmHits;
-	mutex->unlockMutex();
-	return value;
+    uint32_t value;
+    mutex->lockMutex(timeoutType, timeoutMs);
+    value = tmHits;
+    mutex->unlockMutex();
+    return value;
 }
 
 void InternalErrorReporter::incrementTmHits() {
-	mutex->lockMutex(timeoutType, timeoutMs);
-	tmHits++;
-	mutex->unlockMutex();
+    mutex->lockMutex(timeoutType, timeoutMs);
+    tmHits++;
+    mutex->unlockMutex();
 }
 
 void InternalErrorReporter::storeFull() {
-	incrementStoreHits();
+    incrementStoreHits();
 }
 
 uint32_t InternalErrorReporter::getAndResetStoreHits() {
-	uint32_t value;
-	mutex->lockMutex(timeoutType, timeoutMs);
-	value = storeHits;
-	storeHits = 0;
-	mutex->unlockMutex();
-	return value;
+    uint32_t value;
+    mutex->lockMutex(timeoutType, timeoutMs);
+    value = storeHits;
+    storeHits = 0;
+    mutex->unlockMutex();
+    return value;
 }
 
 uint32_t InternalErrorReporter::getStoreHits() {
-	uint32_t value;
-	mutex->lockMutex(timeoutType, timeoutMs);
-	value = storeHits;
-	mutex->unlockMutex();
-	return value;
+    uint32_t value;
+    mutex->lockMutex(timeoutType, timeoutMs);
+    value = storeHits;
+    mutex->unlockMutex();
+    return value;
 }
 
 void InternalErrorReporter::incrementStoreHits() {
-	mutex->lockMutex(timeoutType, timeoutMs);
-	storeHits++;
-	mutex->unlockMutex();
+    mutex->lockMutex(timeoutType, timeoutMs);
+    storeHits++;
+    mutex->unlockMutex();
 }
 
 object_id_t InternalErrorReporter::getObjectId() const {
@@ -155,14 +158,11 @@ MessageQueueId_t InternalErrorReporter::getCommandQueue() const {
 
 ReturnValue_t InternalErrorReporter::initializeLocalDataPool(
         localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
-    localDataPoolMap.emplace(errorPoolIds::TM_HITS,
-            new PoolEntry<uint32_t>());
-    localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS,
-            new PoolEntry<uint32_t>());
-    localDataPoolMap.emplace(errorPoolIds::STORE_HITS,
-            new PoolEntry<uint32_t>());
-    poolManager.subscribeForPeriodicPacket(internalErrorSid, false,
-            getPeriodicOperationFrequency(), true);
+    localDataPoolMap.emplace(errorPoolIds::TM_HITS, new PoolEntry<uint32_t>());
+    localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, new PoolEntry<uint32_t>());
+    localDataPoolMap.emplace(errorPoolIds::STORE_HITS, new PoolEntry<uint32_t>());
+    poolManager.subscribeForPeriodicPacket(internalErrorSid, false, getPeriodicOperationFrequency(),
+            true);
     internalErrorDataset.setValidity(true, true);
     return HasReturnvaluesIF::RETURN_OK;
 }
@@ -192,9 +192,9 @@ ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() {
 }
 
 void InternalErrorReporter::setMutexTimeout(MutexIF::TimeoutType timeoutType,
-		uint32_t timeoutMs) {
-	this->timeoutType = timeoutType;
-	this->timeoutMs = timeoutMs;
+        uint32_t timeoutMs) {
+    this->timeoutType = timeoutType;
+    this->timeoutMs = timeoutMs;
 }
 
 LocalDataPoolManager* InternalErrorReporter::getHkManagerHandle() {
diff --git a/internalError/InternalErrorReporter.h b/internalError/InternalErrorReporter.h
index a237418e..580cb8f6 100644
--- a/internalError/InternalErrorReporter.h
+++ b/internalError/InternalErrorReporter.h
@@ -17,77 +17,78 @@
  * All functions were kept virtual so this class can be extended easily
  * to store custom internal errors (e.g. communication interface errors).
  */
-class InternalErrorReporter: public SystemObject,
-		public ExecutableObjectIF,
-		public InternalErrorReporterIF,
-		public HasLocalDataPoolIF {
+class InternalErrorReporter:
+        public SystemObject,
+        public ExecutableObjectIF,
+        public InternalErrorReporterIF,
+        public HasLocalDataPoolIF {
 public:
 
-	InternalErrorReporter(object_id_t setObjectId,
-	        uint32_t messageQueueDepth = 5);
+    InternalErrorReporter(object_id_t setObjectId,
+            uint32_t messageQueueDepth = 5);
 
-	/**
-	 * Enable diagnostic printout. Please note that this feature will
-	 * only work if DEBUG has been supplied to the build defines.
-	 * @param enable
-	 */
-	void setDiagnosticPrintout(bool enable);
+    /**
+     * Enable diagnostic printout. Please note that this feature will
+     * only work if DEBUG has been supplied to the build defines.
+     * @param enable
+     */
+    void setDiagnosticPrintout(bool enable);
 
-	void setMutexTimeout(MutexIF::TimeoutType timeoutType,
-			uint32_t timeoutMs);
+    void setMutexTimeout(MutexIF::TimeoutType timeoutType,
+            uint32_t timeoutMs);
 
-	virtual ~InternalErrorReporter();
+    virtual ~InternalErrorReporter();
 
     virtual object_id_t getObjectId() const override;
     virtual MessageQueueId_t getCommandQueue() const override;
     virtual ReturnValue_t initializeLocalDataPool(
-    		localpool::DataPool& localDataPoolMap,
+            localpool::DataPool& localDataPoolMap,
             LocalDataPoolManager& poolManager) override;
     virtual dur_millis_t getPeriodicOperationFrequency() const override;
     virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
-	LocalDataPoolManager* getHkManagerHandle() override;
+    LocalDataPoolManager* getHkManagerHandle() override;
 
     virtual ReturnValue_t initialize() override;
     virtual ReturnValue_t initializeAfterTaskCreation() override;
-	virtual ReturnValue_t performOperation(uint8_t opCode) override;
+    virtual ReturnValue_t performOperation(uint8_t opCode) override;
 
-	virtual void queueMessageNotSent();
+    virtual void queueMessageNotSent();
 
-	virtual void lostTm();
+    virtual void lostTm();
 
-	virtual void storeFull();
+    virtual void storeFull();
 
-	virtual void setTaskIF(PeriodicTaskIF* task) override;
+    virtual void setTaskIF(PeriodicTaskIF* task) override;
 protected:
-	MessageQueueIF* commandQueue;
-	LocalDataPoolManager poolManager;
+    MessageQueueIF* commandQueue;
+    LocalDataPoolManager poolManager;
 
-	PeriodicTaskIF* executingTask = nullptr;
+    PeriodicTaskIF* executingTask = nullptr;
 
-	MutexIF* mutex = nullptr;
-	MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
-	uint32_t timeoutMs = 20;
+    MutexIF* mutex = nullptr;
+    MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
+    uint32_t timeoutMs = 20;
 
-	sid_t internalErrorSid;
-	InternalErrorDataset internalErrorDataset;
+    sid_t internalErrorSid;
+    InternalErrorDataset internalErrorDataset;
 
-	bool diagnosticPrintout = true;
+    bool diagnosticPrintout = true;
 
-	uint32_t queueHits = 0;
-	uint32_t tmHits = 0;
-	uint32_t storeHits = 0;
+    uint32_t queueHits = 0;
+    uint32_t tmHits = 0;
+    uint32_t storeHits = 0;
 
-	uint32_t getAndResetQueueHits();
-	uint32_t getQueueHits();
-	void incrementQueueHits();
+    uint32_t getAndResetQueueHits();
+    uint32_t getQueueHits();
+    void incrementQueueHits();
 
-	uint32_t getAndResetTmHits();
-	uint32_t getTmHits();
-	void incrementTmHits();
+    uint32_t getAndResetTmHits();
+    uint32_t getTmHits();
+    void incrementTmHits();
 
-	uint32_t getAndResetStoreHits();
-	uint32_t getStoreHits();
-	void incrementStoreHits();
+    uint32_t getAndResetStoreHits();
+    uint32_t getStoreHits();
+    void incrementStoreHits();
 
 };
 
diff --git a/osal/common/CMakeLists.txt b/osal/common/CMakeLists.txt
index b77985fb..af76484d 100644
--- a/osal/common/CMakeLists.txt
+++ b/osal/common/CMakeLists.txt
@@ -1,3 +1,16 @@
-target_sources(${LIB_FSFW_NAME} PRIVATE 
-    tcpipCommon.cpp
-)
+if(DEFINED WIN32 OR DEFINED UNIX)
+    target_sources(${LIB_FSFW_NAME} PRIVATE 
+        tcpipCommon.cpp
+        TcpIpBase.cpp
+        UdpTcPollingTask.cpp
+        UdpTmTcBridge.cpp
+        TcpTmTcServer.cpp
+    )
+endif()
+
+if(WIN32)
+    target_link_libraries(${LIB_FSFW_NAME} PRIVATE
+        wsock32 
+        ws2_32
+    )
+endif()
\ No newline at end of file
diff --git a/osal/common/TcpIpBase.cpp b/osal/common/TcpIpBase.cpp
new file mode 100644
index 00000000..27384ecc
--- /dev/null
+++ b/osal/common/TcpIpBase.cpp
@@ -0,0 +1,54 @@
+#include "TcpIpBase.h"
+
+#ifdef __unix__
+
+#include <errno.h>
+#include <unistd.h>
+
+#endif
+
+TcpIpBase::TcpIpBase() {
+
+}
+
+ReturnValue_t TcpIpBase::initialize() {
+#ifdef _WIN32
+    /* Initiates Winsock DLL. */
+    WSAData wsaData;
+    WORD wVersionRequested = MAKEWORD(2, 2);
+    int err = WSAStartup(wVersionRequested, &wsaData);
+    if (err != 0) {
+        /* Tell the user that we could not find a usable Winsock DLL. */
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: " <<
+                err << std::endl;
+#endif
+        return HasReturnvaluesIF::RETURN_FAILED;
+    }
+#endif
+    return HasReturnvaluesIF::RETURN_OK;
+}
+
+TcpIpBase::~TcpIpBase() {
+    closeSocket(serverSocket);
+#ifdef _WIN32
+    WSACleanup();
+#endif
+}
+
+int TcpIpBase::closeSocket(socket_t socket) {
+#ifdef _WIN32
+    return closesocket(socket);
+#elif defined(__unix__)
+    return close(socket);
+#endif
+}
+
+int TcpIpBase::getLastSocketError() {
+#ifdef _WIN32
+    return WSAGetLastError();
+#elif defined(__unix__)
+    return errno;
+#endif
+}
+
diff --git a/osal/common/TcpIpBase.h b/osal/common/TcpIpBase.h
new file mode 100644
index 00000000..652d791a
--- /dev/null
+++ b/osal/common/TcpIpBase.h
@@ -0,0 +1,50 @@
+#ifndef FSFW_OSAL_COMMON_TCPIPIF_H_
+#define FSFW_OSAL_COMMON_TCPIPIF_H_
+
+#include <fsfw/returnvalues/HasReturnvaluesIF.h>
+
+#ifdef _WIN32
+
+#include <winsock2.h>
+
+#elif defined(__unix__)
+
+#include <sys/socket.h>
+
+#endif
+
+class TcpIpBase {
+protected:
+
+#ifdef _WIN32
+    static constexpr int SHUT_RECV = SD_RECEIVE;
+    static constexpr int SHUT_SEND = SD_SEND;
+    static constexpr int SHUT_BOTH = SD_BOTH;
+
+    using socket_t = SOCKET;
+#elif defined(__unix__)
+    using socket_t = int;
+
+    static constexpr int INVALID_SOCKET = -1;
+    static constexpr int SOCKET_ERROR = -1;
+
+    static constexpr int SHUT_RECV = SHUT_RD;
+    static constexpr int SHUT_SEND = SHUT_WR;
+    static constexpr int SHUT_BOTH = SHUT_RDWR;
+#endif
+
+    TcpIpBase();
+    virtual ~TcpIpBase();
+
+    ReturnValue_t initialize();
+
+    int closeSocket(socket_t socket);
+
+    int getLastSocketError();
+
+    socket_t serverSocket = 0;
+
+};
+
+
+#endif /* FSFW_OSAL_COMMON_TCPIPIF_H_ */
diff --git a/osal/windows/TcWinTcpServer.cpp b/osal/common/TcpTmTcServer.cpp
similarity index 64%
rename from osal/windows/TcWinTcpServer.cpp
rename to osal/common/TcpTmTcServer.cpp
index f68edfba..296afad8 100644
--- a/osal/windows/TcWinTcpServer.cpp
+++ b/osal/common/TcpTmTcServer.cpp
@@ -1,14 +1,21 @@
-#include "TcWinTcpServer.h"
+#include "TcpTmTcServer.h"
 #include "tcpipHelpers.h"
 #include "../../serviceinterface/ServiceInterface.h"
 
+#ifdef _WIN32
 #include <winsock2.h>
 #include <ws2tcpip.h>
 
-const std::string TcWinTcpServer::DEFAULT_TCP_SERVER_PORT =  "7301";
-const std::string TcWinTcpServer::DEFAULT_TCP_CLIENT_PORT =  "7302";
+#elif defined(__unix__)
 
-TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
+#include <netdb.h>
+
+#endif
+
+const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT =  "7301";
+const std::string TcpTmTcServer::DEFAULT_TCP_CLIENT_PORT =  "7302";
+
+TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
         std::string customTcpServerPort):
         SystemObject(objectId), tcpPort(customTcpServerPort) {
     if(tcpPort == "") {
@@ -16,25 +23,18 @@ TcWinTcpServer::TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBrid
     }
 }
 
-ReturnValue_t TcWinTcpServer::initialize() {
+ReturnValue_t TcpTmTcServer::initialize() {
     using namespace tcpip;
-    int retval = 0;
-    struct addrinfo *addrResult = nullptr;
-    struct addrinfo hints;
-    /* Initiates Winsock DLL. */
-    WSAData wsaData;
-    WORD wVersionRequested = MAKEWORD(2, 2);
-    int err = WSAStartup(wVersionRequested, &wsaData);
-    if (err != 0) {
-        /* Tell the user that we could not find a usable Winsock DLL. */
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: " <<
-                err << std::endl;
-#endif
-        return HasReturnvaluesIF::RETURN_FAILED;
+
+    ReturnValue_t result = TcpIpBase::initialize();
+    if(result != HasReturnvaluesIF::RETURN_OK) {
+        return result;
     }
 
-    ZeroMemory(&hints, sizeof (hints));
+    int retval = 0;
+    struct addrinfo *addrResult = nullptr;
+    struct addrinfo hints = {};
+
     hints.ai_family = AF_INET;
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_protocol = IPPROTO_TCP;
@@ -43,7 +43,7 @@ ReturnValue_t TcWinTcpServer::initialize() {
     retval = getaddrinfo(nullptr, tcpPort.c_str(), &hints, &addrResult);
     if (retval != 0) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TcWinTcpServer::TcWinTcpServer: Retrieving address info failed!" <<
+        sif::warning << "TcWinTcpServer::TcpTmTcServer: Retrieving address info failed!" <<
                 std::endl;
 #endif
         handleError(Protocol::TCP, ErrorSources::GETADDRINFO_CALL);
@@ -65,7 +65,7 @@ ReturnValue_t TcWinTcpServer::initialize() {
     retval = bind(listenerTcpSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
     if(retval == SOCKET_ERROR) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TcWinTcpServer::TcWinTcpServer: Binding socket failed!" <<
+        sif::warning << "TcWinTcpServer::TcpTmTcServer: Binding socket failed!" <<
                 std::endl;
 #endif
         freeaddrinfo(addrResult);
@@ -77,17 +77,16 @@ ReturnValue_t TcWinTcpServer::initialize() {
 }
 
 
-TcWinTcpServer::~TcWinTcpServer() {
-    closesocket(listenerTcpSocket);
-    WSACleanup();
+TcpTmTcServer::~TcpTmTcServer() {
+    closeSocket(listenerTcpSocket);
 }
 
-ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) {
+ReturnValue_t TcpTmTcServer::performOperation(uint8_t opCode) {
     using namespace tcpip;
     /* If a connection is accepted, the corresponding socket will be assigned to the new socket */
-    SOCKET clientSocket;
-    sockaddr_in clientSockAddr;
-    int connectorSockAddrLen = 0;
+    socket_t clientSocket;
+    sockaddr clientSockAddr;
+    socklen_t connectorSockAddrLen = 0;
     int retval = 0;
 
     /* Listen for connection requests permanently for lifetime of program */
@@ -98,8 +97,7 @@ ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) {
             continue;
         }
 
-        clientSocket = accept(listenerTcpSocket, reinterpret_cast<sockaddr*>(&clientSockAddr),
-                &connectorSockAddrLen);
+        clientSocket = accept(listenerTcpSocket, &clientSockAddr, &connectorSockAddrLen);
 
         if(clientSocket == INVALID_SOCKET) {
             handleError(Protocol::TCP, ErrorSources::ACCEPT_CALL, 500);
@@ -110,7 +108,7 @@ ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) {
                 receptionBuffer.size(), 0);
         if(retval > 0) {
 #if FSFW_TCP_RCV_WIRETAPPING_ENABLED == 1
-            sif::info << "TcWinTcpServer::performOperation: Received " << retval << " bytes."
+            sif::info << "TcpTmTcServer::performOperation: Received " << retval << " bytes."
                     std::endl;
 #endif
             handleError(Protocol::TCP, ErrorSources::RECV_CALL, 500);
@@ -123,7 +121,7 @@ ReturnValue_t TcWinTcpServer::performOperation(uint8_t opCode) {
         }
 
         /* Done, shut down connection */
-        retval = shutdown(clientSocket, SD_SEND);
+        retval = shutdown(clientSocket, SHUT_SEND);
     }
     return HasReturnvaluesIF::RETURN_OK;
 }
diff --git a/osal/windows/TcWinTcpServer.h b/osal/common/TcpTmTcServer.h
similarity index 79%
rename from osal/windows/TcWinTcpServer.h
rename to osal/common/TcpTmTcServer.h
index bd9f3576..4dcc77a2 100644
--- a/osal/windows/TcWinTcpServer.h
+++ b/osal/common/TcpTmTcServer.h
@@ -1,9 +1,14 @@
 #ifndef FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_
 #define FSFW_OSAL_WINDOWS_TCWINTCPSERVER_H_
 
+#include "TcpIpBase.h"
 #include "../../objectmanager/SystemObject.h"
 #include "../../tasks/ExecutableObjectIF.h"
 
+#ifdef __unix__
+#include <sys/socket.h>
+#endif
+
 #include <string>
 #include <vector>
 
@@ -15,17 +20,18 @@
  * @details
  * Based on: https://docs.microsoft.com/en-us/windows/win32/winsock/complete-server-code
  */
-class TcWinTcpServer:
+class TcpTmTcServer:
         public SystemObject,
+        public TcpIpBase,
         public ExecutableObjectIF {
 public:
     /* The ports chosen here should not be used by any other process. */
     static const std::string DEFAULT_TCP_SERVER_PORT;
     static const std::string DEFAULT_TCP_CLIENT_PORT;
 
-    TcWinTcpServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
+    TcpTmTcServer(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
             std::string customTcpServerPort = "");
-    virtual~ TcWinTcpServer();
+    virtual~ TcpTmTcServer();
 
     ReturnValue_t initialize() override;
     ReturnValue_t performOperation(uint8_t opCode) override;
@@ -33,8 +39,8 @@ public:
 private:
 
     std::string tcpPort;
-    SOCKET listenerTcpSocket = 0;
-    struct sockaddr_in tcpAddress;
+    socket_t listenerTcpSocket = 0;
+    struct sockaddr tcpAddress;
     int tcpAddrLen = sizeof(tcpAddress);
     int currentBacklog = 3;
 
diff --git a/osal/common/UdpTcPollingTask.cpp b/osal/common/UdpTcPollingTask.cpp
new file mode 100644
index 00000000..759cee05
--- /dev/null
+++ b/osal/common/UdpTcPollingTask.cpp
@@ -0,0 +1,177 @@
+#include "UdpTcPollingTask.h"
+#include "tcpipHelpers.h"
+#include "../../globalfunctions/arrayprinter.h"
+#include "../../serviceinterface/ServiceInterfaceStream.h"
+
+#ifdef _WIN32
+
+#include <winsock2.h>
+
+#else
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#endif
+
+//! Debugging preprocessor define.
+#define FSFW_UDP_RCV_WIRETAPPING_ENABLED    0
+
+UdpTcPollingTask::UdpTcPollingTask(object_id_t objectId,
+        object_id_t tmtcUnixUdpBridge, size_t maxRecvSize,
+        double timeoutSeconds): SystemObject(objectId),
+        tmtcBridgeId(tmtcUnixUdpBridge) {
+    if(frameSize > 0) {
+        this->frameSize = frameSize;
+    }
+    else {
+        this->frameSize = DEFAULT_MAX_RECV_SIZE;
+    }
+
+    /* Set up reception buffer with specified frame size.
+	For now, it is assumed that only one frame is held in the buffer! */
+    receptionBuffer.reserve(this->frameSize);
+    receptionBuffer.resize(this->frameSize);
+
+    if(timeoutSeconds == -1) {
+        receptionTimeout = DEFAULT_TIMEOUT;
+    }
+    else {
+        receptionTimeout = timevalOperations::toTimeval(timeoutSeconds);
+    }
+}
+
+UdpTcPollingTask::~UdpTcPollingTask() {}
+
+ReturnValue_t UdpTcPollingTask::performOperation(uint8_t opCode) {
+    /* Sender Address is cached here. */
+    struct sockaddr senderAddress;
+    socklen_t senderAddressSize = sizeof(senderAddress);
+
+    /* Poll for new UDP datagrams in permanent loop. */
+    while(true) {
+        int bytesReceived = recvfrom(
+                this->serverSocket,
+                reinterpret_cast<char*>(receptionBuffer.data()),
+                frameSize,
+                receptionFlags,
+                &senderAddress,
+                &senderAddressSize
+        );
+        if(bytesReceived == SOCKET_ERROR) {
+            /* Handle error */
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+            sif::error << "UdpTcPollingTask::performOperation: Reception error." << std::endl;
+#endif
+            tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000);
+            continue;
+        }
+#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
+        sif::debug << "UdpTcPollingTask::performOperation: " << bytesReceived <<
+                " bytes received" << std::endl;
+#endif
+
+        ReturnValue_t result = handleSuccessfullTcRead(bytesReceived);
+        if(result != HasReturnvaluesIF::RETURN_FAILED) {
+
+        }
+        tmtcBridge->checkAndSetClientAddress(senderAddress);
+    }
+    return HasReturnvaluesIF::RETURN_OK;
+}
+
+
+ReturnValue_t UdpTcPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
+    store_address_t storeId;
+
+#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
+    arrayprinter::print(receptionBuffer.data(), bytesRead);
+#endif
+
+    ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead);
+    if (result != HasReturnvaluesIF::RETURN_OK) {
+#if FSFW_VERBOSE_LEVEL >= 1
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::warning<< "UdpTcPollingTask::transferPusToSoftwareBus: Data storage failed." <<
+                std::endl;
+        sif::warning << "Packet size: " << bytesRead << std::endl;
+#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
+#endif /* FSFW_VERBOSE_LEVEL >= 1 */
+        return HasReturnvaluesIF::RETURN_FAILED;
+    }
+
+    TmTcMessage message(storeId);
+
+    result  = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
+    if (result != HasReturnvaluesIF::RETURN_OK) {
+#if FSFW_VERBOSE_LEVEL >= 1
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::warning << "UdpTcPollingTask::handleSuccessfullTcRead: "
+                " Sending message to queue failed" << std::endl;
+#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
+#endif /* FSFW_VERBOSE_LEVEL >= 1 */
+        tcStore->deleteData(storeId);
+    }
+    return result;
+}
+
+ReturnValue_t UdpTcPollingTask::initialize() {
+    tcStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
+    if (tcStore == nullptr) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::error << "UdpTcPollingTask::initialize: TC store uninitialized!" << std::endl;
+#endif
+        return ObjectManagerIF::CHILD_INIT_FAILED;
+    }
+
+    tmtcBridge = objectManager->get<UdpTmTcBridge>(tmtcBridgeId);
+    if(tmtcBridge == nullptr) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::error << "UdpTcPollingTask::initialize: Invalid TMTC bridge object!" <<
+                std::endl;
+#endif
+        return ObjectManagerIF::CHILD_INIT_FAILED;
+    }
+
+    ReturnValue_t result = TcpIpBase::initialize();
+    if(result != HasReturnvaluesIF::RETURN_OK) {
+        return result;
+    }
+
+    return HasReturnvaluesIF::RETURN_OK;
+}
+
+ReturnValue_t UdpTcPollingTask::initializeAfterTaskCreation() {
+    /* Initialize the destination after task creation. This ensures
+	that the destination has already been set in the TMTC bridge. */
+    targetTcDestination = tmtcBridge->getRequestQueue();
+    /* The server socket is set up in the bridge intialization. Calling this function here
+	ensures that it is set up regardless of which class was initialized first */
+    this->serverSocket = tmtcBridge->serverSocket;
+    return HasReturnvaluesIF::RETURN_OK;
+}
+
+void UdpTcPollingTask::setTimeout(double timeoutSeconds) {
+#ifdef _WIN32
+    DWORD timeoutMs = timeoutSeconds * 1000.0;
+    int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO,
+            reinterpret_cast<const char*>(&timeoutMs), sizeof(DWORD));
+    if(result == -1) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::error << "TcWinUdpPollingTask::TcSocketPollingTask: Setting "
+                "receive timeout failed with " << strerror(errno) << std::endl;
+#endif
+    }
+#elif defined(__unix__)
+    timeval tval;
+    tval = timevalOperations::toTimeval(timeoutSeconds);
+    int result = setsockopt(serverSocket, SOL_SOCKET, SO_RCVTIMEO,
+            &tval, sizeof(receptionTimeout));
+    if(result == -1) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting "
+                "receive timeout failed with " << strerror(errno) << std::endl;
+#endif
+    }
+#endif
+}
diff --git a/osal/windows/TcWinUdpPollingTask.h b/osal/common/UdpTcPollingTask.h
similarity index 62%
rename from osal/windows/TcWinUdpPollingTask.h
rename to osal/common/UdpTcPollingTask.h
index 35e3a701..052eced5 100644
--- a/osal/windows/TcWinUdpPollingTask.h
+++ b/osal/common/UdpTcPollingTask.h
@@ -1,7 +1,7 @@
 #ifndef FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_
 #define FSFW_OSAL_WINDOWS_TCSOCKETPOLLINGTASK_H_
 
-#include "TmTcWinUdpBridge.h"
+#include "UdpTmTcBridge.h"
 #include "../../objectmanager/SystemObject.h"
 #include "../../tasks/ExecutableObjectIF.h"
 #include "../../storagemanager/StorageManagerIF.h"
@@ -9,25 +9,22 @@
 #include <vector>
 
 /**
- * @brief 	This class can be used to implement the polling of a Unix socket,
- * 			using UDP for now.
- * @details
- * The task will be blocked while the specified number of bytes has not been
- * received, so TC reception is handled inside a separate task.
- * This class caches the IP address of the sender. It is assumed there
- * is only one sender for now.
+ * @brief   This class should be used with the UdpTmTcBridge to implement a UDP server
+ *          for receiving and sending PUS TMTC.
  */
-class TcWinUdpPollingTask: public SystemObject,
+class UdpTcPollingTask:
+        public TcpIpBase,
+        public SystemObject,
 		public ExecutableObjectIF {
 	friend class TmTcWinUdpBridge;
 public:
-	static constexpr size_t DEFAULT_MAX_FRAME_SIZE = 2048;
+	static constexpr size_t DEFAULT_MAX_RECV_SIZE = 1500;
 	//! 0.5  default milliseconds timeout for now.
 	static constexpr timeval DEFAULT_TIMEOUT = {0, 500};
 
-	TcWinUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
-			size_t frameSize = 0, double timeoutSeconds = -1);
-	virtual~ TcWinUdpPollingTask();
+	UdpTcPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
+			size_t maxRecvSize = 0, double timeoutSeconds = -1);
+	virtual~ UdpTcPollingTask();
 
 	/**
 	 * Turn on optional timeout for UDP polling. In the default mode,
@@ -46,16 +43,12 @@ protected:
 private:
 	//! TMTC bridge is cached.
 	object_id_t tmtcBridgeId = objects::NO_OBJECT;
-	TmTcWinUdpBridge* tmtcBridge = nullptr;
+	UdpTmTcBridge* tmtcBridge = nullptr;
 	MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;
 
 	//! See: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom
 	int receptionFlags = 0;
 
-	//! Server socket, which is member of TMTC bridge.
-	//! Will be cached shortly after SW intialization.
-	SOCKET serverUdpSocket = 0;
-
 	std::vector<uint8_t> receptionBuffer;
 
 	size_t frameSize = 0;
diff --git a/osal/windows/TmTcWinUdpBridge.cpp b/osal/common/UdpTmTcBridge.cpp
similarity index 73%
rename from osal/windows/TmTcWinUdpBridge.cpp
rename to osal/common/UdpTmTcBridge.cpp
index 8755c84a..7f3dc929 100644
--- a/osal/windows/TmTcWinUdpBridge.cpp
+++ b/osal/common/UdpTmTcBridge.cpp
@@ -1,16 +1,26 @@
-#include "TmTcWinUdpBridge.h"
 #include "tcpipHelpers.h"
 
 #include <fsfw/serviceinterface/ServiceInterface.h>
 #include <fsfw/ipc/MutexGuard.h>
+#include <fsfw/osal/common/UdpTmTcBridge.h>
+
+#ifdef _WIN32
+
 #include <ws2tcpip.h>
 
+#elif defined(__unix__)
+
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#endif
+
 //! Debugging preprocessor define.
 #define FSFW_UDP_SEND_WIRETAPPING_ENABLED    0
 
-const std::string TmTcWinUdpBridge::DEFAULT_UDP_SERVER_PORT =  tcpip::DEFAULT_UDP_SERVER_PORT;
+const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT =  tcpip::DEFAULT_SERVER_PORT;
 
-TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination,
+UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
         object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort):
         TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
     if(udpServerPort == "") {
@@ -24,16 +34,18 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestinati
     communicationLinkUp = false;
 }
 
-ReturnValue_t TmTcWinUdpBridge::initialize() {
+ReturnValue_t UdpTmTcBridge::initialize() {
     ReturnValue_t result = TmTcBridge::initialize();
     if(result != HasReturnvaluesIF::RETURN_OK) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "TmTcWinUdpBridge::initialize: TmTcBridge initialization failed!"
+        sif::error << "TmTcUdpBridge::initialize: TmTcBridge initialization failed!"
                 << std::endl;
 #endif
         return result;
     }
 
+
+#ifdef _WIN32
     /* Initiates Winsock DLL. */
     WSAData wsaData;
     WORD wVersionRequested = MAKEWORD(2, 2);
@@ -42,26 +54,22 @@ ReturnValue_t TmTcWinUdpBridge::initialize() {
         /* Tell the user that we could not find a usable */
         /* Winsock DLL.                                  */
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: " <<
+        sif::error << "TmTcUdpBridge::TmTcUdpBridge: WSAStartup failed with error: " <<
                 err << std::endl;
 #else
-        sif::printError("TmTcWinUdpBridge::TmTcWinUdpBridge: WSAStartup failed with error: %d\n",
+        sif::printError("TmTcUdpBridge::TmTcUdpBridge: WSAStartup failed with error: %d\n",
                 err);
 #endif
         return HasReturnvaluesIF::RETURN_FAILED;
     }
+#endif
 
     struct addrinfo *addrResult = nullptr;
-    struct addrinfo hints;
+    struct addrinfo hints = {};
 
-    ZeroMemory(&hints, sizeof (hints));
     hints.ai_family = AF_INET;
     hints.ai_socktype = SOCK_DGRAM;
     hints.ai_protocol = IPPROTO_UDP;
-    /* See:
-    https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo
-    for information about AI_PASSIVE. */
-    hints.ai_flags = AI_PASSIVE;
 
     /* Set up UDP socket:
     https://en.wikipedia.org/wiki/Getaddrinfo
@@ -70,7 +78,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() {
     int retval = getaddrinfo(nullptr, udpServerPort.c_str(), &hints, &addrResult);
     if (retval != 0) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Retrieving address info failed!" <<
+        sif::warning << "TmTcUdpBridge::TmTcUdpBridge: Retrieving address info failed!" <<
                 std::endl;
 #endif
         return HasReturnvaluesIF::RETURN_FAILED;
@@ -79,7 +87,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() {
     serverSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol);
     if(serverSocket == INVALID_SOCKET) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not open UDP socket!" <<
+        sif::warning << "TmTcUdpBridge::TmTcUdpBridge: Could not open UDP socket!" <<
                 std::endl;
 #endif
         freeaddrinfo(addrResult);
@@ -90,7 +98,7 @@ ReturnValue_t TmTcWinUdpBridge::initialize() {
     retval = bind(serverSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
     if(retval != 0) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind "
+        sif::error << "TmTcUdpBridge::TmTcUdpBridge: Could not bind "
                 "local port (" << udpServerPort << ") to server socket!" << std::endl;
 #endif
         freeaddrinfo(addrResult);
@@ -100,15 +108,13 @@ ReturnValue_t TmTcWinUdpBridge::initialize() {
     return HasReturnvaluesIF::RETURN_OK;
 }
 
-TmTcWinUdpBridge::~TmTcWinUdpBridge() {
+UdpTmTcBridge::~UdpTmTcBridge() {
     if(mutex != nullptr) {
         MutexFactory::instance()->deleteMutex(mutex);
     }
-    closesocket(serverSocket);
-    WSACleanup();
 }
 
-ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
+ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
     int flags = 0;
 
     /* The target address can be set by different threads so this lock ensures thread-safety */
@@ -125,23 +131,23 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
             reinterpret_cast<const char*>(data),
             dataLen,
             flags,
-            reinterpret_cast<sockaddr*>(&clientAddress),
+            &clientAddress,
             clientAddressLen
     );
     if(bytesSent == SOCKET_ERROR) {
 #if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TmTcWinUdpBridge::sendTm: Send operation failed." << std::endl;
+        sif::warning << "TmTcUdpBridge::sendTm: Send operation failed." << std::endl;
 #endif
         tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
     }
 #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
-    sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were"
+    sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent << " bytes were"
             " sent." << std::endl;
 #endif
     return HasReturnvaluesIF::RETURN_OK;
 }
 
-void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) {
+void UdpTmTcBridge::checkAndSetClientAddress(sockaddr& newAddress) {
     /* The target address can be set by different threads so this lock ensures thread-safety */
     MutexGuard lock(mutex, timeoutType, mutexTimeoutMs);
 
@@ -159,7 +165,7 @@ void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) {
     clientAddressLen = sizeof(clientAddress);
 }
 
-void TmTcWinUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType,
+void UdpTmTcBridge::setMutexProperties(MutexIF::TimeoutType timeoutType,
         dur_millis_t timeoutMs) {
     this->timeoutType = timeoutType;
     this->mutexTimeoutMs = timeoutMs;
diff --git a/osal/windows/TmTcWinUdpBridge.h b/osal/common/UdpTmTcBridge.h
similarity index 61%
rename from osal/windows/TmTcWinUdpBridge.h
rename to osal/common/UdpTmTcBridge.h
index c2f7d6aa..8b8d1949 100644
--- a/osal/windows/TmTcWinUdpBridge.h
+++ b/osal/common/UdpTmTcBridge.h
@@ -1,20 +1,36 @@
 #ifndef FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_
 #define FSFW_OSAL_WINDOWS_TMTCWINUDPBRIDGE_H_
 
+#include "TcpIpBase.h"
 #include "../../tmtcservices/TmTcBridge.h"
 
-#include <string>
-#include <winsock2.h>
+#ifdef _WIN32
 
-class TmTcWinUdpBridge: public TmTcBridge {
-    friend class TcWinUdpPollingTask;
+#include <ws2tcpip.h>
+
+#elif defined(__unix__)
+
+#include <sys/socket.h>
+
+#endif
+
+#include <string>
+
+/**
+ * @brief   This class should be used with the UdpTcPollingTask to implement a UDP server
+ *          for receiving and sending PUS TMTC.
+ */
+class UdpTmTcBridge:
+        public TmTcBridge,
+        public TcpIpBase {
+    friend class UdpTcPollingTask;
 public:
     /* The ports chosen here should not be used by any other process. */
     static const std::string DEFAULT_UDP_SERVER_PORT;
 
-    TmTcWinUdpBridge(object_id_t objectId, object_id_t tcDestination,
+    UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
             object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort = "");
-    virtual~ TmTcWinUdpBridge();
+    virtual~ UdpTmTcBridge();
 
     /**
      * Set properties of internal mutex.
@@ -23,17 +39,16 @@ public:
 
     ReturnValue_t initialize() override;
 
-    void checkAndSetClientAddress(sockaddr_in& clientAddress);
+    void checkAndSetClientAddress(sockaddr& clientAddress);
 
 protected:
     virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
 
 private:
-    SOCKET serverSocket = 0;
     std::string udpServerPort;
 
-    struct sockaddr_in clientAddress;
-    int clientAddressLen = 0;
+    struct sockaddr clientAddress;
+    socklen_t clientAddressLen = 0;
 
     //! Access to the client address is mutex protected as it is set by another task.
     MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
diff --git a/osal/common/tcpipCommon.h b/osal/common/tcpipCommon.h
index 9b38c9fb..dc5ada52 100644
--- a/osal/common/tcpipCommon.h
+++ b/osal/common/tcpipCommon.h
@@ -6,8 +6,7 @@
 
 namespace tcpip {
 
-const char* const DEFAULT_UDP_SERVER_PORT = "7301";
-const char* const DEFAULT_TCP_SERVER_PORT = "7303";
+const char* const DEFAULT_SERVER_PORT = "7301";
 
 enum class Protocol {
     UDP,
diff --git a/osal/windows/tcpipHelpers.h b/osal/common/tcpipHelpers.h
similarity index 89%
rename from osal/windows/tcpipHelpers.h
rename to osal/common/tcpipHelpers.h
index 01f009b9..9764a93f 100644
--- a/osal/windows/tcpipHelpers.h
+++ b/osal/common/tcpipHelpers.h
@@ -2,7 +2,7 @@
 #define FSFW_OSAL_WINDOWS_TCPIPHELPERS_H_
 
 #include "../../timemanager/clockDefinitions.h"
-#include "../common/tcpipCommon.h"
+#include "tcpipCommon.h"
 
 namespace tcpip {
 
diff --git a/osal/host/CMakeLists.txt b/osal/host/CMakeLists.txt
index 367f721e..2d29ce5d 100644
--- a/osal/host/CMakeLists.txt
+++ b/osal/host/CMakeLists.txt
@@ -10,6 +10,7 @@ target_sources(${LIB_FSFW_NAME}
 		QueueMapManager.cpp
 		SemaphoreFactory.cpp
 		TaskFactory.cpp
+		taskHelpers.cpp
 )
 
 if(UNIX)
diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp
index 272d99b9..3b169b5a 100644
--- a/osal/host/FixedTimeslotTask.cpp
+++ b/osal/host/FixedTimeslotTask.cpp
@@ -1,9 +1,8 @@
+#include "taskHelpers.h"
 #include "../../osal/host/FixedTimeslotTask.h"
-
 #include "../../ipc/MutexFactory.h"
 #include "../../osal/host/Mutex.h"
 #include "../../osal/host/FixedTimeslotTask.h"
-
 #include "../../serviceinterface/ServiceInterfaceStream.h"
 #include "../../tasks/ExecutableObjectIF.h"
 
@@ -12,6 +11,7 @@
 
 #if defined(WIN32)
 #include <windows.h>
+#include "../windows/winTaskHelpers.h"
 #elif defined(LINUX)
 #include <pthread.h>
 #endif
@@ -24,34 +24,12 @@ FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority,
     // It is propably possible to set task priorities by using the native
     // task handles for Windows / Linux
     mainThread = std::thread(&FixedTimeslotTask::taskEntryPoint, this, this);
-#if defined(WIN32)
-    /* List of possible priority classes:
-     * https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/
-     * nf-processthreadsapi-setpriorityclass
-     * And respective thread priority numbers:
-     * https://docs.microsoft.com/en-us/windows/
-     * win32/procthread/scheduling-priorities */
-    int result = SetPriorityClass(
-            reinterpret_cast<HANDLE>(mainThread.native_handle()),
-            ABOVE_NORMAL_PRIORITY_CLASS);
-    if(result != 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
-                << GetLastError() << std::endl;
-#endif
-    }
-    result = SetThreadPriority(
-            reinterpret_cast<HANDLE>(mainThread.native_handle()),
-            THREAD_PRIORITY_NORMAL);
-    if(result != 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code "
-                << GetLastError() << std::endl;
-#endif
-    }
-#elif defined(LINUX)
-    // TODO: we can just copy and paste the code from the linux OSAL here.
+#if defined(_WIN32)
+    tasks::setTaskPriority(reinterpret_cast<HANDLE>(mainThread.native_handle()), setPriority);
+#elif defined(__unix__)
+    // TODO: We could reuse existing code here.
 #endif
+    tasks::insertTaskName(mainThread.get_id(), taskName);
 }
 
 FixedTimeslotTask::~FixedTimeslotTask(void) {
diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp
index fe7b8c08..18272a68 100644
--- a/osal/host/MessageQueue.cpp
+++ b/osal/host/MessageQueue.cpp
@@ -63,8 +63,6 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) {
 	if(messageQueue.empty()) {
 		return MessageQueueIF::EMPTY;
 	}
-	// not sure this will work..
-	//*message = std::move(messageQueue.front());
 	MutexGuard mutexLock(queueLock, MutexIF::TimeoutType::WAITING, 20);
 	MessageQueueMessage* currentMessage = &messageQueue.front();
 	std::copy(currentMessage->getBuffer(),
diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp
index 7663d522..d7abf9d0 100644
--- a/osal/host/PeriodicTask.cpp
+++ b/osal/host/PeriodicTask.cpp
@@ -1,5 +1,6 @@
 #include "Mutex.h"
 #include "PeriodicTask.h"
+#include "taskHelpers.h"
 
 #include "../../ipc/MutexFactory.h"
 #include "../../serviceinterface/ServiceInterfaceStream.h"
@@ -10,7 +11,8 @@
 
 #if defined(WIN32)
 #include <processthreadsapi.h>
-#elif defined(LINUX)
+#include <fsfw/osal/windows/winTaskHelpers.h>
+#elif defined(__unix__)
 #include <pthread.h>
 #endif
 
@@ -22,34 +24,12 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority,
     // It is propably possible to set task priorities by using the native
     // task handles for Windows / Linux
 	mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this);
-#if defined(WIN32)
-    /* List of possible priority classes:
-     * https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/
-     * nf-processthreadsapi-setpriorityclass
-     * And respective thread priority numbers:
-     * https://docs.microsoft.com/en-us/windows/
-     * win32/procthread/scheduling-priorities */
-    int result = SetPriorityClass(
-            reinterpret_cast<HANDLE>(mainThread.native_handle()),
-            ABOVE_NORMAL_PRIORITY_CLASS);
-    if(result != 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
-                << GetLastError() << std::endl;
-#endif
-    }
-    result = SetThreadPriority(
-            reinterpret_cast<HANDLE>(mainThread.native_handle()),
-            THREAD_PRIORITY_NORMAL);
-    if(result != 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
-                << GetLastError() << std::endl;
-#endif
-    }
-#elif defined(LINUX)
-    // we can just copy and paste the code from linux here.
+#if defined(_WIN32)
+	tasks::setTaskPriority(reinterpret_cast<HANDLE>(mainThread.native_handle()), setPriority);
+#elif defined(__unix__)
+    // TODO: We could reuse existing code here.
 #endif
+    tasks::insertTaskName(mainThread.get_id(), taskName);
 }
 
 PeriodicTask::~PeriodicTask(void) {
diff --git a/osal/host/TaskFactory.cpp b/osal/host/TaskFactory.cpp
index 4fafd349..71d0bf8b 100644
--- a/osal/host/TaskFactory.cpp
+++ b/osal/host/TaskFactory.cpp
@@ -1,14 +1,16 @@
+#include "taskHelpers.h"
+#include "../../tasks/TaskFactory.h"
 #include "../../osal/host/FixedTimeslotTask.h"
 #include "../../osal/host/PeriodicTask.h"
-#include "../../tasks/TaskFactory.h"
 #include "../../returnvalues/HasReturnvaluesIF.h"
 #include "../../tasks/PeriodicTaskIF.h"
+#include "../../serviceinterface/ServiceInterface.h"
 
 #include <chrono>
 
 TaskFactory* TaskFactory::factoryInstance = new TaskFactory();
 
-// Will propably not be used for hosted implementation
+// Not used for the host implementation for now because C++ thread abstraction is used
 const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = 0;
 
 TaskFactory::TaskFactory() {
@@ -49,8 +51,12 @@ ReturnValue_t TaskFactory::delayTask(uint32_t delayMs){
 }
 
 void TaskFactory::printMissedDeadline() {
-    /* TODO: Implement */
-    return;
+    std::string name = tasks::getTaskName(std::this_thread::get_id());
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+    sif::warning << "TaskFactory::printMissedDeadline: " << name << std::endl;
+#else
+    sif::printWarning("TaskFactory::printMissedDeadline: %s\n", name);
+#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
 }
 
 
diff --git a/osal/host/taskHelpers.cpp b/osal/host/taskHelpers.cpp
new file mode 100644
index 00000000..be4c29ad
--- /dev/null
+++ b/osal/host/taskHelpers.cpp
@@ -0,0 +1,27 @@
+#include "taskHelpers.h"
+#include <map>
+#include <mutex>
+
+std::mutex nameMapLock;
+std::map<std::thread::id, std::string> taskNameMap;
+
+ReturnValue_t tasks::insertTaskName(std::thread::id threadId, std::string taskName) {
+    std::lock_guard<std::mutex> lg(nameMapLock);
+    auto returnPair = taskNameMap.emplace(threadId, taskName);
+    if(not returnPair.second) {
+        return HasReturnvaluesIF::RETURN_FAILED;
+    }
+    return HasReturnvaluesIF::RETURN_OK;
+}
+
+std::string tasks::getTaskName(std::thread::id threadId) {
+    std::lock_guard<std::mutex> lg(nameMapLock);
+    auto resultIter = taskNameMap.find(threadId);
+    if(resultIter != taskNameMap.end()) {
+        return resultIter->second;
+    }
+    else {
+        return "Unknown task";
+    }
+}
+
diff --git a/osal/host/taskHelpers.h b/osal/host/taskHelpers.h
new file mode 100644
index 00000000..fa00490f
--- /dev/null
+++ b/osal/host/taskHelpers.h
@@ -0,0 +1,16 @@
+#ifndef FSFW_OSAL_HOST_TASKHELPERS_H_
+#define FSFW_OSAL_HOST_TASKHELPERS_H_
+
+#include <fsfw/returnvalues/HasReturnvaluesIF.h>
+#include <thread>
+
+namespace tasks {
+
+ReturnValue_t insertTaskName(std::thread::id threadId, std::string taskName);
+std::string getTaskName(std::thread::id threadId);
+
+}
+
+
+
+#endif /* FSFW_OSAL_HOST_TASKHELPERS_H_ */
diff --git a/osal/linux/CMakeLists.txt b/osal/linux/CMakeLists.txt
index 6c377844..332fe2f4 100644
--- a/osal/linux/CMakeLists.txt
+++ b/osal/linux/CMakeLists.txt
@@ -13,8 +13,6 @@ target_sources(${LIB_FSFW_NAME}
 		QueueFactory.cpp
 		SemaphoreFactory.cpp
 		TaskFactory.cpp
-		TcUnixUdpPollingTask.cpp
-		TmTcUnixUdpBridge.cpp
 		Timer.cpp
 		tcpipHelpers.cpp
 )
diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp
index bd8e7258..5296dfb5 100644
--- a/osal/linux/PosixThread.cpp
+++ b/osal/linux/PosixThread.cpp
@@ -6,7 +6,7 @@
 #include <errno.h>
 
 PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
-		thread(0),priority(priority_),stackSize(stackSize_) {
+		thread(0), priority(priority_), stackSize(stackSize_) {
     name[0] = '\0';
     std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
 }
@@ -75,18 +75,18 @@ bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
 
 	if (currentTime_ms < *prevoiusWakeTime_ms) {
 		/* The tick count has overflowed since this function was
-		 lasted called.  In this case the only time we should ever
-		 actually delay is if the wake time has also	overflowed,
-		 and the wake time is greater than the tick time.  When this
-		 is the case it is as if neither time had overflowed. */
+		lasted called.  In this case the only time we should ever
+		actually delay is if the wake time has also overflowed,
+		and the wake time is greater than the tick time. When this
+		is the case it is as if neither time had overflowed. */
 		if ((nextTimeToWake_ms < *prevoiusWakeTime_ms)
 				&& (nextTimeToWake_ms > currentTime_ms)) {
 			shouldDelay = true;
 		}
 	} else {
-		/* The tick time has not overflowed.  In this case we will
-		 delay if either the wake time has overflowed, and/or the
-		 tick time is less than the wake time. */
+		/* The tick time has not overflowed. In this case we will
+		delay if either the wake time has overflowed, and/or the
+		tick time is less than the wake time. */
 		if ((nextTimeToWake_ms < *prevoiusWakeTime_ms)
 				|| (nextTimeToWake_ms > currentTime_ms)) {
 			shouldDelay = true;
diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp
deleted file mode 100644
index 37dadb76..00000000
--- a/osal/linux/TcUnixUdpPollingTask.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include "TcUnixUdpPollingTask.h"
-#include "tcpipHelpers.h"
-
-#include "../../globalfunctions/arrayprinter.h"
-
-#define FSFW_UDP_RCV_WIRETAPPING_ENABLED    0
-
-TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId,
-		object_id_t tmtcUnixUdpBridge, size_t frameSize,
-		double timeoutSeconds): SystemObject(objectId),
-		tmtcBridgeId(tmtcUnixUdpBridge) {
-
-	if(frameSize > 0) {
-		this->frameSize = frameSize;
-	}
-	else {
-		this->frameSize = DEFAULT_MAX_FRAME_SIZE;
-	}
-
-	/* Set up reception buffer with specified frame size.
-	For now, it is assumed that only one frame is held in the buffer! */
-	receptionBuffer.reserve(this->frameSize);
-	receptionBuffer.resize(this->frameSize);
-
-	if(timeoutSeconds == -1) {
-		receptionTimeout = DEFAULT_TIMEOUT;
-	}
-	else {
-		receptionTimeout = timevalOperations::toTimeval(timeoutSeconds);
-	}
-}
-
-TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {}
-
-ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) {
-    /* Sender Address is cached here. */
-    struct sockaddr_in senderAddress;
-    socklen_t senderAddressSize = sizeof(senderAddress);
-
-	/* Poll for new UDP datagrams in permanent loop. */
-	while(true) {
-		ssize_t bytesReceived = recvfrom(
-		        serverUdpSocket,
-				receptionBuffer.data(),
-				frameSize,
-				receptionFlags,
-				reinterpret_cast<sockaddr*>(&senderAddress),
-				&senderAddressSize
-		);
-		if(bytesReceived < 0) {
-			/* Handle error */
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-			sif::error << "TcSocketPollingTask::performOperation: Reception error." << std::endl;
-#endif
-			tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 500);
-			continue;
-		}
-#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
-		sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived
-		        << " bytes received" << std::endl;
-#endif
-
-		ReturnValue_t result = handleSuccessfullTcRead(bytesReceived);
-		if(result != HasReturnvaluesIF::RETURN_FAILED) {
-
-		}
-		tmtcBridge->checkAndSetClientAddress(senderAddress);
-	}
-	return HasReturnvaluesIF::RETURN_OK;
-}
-
-
-ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
-	store_address_t storeId;
-
-#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
-    arrayprinter::print(receptionBuffer.data(), bytesRead);
-#endif
-
-    ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead);
-	if (result != HasReturnvaluesIF::RETURN_OK) {
-#if FSFW_VERBOSE_LEVEL >= 1
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Data "
-				"storage failed" << std::endl;
-		sif::error << "Packet size: " << bytesRead << std::endl;
-#else
-#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
-#endif /* FSFW_VERBOSE_LEVEL >= 1 */
-		return HasReturnvaluesIF::RETURN_FAILED;
-	}
-
-	TmTcMessage message(storeId);
-
-	result  = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
-	if (result != HasReturnvaluesIF::RETURN_OK) {
-#if FSFW_VERBOSE_LEVEL >= 1
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcUnixUdpPollingTask::handleSuccessfullTcRead: Sending message to queue "
-		        "failed" << std::endl;
-#else
-#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
-#endif /* FSFW_VERBOSE_LEVEL >= 1 */
-		tcStore->deleteData(storeId);
-	}
-	return result;
-}
-
-ReturnValue_t TcUnixUdpPollingTask::initialize() {
-	tcStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
-	if (tcStore == nullptr) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcSerialPollingTask::initialize: TC Store uninitialized!"
-				<< std::endl;
-#endif
-		return ObjectManagerIF::CHILD_INIT_FAILED;
-	}
-
-	tmtcBridge = objectManager->get<TmTcUnixUdpBridge>(tmtcBridgeId);
-	if(tmtcBridge == nullptr) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid"
-				" TMTC bridge object!" << std::endl;
-#endif
-		return ObjectManagerIF::CHILD_INIT_FAILED;
-	}
-
-	return HasReturnvaluesIF::RETURN_OK;
-}
-
-ReturnValue_t TcUnixUdpPollingTask::initializeAfterTaskCreation() {
-    /* Initialize the destination after task creation. This ensures
-    that the destination has already been set in the TMTC bridge. */
-	targetTcDestination = tmtcBridge->getRequestQueue();
-    /* The server socket is set up in the bridge intialization. Calling this function here
-    ensures that it is set up properly in any case*/
-    serverUdpSocket = tmtcBridge->serverSocket;
-	return HasReturnvaluesIF::RETURN_OK;
-}
-
-void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) {
-	timeval tval;
-	tval = timevalOperations::toTimeval(timeoutSeconds);
-	int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO,
-			&tval, sizeof(receptionTimeout));
-	if(result == -1) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting "
-				"receive timeout failed with " << strerror(errno) << std::endl;
-#endif
-	}
-}
diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h
deleted file mode 100644
index 39ee0914..00000000
--- a/osal/linux/TcUnixUdpPollingTask.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_
-#define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_
-
-#include "../../objectmanager/SystemObject.h"
-#include "../../osal/linux/TmTcUnixUdpBridge.h"
-#include "../../tasks/ExecutableObjectIF.h"
-
-#include <sys/socket.h>
-#include <vector>
-
-/**
- * @brief 	This class can be used to implement the polling of a Unix socket,
- * 			using UDP for now.
- * @details
- * The task will be blocked while the specified number of bytes has not been
- * received, so TC reception is handled inside a separate task.
- * This class caches the IP address of the sender. It is assumed there
- * is only one sender for now.
- */
-class TcUnixUdpPollingTask: public SystemObject,
-		public ExecutableObjectIF {
-	friend class TmTcUnixUdpBridge;
-public:
-	static constexpr size_t DEFAULT_MAX_FRAME_SIZE = 2048;
-	//! 0.5  default milliseconds timeout for now.
-	static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500};
-
-	TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
-			size_t frameSize = 0, double timeoutSeconds = -1);
-	virtual~ TcUnixUdpPollingTask();
-
-	/**
-	 * Turn on optional timeout for UDP polling. In the default mode,
-	 * the receive function will block until a packet is received.
-	 * @param timeoutSeconds
-	 */
-	void setTimeout(double timeoutSeconds);
-
-	virtual ReturnValue_t performOperation(uint8_t opCode) override;
-	virtual ReturnValue_t initialize() override;
-	virtual ReturnValue_t initializeAfterTaskCreation() override;
-
-protected:
-	StorageManagerIF* tcStore = nullptr;
-
-private:
-	//! TMTC bridge is cached.
-	object_id_t tmtcBridgeId = objects::NO_OBJECT;
-	TmTcUnixUdpBridge* tmtcBridge = nullptr;
-	MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;
-
-	//! Reception flags: https://linux.die.net/man/2/recvfrom.
-	int receptionFlags = 0;
-
-	//! Server socket, which is member of TMTC bridge and is assigned in
-	//! constructor
-	int serverUdpSocket = 0;
-
-	std::vector<uint8_t> receptionBuffer;
-
-	size_t frameSize = 0;
-	timeval receptionTimeout;
-
-	ReturnValue_t handleSuccessfullTcRead(size_t bytesRead);
-};
-
-#endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */
diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp
deleted file mode 100644
index fa7913ea..00000000
--- a/osal/linux/TmTcUnixUdpBridge.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-#include "TmTcUnixUdpBridge.h"
-#include "tcpipHelpers.h"
-#include "../../serviceinterface/ServiceInterface.h"
-#include "../../ipc/MutexGuard.h"
-
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <netdb.h>
-
-#include <cstring>
-
-//! Debugging preprocessor define.
-#define FSFW_UDP_SEND_WIRETAPPING_ENABLED   0
-
-const std::string TmTcUnixUdpBridge::DEFAULT_UDP_SERVER_PORT =  tcpip::DEFAULT_UDP_SERVER_PORT;
-
-TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination,
-        object_id_t tmStoreId, object_id_t tcStoreId, std::string udpServerPort):
-		TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
-    if(udpServerPort == "") {
-        this->udpServerPort = DEFAULT_UDP_SERVER_PORT;
-    }
-    else {
-        this->udpServerPort = udpServerPort;
-    }
-
-    mutex = MutexFactory::instance()->createMutex();
-    communicationLinkUp = false;
-}
-
-ReturnValue_t TmTcUnixUdpBridge::initialize() {
-    using namespace tcpip;
-
-    ReturnValue_t result = TmTcBridge::initialize();
-    if(result != HasReturnvaluesIF::RETURN_OK) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "TmTcUnixUdpBridge::initialize: TmTcBridge initialization failed!"
-                << std::endl;
-#endif
-        return result;
-    }
-
-    struct addrinfo *addrResult = nullptr;
-    struct addrinfo hints;
-
-    std::memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_DGRAM;
-    hints.ai_protocol = IPPROTO_UDP;
-    hints.ai_flags = AI_PASSIVE;
-
-    /* Set up UDP socket:
-    https://man7.org/linux/man-pages/man3/getaddrinfo.3.html
-    Passing nullptr as the first parameter and specifying AI_PASSIVE in hints will cause
-    getaddrinfo to assign the address 0.0.0.0 (any address) */
-    int retval = getaddrinfo(nullptr, udpServerPort.c_str(), &hints, &addrResult);
-    if (retval != 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Retrieving address info failed!" <<
-                std::endl;
-#endif
-        return HasReturnvaluesIF::RETURN_FAILED;
-    }
-
-    /* Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html */
-    serverSocket = socket(addrResult->ai_family, addrResult->ai_socktype, addrResult->ai_protocol);
-    if(serverSocket < 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open UDP socket!" <<
-                std::endl;
-#else
-        sif::printError("TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open UDP socket!\n");
-#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
-        freeaddrinfo(addrResult);
-        handleError(Protocol::UDP, ErrorSources::SOCKET_CALL);
-        return HasReturnvaluesIF::RETURN_FAILED;
-    }
-
-    retval = bind(serverSocket, addrResult->ai_addr, static_cast<int>(addrResult->ai_addrlen));
-    if(retval != 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TmTcWinUdpBridge::TmTcWinUdpBridge: Could not bind "
-                "local port (" << udpServerPort << ") to server socket!" << std::endl;
-#endif
-        freeaddrinfo(addrResult);
-        handleError(Protocol::UDP, ErrorSources::BIND_CALL);
-        return HasReturnvaluesIF::RETURN_FAILED;
-    }
-
-    return HasReturnvaluesIF::RETURN_OK;
-}
-
-TmTcUnixUdpBridge::~TmTcUnixUdpBridge() {
-    if(mutex != nullptr) {
-        MutexFactory::instance()->deleteMutex(mutex);
-    }
-    close(serverSocket);
-}
-
-ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
-    int flags = 0;
-
-    /* The target address can be set by different threads so this lock ensures thread-safety */
-    MutexGuard lock(mutex, timeoutType, mutexTimeoutMs);
-
-    if(ipAddrAnySet){
-        clientAddress.sin_addr.s_addr = htons(INADDR_ANY);
-        clientAddressLen = sizeof(clientAddress);
-    }
-
-#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
-    char ipAddress [15];
-    sif::debug << "IP Address Sender: "<<
-            inet_ntop(AF_INET,&clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
-#endif
-
-    ssize_t bytesSent = sendto(
-            serverSocket,
-            data,
-            dataLen,
-            flags,
-            reinterpret_cast<sockaddr*>(&clientAddress),
-            clientAddressLen
-    );
-    if(bytesSent < 0) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-        sif::warning << "TmTcUnixUdpBridge::sendTm: Send operation failed." << std::endl;
-#endif
-        tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
-    }
-
-#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
-    sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were"
-            " sent." << std::endl;
-#endif
-
-    return HasReturnvaluesIF::RETURN_OK;
-}
-
-void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in& newAddress) {
-    /* The target address can be set by different threads so this lock ensures thread-safety */
-    MutexGuard lock(mutex, timeoutType, mutexTimeoutMs);
-
-#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
-    char ipAddress [15];
-    sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET,
-            &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
-    sif::debug << "IP Address Old: " <<  inet_ntop(AF_INET,
-            &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
-#endif
-    registerCommConnect();
-
-    /* Set new IP address to reply to. */
-    clientAddress = newAddress;
-    clientAddressLen = sizeof(clientAddress);
-}
-
-void TmTcUnixUdpBridge::setMutexProperties(MutexIF::TimeoutType timeoutType,
-        dur_millis_t timeoutMs) {
-    this->timeoutType = timeoutType;
-    this->mutexTimeoutMs = timeoutMs;
-}
-
-void TmTcUnixUdpBridge::setClientAddressToAny(bool ipAddrAnySet){
-    this->ipAddrAnySet = ipAddrAnySet;
-}
-
diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h
deleted file mode 100644
index 3ab2118c..00000000
--- a/osal/linux/TmTcUnixUdpBridge.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_
-#define FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_
-
-#include "../../tmtcservices/AcceptsTelecommandsIF.h"
-#include "../../tmtcservices/TmTcBridge.h"
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/udp.h>
-
-class TmTcUnixUdpBridge:
-        public TmTcBridge {
-    friend class TcUnixUdpPollingTask;
-public:
-
-    /* The ports chosen here should not be used by any other process.
-	List of used ports on Linux: /etc/services */
-    static const std::string DEFAULT_UDP_SERVER_PORT;
-
-    TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination,
-            object_id_t tmStoreId, object_id_t tcStoreId,
-            std::string serverPort = "");
-    virtual~ TmTcUnixUdpBridge();
-
-    /**
-     * Set properties of internal mutex.
-     */
-    void setMutexProperties(MutexIF::TimeoutType timeoutType, dur_millis_t timeoutMs);
-
-    ReturnValue_t initialize() override;
-
-    void checkAndSetClientAddress(sockaddr_in& clientAddress);
-
-    void setClientAddressToAny(bool ipAddrAnySet);
-
-protected:
-    virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
-
-private:
-    int serverSocket = 0;
-    std::string udpServerPort;
-
-    struct sockaddr_in clientAddress;
-    socklen_t clientAddressLen = 0;
-
-    bool ipAddrAnySet = false;
-
-    //! Access to the client address is mutex protected as it is set by another task.
-    MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
-    dur_millis_t mutexTimeoutMs = 20;
-    MutexIF* mutex;
-};
-
-#endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */
diff --git a/osal/linux/tcpipHelpers.cpp b/osal/linux/tcpipHelpers.cpp
index 1c380769..4c1b9a78 100644
--- a/osal/linux/tcpipHelpers.cpp
+++ b/osal/linux/tcpipHelpers.cpp
@@ -1,4 +1,4 @@
-#include "tcpipHelpers.h"
+#include "../common/tcpipHelpers.h"
 
 #include "../../tasks/TaskFactory.h"
 
diff --git a/osal/linux/tcpipHelpers.h b/osal/linux/tcpipHelpers.h
deleted file mode 100644
index 6b337c62..00000000
--- a/osal/linux/tcpipHelpers.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef FSFW_OSAL_LINUX_TCPIPHELPERS_H_
-#define FSFW_OSAL_LINUX_TCPIPHELPERS_H_
-
-#include "../../timemanager/clockDefinitions.h"
-#include "../common/tcpipCommon.h"
-
-namespace tcpip {
-
-
-void handleError(Protocol protocol, ErrorSources errorSrc, dur_millis_t sleepDuration = 0);
-
-}
-
-#endif /* FSFW_OSAL_LINUX_TCPIPHELPERS_H_ */
diff --git a/osal/windows/CMakeLists.txt b/osal/windows/CMakeLists.txt
index a2b31688..36a54765 100644
--- a/osal/windows/CMakeLists.txt
+++ b/osal/windows/CMakeLists.txt
@@ -1,11 +1,4 @@
 target_sources(${LIB_FSFW_NAME} PRIVATE 
-    TcWinUdpPollingTask.cpp
-    TmTcWinUdpBridge.cpp
-    TcWinTcpServer.cpp
     tcpipHelpers.cpp
+    winTaskHelpers.cpp
 )
-
-target_link_libraries(${LIB_FSFW_NAME} PRIVATE
-    wsock32 
-    ws2_32
-)
\ No newline at end of file
diff --git a/osal/windows/TcWinUdpPollingTask.cpp b/osal/windows/TcWinUdpPollingTask.cpp
deleted file mode 100644
index 980404f9..00000000
--- a/osal/windows/TcWinUdpPollingTask.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-#include "TcWinUdpPollingTask.h"
-#include "tcpipHelpers.h"
-#include "../../globalfunctions/arrayprinter.h"
-#include "../../serviceinterface/ServiceInterfaceStream.h"
-
-#include <winsock2.h>
-
-//! Debugging preprocessor define.
-#define FSFW_UDP_RCV_WIRETAPPING_ENABLED    0
-
-TcWinUdpPollingTask::TcWinUdpPollingTask(object_id_t objectId,
-		object_id_t tmtcUnixUdpBridge, size_t frameSize,
-		double timeoutSeconds): SystemObject(objectId),
-		tmtcBridgeId(tmtcUnixUdpBridge) {
-	if(frameSize > 0) {
-		this->frameSize = frameSize;
-	}
-	else {
-		this->frameSize = DEFAULT_MAX_FRAME_SIZE;
-	}
-
-	/* Set up reception buffer with specified frame size.
-	For now, it is assumed that only one frame is held in the buffer! */
-	receptionBuffer.reserve(this->frameSize);
-	receptionBuffer.resize(this->frameSize);
-
-	if(timeoutSeconds == -1) {
-		receptionTimeout = DEFAULT_TIMEOUT;
-	}
-	else {
-		receptionTimeout = timevalOperations::toTimeval(timeoutSeconds);
-	}
-}
-
-TcWinUdpPollingTask::~TcWinUdpPollingTask() {}
-
-ReturnValue_t TcWinUdpPollingTask::performOperation(uint8_t opCode) {
-    /* Sender Address is cached here. */
-    struct sockaddr_in senderAddress;
-    int senderAddressSize = sizeof(senderAddress);
-
-	/* Poll for new UDP datagrams in permanent loop. */
-	while(true) {
-		int bytesReceived = recvfrom(
-		        serverUdpSocket,
-		        reinterpret_cast<char*>(receptionBuffer.data()),
-		        frameSize,
-				receptionFlags,
-				reinterpret_cast<sockaddr*>(&senderAddress),
-				&senderAddressSize
-		);
-		if(bytesReceived == SOCKET_ERROR) {
-			/* Handle error */
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-			sif::error << "TcWinUdpPollingTask::performOperation: Reception error." << std::endl;
-#endif
-			tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::RECVFROM_CALL, 1000);
-			continue;
-		}
-#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
-		sif::debug << "TcWinUdpPollingTask::performOperation: " << bytesReceived <<
-		        " bytes received" << std::endl;
-#endif
-
-		ReturnValue_t result = handleSuccessfullTcRead(bytesReceived);
-		if(result != HasReturnvaluesIF::RETURN_FAILED) {
-
-		}
-		tmtcBridge->checkAndSetClientAddress(senderAddress);
-	}
-	return HasReturnvaluesIF::RETURN_OK;
-}
-
-
-ReturnValue_t TcWinUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
-	store_address_t storeId;
-
-#if FSFW_UDP_RCV_WIRETAPPING_ENABLED == 1
-    arrayprinter::print(receptionBuffer.data(), bytesRead);
-#endif
-
-	ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead);
-	if (result != HasReturnvaluesIF::RETURN_OK) {
-#if FSFW_VERBOSE_LEVEL >= 1
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::warning<< "TcWinUdpPollingTask::transferPusToSoftwareBus: Data storage failed." <<
-		        std::endl;
-		sif::warning << "Packet size: " << bytesRead << std::endl;
-#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
-#endif /* FSFW_VERBOSE_LEVEL >= 1 */
-		return HasReturnvaluesIF::RETURN_FAILED;
-	}
-
-	TmTcMessage message(storeId);
-
-	result  = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
-	if (result != HasReturnvaluesIF::RETURN_OK) {
-#if FSFW_VERBOSE_LEVEL >= 1
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::warning << "TcWinUdpPollingTask::handleSuccessfullTcRead: "
-		        " Sending message to queue failed" << std::endl;
-#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
-#endif /* FSFW_VERBOSE_LEVEL >= 1 */
-		tcStore->deleteData(storeId);
-	}
-	return result;
-}
-
-ReturnValue_t TcWinUdpPollingTask::initialize() {
-	tcStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
-	if (tcStore == nullptr) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcWinUdpPollingTask::initialize: TC store uninitialized!" << std::endl;
-#endif
-		return ObjectManagerIF::CHILD_INIT_FAILED;
-	}
-
-	tmtcBridge = objectManager->get<TmTcWinUdpBridge>(tmtcBridgeId);
-	if(tmtcBridge == nullptr) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcWinUdpPollingTask::initialize: Invalid TMTC bridge object!" <<
-		        std::endl;
-#endif
-		return ObjectManagerIF::CHILD_INIT_FAILED;
-	}
-	return HasReturnvaluesIF::RETURN_OK;
-}
-
-ReturnValue_t TcWinUdpPollingTask::initializeAfterTaskCreation() {
-	/* Initialize the destination after task creation. This ensures
-	that the destination has already been set in the TMTC bridge. */
-	targetTcDestination = tmtcBridge->getRequestQueue();
-	/* The server socket is set up in the bridge intialization. Calling this function here
-	ensures that it is set up properly in any case*/
-    serverUdpSocket = tmtcBridge->serverSocket;
-	return HasReturnvaluesIF::RETURN_OK;
-}
-
-void TcWinUdpPollingTask::setTimeout(double timeoutSeconds) {
-	DWORD timeoutMs = timeoutSeconds * 1000.0;
-	int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO,
-			reinterpret_cast<const char*>(&timeoutMs), sizeof(DWORD));
-	if(result == -1) {
-#if FSFW_CPP_OSTREAM_ENABLED == 1
-		sif::error << "TcWinUdpPollingTask::TcSocketPollingTask: Setting "
-				"receive timeout failed with " << strerror(errno) << std::endl;
-#endif
-	}
-}
diff --git a/osal/windows/tcpipHelpers.cpp b/osal/windows/tcpipHelpers.cpp
index ef07f5ca..03278a92 100644
--- a/osal/windows/tcpipHelpers.cpp
+++ b/osal/windows/tcpipHelpers.cpp
@@ -1,4 +1,4 @@
-#include "tcpipHelpers.h"
+#include "../common/tcpipHelpers.h"
 #include <FSFWConfig.h>
 
 #include "../../tasks/TaskFactory.h"
diff --git a/osal/windows/winTaskHelpers.cpp b/osal/windows/winTaskHelpers.cpp
new file mode 100644
index 00000000..6765b952
--- /dev/null
+++ b/osal/windows/winTaskHelpers.cpp
@@ -0,0 +1,107 @@
+#include <fsfw/osal/windows/winTaskHelpers.h>
+#include <mutex>
+
+TaskPriority tasks::makeWinPriority(PriorityClass prioClass, PriorityNumber prioNumber) {
+    return (static_cast<uint16_t>(prioClass) << 16) | static_cast<uint16_t> (prioNumber);
+}
+
+void tasks::getWinPriorityParameters(TaskPriority priority,
+        DWORD& priorityClass, int& priorityNumber) {
+    PriorityClass classInternal = static_cast<PriorityClass>(priority >> 16 & 0xff);
+    PriorityNumber numberInternal = static_cast<PriorityNumber>(priority & 0xff);
+    switch(classInternal) {
+    case(CLASS_IDLE): {
+        priorityClass = IDLE_PRIORITY_CLASS;
+        break;
+    }
+    case(CLASS_BELOW_NORMAL): {
+        priorityClass = BELOW_NORMAL_PRIORITY_CLASS;
+        break;
+    }
+    case(CLASS_NORMAL): {
+        priorityClass = NORMAL_PRIORITY_CLASS;
+        break;
+    }
+    case(CLASS_ABOVE_NORMAL): {
+        priorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
+        break;
+    }
+    case(CLASS_HIGH): {
+        priorityClass = HIGH_PRIORITY_CLASS;
+        break;
+    }
+    case(CLASS_REALTIME): {
+        priorityClass = REALTIME_PRIORITY_CLASS;
+        break;
+    }
+    default: {
+        priorityClass = NORMAL_PRIORITY_CLASS;
+    }
+    }
+
+    switch(numberInternal) {
+    case(IDLE): {
+        priorityNumber = THREAD_PRIORITY_IDLE;
+        break;
+    }
+    case(LOWEST): {
+        priorityNumber = THREAD_PRIORITY_LOWEST;
+        break;
+    }
+    case(BELOW_NORMAL): {
+        priorityNumber = THREAD_PRIORITY_BELOW_NORMAL;
+        break;
+    }
+    case(NORMAL): {
+        priorityNumber = THREAD_PRIORITY_NORMAL;
+        break;
+    }
+    case(ABOVE_NORMAL): {
+        priorityNumber = THREAD_PRIORITY_ABOVE_NORMAL;
+        break;
+    }
+    case(HIGHEST): {
+        priorityNumber = THREAD_PRIORITY_HIGHEST;
+        break;
+    }
+    case(CRITICAL): {
+        priorityNumber = THREAD_PRIORITY_TIME_CRITICAL;
+        break;
+    }
+    default: {
+        priorityNumber = THREAD_PRIORITY_NORMAL;
+    }
+    }
+}
+
+ReturnValue_t tasks::setTaskPriority(HANDLE nativeHandle, TaskPriority priority) {
+    /* List of possible priority classes:
+    https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setpriorityclass
+    And respective thread priority numbers:
+    https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities
+    */
+    DWORD dwPriorityClass = 0;
+    int nPriorityNumber = 0;
+    tasks::getWinPriorityParameters(priority, dwPriorityClass, nPriorityNumber);
+    int result = SetPriorityClass(
+            reinterpret_cast<HANDLE>(nativeHandle),
+            dwPriorityClass);
+    if(result != 0) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
+                << GetLastError() << std::endl;
+        return HasReturnvaluesIF::RETURN_FAILED;
+#endif
+    }
+    result = SetThreadPriority(
+            reinterpret_cast<HANDLE>(nativeHandle),
+            nPriorityNumber);
+    if(result != 0) {
+#if FSFW_CPP_OSTREAM_ENABLED == 1
+        sif::error << "PeriodicTask: Windows SetPriorityClass failed with code "
+                << GetLastError() << std::endl;
+        return HasReturnvaluesIF::RETURN_FAILED;
+#endif
+    }
+    return HasReturnvaluesIF::RETURN_OK;
+}
diff --git a/osal/windows/winTaskHelpers.h b/osal/windows/winTaskHelpers.h
new file mode 100644
index 00000000..64e52672
--- /dev/null
+++ b/osal/windows/winTaskHelpers.h
@@ -0,0 +1,37 @@
+#include "../../tasks/TaskFactory.h"
+
+#include <thread>
+#include <map>
+
+#ifdef _WIN32
+
+namespace tasks {
+
+enum PriorityClass: uint16_t {
+    CLASS_IDLE,
+    CLASS_BELOW_NORMAL,
+    CLASS_NORMAL,
+    CLASS_ABOVE_NORMAL,
+    CLASS_HIGH,
+    CLASS_REALTIME
+};
+enum PriorityNumber: uint16_t {
+    IDLE,
+    LOWEST,
+    BELOW_NORMAL,
+    NORMAL,
+    ABOVE_NORMAL,
+    HIGHEST,
+    CRITICAL
+};
+TaskPriority makeWinPriority(PriorityClass prioClass = PriorityClass::CLASS_NORMAL,
+        PriorityNumber prioNumber = PriorityNumber::NORMAL);
+void getWinPriorityParameters(TaskPriority priority, DWORD& priorityClass,
+        int& priorityNumber);
+
+ReturnValue_t setTaskPriority(HANDLE nativeHandle, TaskPriority priority);
+
+}
+
+#endif
+
diff --git a/tasks/TaskFactory.h b/tasks/TaskFactory.h
index 03b5163c..d4795202 100644
--- a/tasks/TaskFactory.h
+++ b/tasks/TaskFactory.h
@@ -22,9 +22,26 @@ public:
 	/**
 	 * Creates a new periodic task and returns the interface pointer.
 	 * @param name_ Name of the task
-	 * @param taskPriority_ Priority of the task
+	 * @param taskPriority_
+	 * Priority of the task. This value might have different ranges for the various OSALs.
+	 *  - Linux     Value ranging from 0 to 99 with 99 being the highest value.
+	 *  - Host      For Windows, the value can be retrieved by using the #tasks::makeWinPriority
+	 *              function. For Linux, same priority system as specified above. MacOS not tested
+	 *              yet
+	 *  - FreeRTOS  Value depends on the FreeRTOS configuration, higher number means higher priority
+	 *  - RTEMS     Values ranging from 0 to 99 with 99 being the highest value.
+	 *
 	 * @param stackSize_ Stack Size of the task
+	 * This value might have different recommended ranges for the various OSALs.
+	 *  - Linux     Lowest limit is the PeriodicTaskIF::MINIMUM_STACK_SIZE value
+	 *  - Host      Value is ignored for now because the C++ threading abstraction layer is used.
+	 *  - FreeRTOS  Stack size in bytes. It is recommended to specify at least 1kB of stack for
+	 *              FSFW tasks, but the lowest possible size is specified in the
+	 *              FreeRTOSConfig.h file.
+	 *  - RTEMS     Lowest limit is specified the PeriodicTaskIF::MINIMUM_STACK_SIZE value.
+	 *
 	 * @param period_ Period of the task
+	 *
 	 * @param deadLineMissedFunction_ Function to be called if a deadline was missed
 	 * @return PeriodicTaskIF* Pointer to the newly created Task
 	 */
@@ -34,7 +51,8 @@ public:
 			TaskDeadlineMissedFunction deadLineMissedFunction_);
 
 	/**
-	 *
+	 * The meaning for the variables for fixed timeslot tasks is the same as for periodic tasks.
+	 * See #createPeriodicTask documentation.
 	 * @param name_ Name of the task
 	 * @param taskPriority_ Priority of the task
 	 * @param stackSize_ Stack Size of the task
diff --git a/tasks/Typedef.h b/tasks/Typedef.h
index 07d96b00..55f6bda2 100644
--- a/tasks/Typedef.h
+++ b/tasks/Typedef.h
@@ -2,7 +2,7 @@
 #define FRAMEWORK_TASKS_TYPEDEF_H_
 
 typedef const char* TaskName;
-typedef uint8_t TaskPriority;
+typedef uint32_t TaskPriority;
 typedef size_t TaskStackSize;
 typedef double TaskPeriod;
 typedef void (*TaskDeadlineMissedFunction)();