diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp
new file mode 100644
index 00000000..e7928317
--- /dev/null
+++ b/tmtcservices/TmTcBridge.cpp
@@ -0,0 +1,173 @@
+/**
+ * @file TmTcBridge.cpp
+ *
+ * @date 26.12.2019
+ */
+
+#include <framework/tmtcservices/TmTcBridge.h>
+
+#include <framework/ipc/QueueFactory.h>
+#include <framework/tmtcservices/AcceptsTelecommandsIF.h>
+#include <framework/serviceinterface/ServiceInterfaceStream.h>
+
+TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_):
+	SystemObject(objectId_),tcStore(NULL), tmStore(NULL),
+	ccsdsPacketDistributor(ccsdsPacketDistributor_), communicationLinkUp(false),
+	tmStored(false) {
+	TmTcReceptionQueue = QueueFactory::instance()->
+			createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
+
+}
+
+TmTcBridge::~TmTcBridge() {
+}
+
+ReturnValue_t TmTcBridge::initialize() {
+	tcStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
+	if (tcStore == NULL) {
+		return RETURN_FAILED;
+	}
+	tmStore = objectManager->get<StorageManagerIF>(objects::TM_STORE);
+	if (tmStore == NULL) {
+		return RETURN_FAILED;
+	}
+	AcceptsTelecommandsIF* tcDistributor =
+			objectManager->get<AcceptsTelecommandsIF>(ccsdsPacketDistributor);
+	if (tcDistributor == NULL) {
+		return RETURN_FAILED;
+	}
+	TmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue());
+	return RETURN_OK;
+}
+
+ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) {
+	ReturnValue_t result;
+	result = handleTc();
+	if(result != RETURN_OK) {
+		error << "TMTC Bridge: Error handling TCs" << std::endl;
+	}
+	result = handleTm();
+	if (result != RETURN_OK) {
+		error << "TMTC Bridge: Error handling TMs" << std::endl;
+	}
+	return result;
+}
+
+ReturnValue_t TmTcBridge::handleTc() {
+	ReturnValue_t result = receiveTc();
+	return result;
+}
+
+ReturnValue_t TmTcBridge::handleTm() {
+	ReturnValue_t result = readTmQueue();
+	if(result != RETURN_OK) {
+		error << "TMTC Bridge: Reading TM Queue failed" << std::endl;
+		return RETURN_FAILED;
+	}
+
+	if(tmStored && communicationLinkUp) {
+		result = sendStoredTm();
+	}
+	return result;
+
+}
+
+ReturnValue_t TmTcBridge::readTmQueue() {
+	TmTcMessage message;
+	const uint8_t* data = NULL;
+	uint32_t size = 0;
+	for (ReturnValue_t result = TmTcReceptionQueue->receiveMessage(&message);
+		 result == RETURN_OK; result = TmTcReceptionQueue->receiveMessage(&message))
+	{
+		if(not communicationLinkUp) {
+			result = storeDownlinkData(&message);
+			return result;
+		}
+
+		result = tmStore->getData(message.getStorageId(), &data, &size);
+		if (result != HasReturnvaluesIF::RETURN_OK) {
+			continue;
+		}
+
+		result = sendTm(data, size);
+		if (result != RETURN_OK) {
+			error << "UDP Server: Could not send TM packet"<< std::endl;
+			tmStore->deleteData(message.getStorageId());
+			return result;
+
+		}
+		tmStore->deleteData(message.getStorageId());
+	}
+	return RETURN_OK;
+}
+
+ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) {
+	info << "UDP Server: Client address not bound yet. Packet can not be sent. "
+			"Saving packet to be sent later " << std::endl;
+	store_address_t storeId;
+
+	if(fifo.full()) {
+		info << "UDP Server: TM downlink store is full. Overwriting old data" << std::endl;
+		fifo.retrieve(&storeId);
+	}
+	storeId = message->getStorageId();
+	fifo.insert(storeId);
+	//storageIdBufferCounter ++;
+	tmStored = true;
+	return RETURN_OK;
+}
+
+ReturnValue_t TmTcBridge::sendStoredTm() {
+	uint8_t counter = 0;
+	ReturnValue_t result = RETURN_OK;
+	while(!fifo.empty() && counter < MAX_STORED_DATA_SENT_PER_CYCLE) {
+		info << "UDP Server: Sending stored TM data. There are "
+				<< (int) fifo.size() << " left to send" << std::endl;
+		store_address_t storeId;
+		const uint8_t* data = NULL;
+		uint32_t size = 0;
+		fifo.retrieve(&storeId);
+		result = tmStore->getData(storeId, &data, &size);
+		sendTm(data,size);
+		if(result != RETURN_OK) {
+			error << "UDP Server: Could not send stored downlink data" << std::endl;
+			result = RETURN_FAILED;
+		}
+		counter ++;
+
+		if(fifo.empty()) {
+			tmStored = false;
+		}
+		tmStore->deleteData(storeId);
+	}
+	return result;
+}
+
+void TmTcBridge::registerCommConnect() {
+	info << "TMTC Bridge: Registered Comm Link Connect" << std::endl;
+	if(not communicationLinkUp) {
+		communicationLinkUp = true;
+	}
+}
+
+void TmTcBridge::registerCommDisconnect() {
+	info << "TMTC Bridge: Registered Comm Link Disconnect" << std::endl;
+	if(communicationLinkUp) {
+		communicationLinkUp = false;
+	}
+}
+
+MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) {
+	return TmTcReceptionQueue->getId();
+}
+
+void TmTcBridge::printData(uint8_t * data, uint32_t dataLen) {
+	info << "TMTC Bridge: Printing data: [";
+	for(uint32_t i=0;i<dataLen;i++) {
+		info << std::hex << (int)data[i];
+		if(i < dataLen-1){
+			info << " , ";
+		}
+	}
+	info << " ] " << std::endl;
+}
diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h
new file mode 100644
index 00000000..ad09bf7c
--- /dev/null
+++ b/tmtcservices/TmTcBridge.h
@@ -0,0 +1,121 @@
+/**
+ * @file TmTcBridge.h
+ *
+ * @date 26.12.2019
+ */
+
+#ifndef FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_
+#define FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_
+
+#include <framework/tmtcservices/AcceptsTelemetryIF.h>
+#include <framework/tasks/ExecutableObjectIF.h>
+#include <framework/ipc/MessageQueueIF.h>
+#include <framework/storagemanager/StorageManagerIF.h>
+#include <framework/objectmanager/SystemObject.h>
+
+#include <framework/tmtcservices/TmTcMessage.h>
+#include <framework/container/FIFO.h>
+
+class TmTcBridge : public AcceptsTelemetryIF,
+		public ExecutableObjectIF,
+		public HasReturnvaluesIF,
+		public SystemObject {
+public:
+	TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_);
+	virtual ~TmTcBridge();
+
+	/**
+	 * Initializes basic FSFW components for TMTC Bridge
+	 * @return
+	 */
+	virtual ReturnValue_t initialize();
+
+	/**
+	 * @brief	The performOperation method is executed in a task.
+	 * @details	There are no restrictions for calls within this method, so any
+	 * 			other member of the class can be used.
+	 * @return	Currently, the return value is ignored.
+	 */
+	virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
+
+	/**
+	 * Return TMTC Reception Queue
+	 * @param virtualChannel
+	 * @return
+	 */
+	virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0);
+
+protected:
+	MessageQueueIF* TmTcReceptionQueue; //!< Used to send and receive TMTC messages. TmTcMessage is used to transport messages between tasks.
+	StorageManagerIF* tcStore;
+	StorageManagerIF* tmStore;
+	object_id_t ccsdsPacketDistributor;
+	bool communicationLinkUp; //!< Used to specify whether communication link is up
+	bool tmStored;
+
+	/**
+	 * Handle TC reception. Default implementation provided
+	 * @return
+	 */
+	virtual ReturnValue_t handleTc();
+
+	/**
+	 * Implemented by child class. Perform receiving of Telecommand
+	 * @return
+	 */
+	virtual ReturnValue_t receiveTc() = 0;
+
+	/**
+	 * Handle Telemetry. Default implementation provided.
+	 * Calls sendTm()
+	 * @return
+	 */
+	virtual ReturnValue_t handleTm();
+
+	/**
+	 * Read the TM Queue and send TM if necessary. Default implementation provided
+	 * @return
+	 */
+	virtual ReturnValue_t readTmQueue();
+
+	/**
+	 * Implemented by child class. Perform sending of Telemetry
+	 * @param data
+	 * @param dataLen
+	 * @return
+	 */
+	virtual ReturnValue_t sendTm(const uint8_t * data, uint32_t dataLen) = 0;
+
+	/**
+	 * Store data to be sent later if communication link is not up.
+	 * @param message
+	 * @return
+	 */
+	ReturnValue_t storeDownlinkData(TmTcMessage * message);
+
+	/**
+	 * Send stored data if communication link is active
+	 * @return
+	 */
+	ReturnValue_t sendStoredTm();
+
+	/**
+	 * Print data as hexidecimal array
+	 * @param data
+	 * @param dataLen
+	 */
+	void printData(uint8_t * data, uint32_t dataLen);
+
+	void registerCommConnect();
+	void registerCommDisconnect();
+
+private:
+	static const uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
+	static const uint8_t MAX_STORED_DATA_SENT_PER_CYCLE = 10;
+	static const uint8_t MAX_DOWNLINK_PACKETS_STORED = 20;
+
+	FIFO<store_address_t, MAX_DOWNLINK_PACKETS_STORED> fifo;
+};
+
+
+#endif /* FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ */