From d7bbd4b652ff2e2e4fe63485fe57e5622ec3d82a Mon Sep 17 00:00:00 2001
From: "Robin.Mueller" <robin.mueller.m@gmail.com>
Date: Thu, 10 Sep 2020 19:51:17 +0200
Subject: [PATCH] severla bugfixes, new periodic op divider added

---
 datapoollocal/LocalDataPoolManager.cpp       | 32 ++++++----
 datapoollocal/LocalDataPoolManager.h         |  5 +-
 globalfunctions/PeriodicOperationDivider.cpp | 34 +++++++++++
 globalfunctions/PeriodicOperationDivider.h   | 55 +++++++++++++++++
 housekeeping/HousekeepingPacketDownlink.h    | 64 +++++---------------
 5 files changed, 127 insertions(+), 63 deletions(-)
 create mode 100644 globalfunctions/PeriodicOperationDivider.cpp
 create mode 100644 globalfunctions/PeriodicOperationDivider.h

diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp
index c84b2c697..39434b5a7 100644
--- a/datapoollocal/LocalDataPoolManager.cpp
+++ b/datapoollocal/LocalDataPoolManager.cpp
@@ -177,7 +177,8 @@ const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
 }
 
 ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
-        float collectionInterval, MessageQueueId_t destination) {
+        /*float collectionInterval, bool reportingEnabled, */
+		bool forDownlink, MessageQueueId_t destination) {
 	LocalPoolDataSetBase* dataSetToSerialize =
 			dynamic_cast<LocalPoolDataSetBase*>(owner->getDataSetHandle(sid));
 	if(dataSetToSerialize == nullptr) {
@@ -187,10 +188,13 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
 	}
 
 	store_address_t storeId;
-	HousekeepingPacketDownlink hkPacket(sid, collectionInterval,
-	        dataSetToSerialize->getFillCount(), dataSetToSerialize);
-	ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, &storeId);
-	if(result != HasReturnvaluesIF::RETURN_OK) {
+	HousekeepingPacketDownlink hkPacket(sid,/* reportingEnabled,
+			collectionInterval, dataSetToSerialize->getFillCount(), */
+			dataSetToSerialize);
+	size_t serializedSize = 0;
+	ReturnValue_t result = serializeHkPacketIntoStore(hkPacket, storeId,
+			forDownlink, &serializedSize);
+	if(result != HasReturnvaluesIF::RETURN_OK or serializedSize == 0) {
 	    return result;
 	}
 
@@ -213,17 +217,21 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
 
 ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
         HousekeepingPacketDownlink& hkPacket,
-        store_address_t *storeId) {
+        store_address_t& storeId, bool forDownlink,
+		size_t* serializedSize) {
     uint8_t* dataPtr = nullptr;
-    size_t serializedSize = 0;
     const size_t maxSize = hkPacket.getSerializedSize();
-    ReturnValue_t  result = ipcStore->getFreeElement(storeId,
-            serializedSize, &dataPtr);
+    ReturnValue_t result = ipcStore->getFreeElement(&storeId,
+            maxSize, &dataPtr);
     if(result != HasReturnvaluesIF::RETURN_OK) {
         return result;
     }
 
-    return hkPacket.serialize(&dataPtr, &serializedSize, maxSize,
+    if(forDownlink) {
+    	return hkPacket.serialize(&dataPtr, serializedSize, maxSize,
+    	            SerializeIF::Endianness::BIG);
+    }
+    return hkPacket.serialize(&dataPtr, serializedSize, maxSize,
             SerializeIF::Endianness::MACHINE);
 }
 
@@ -265,7 +273,9 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) {
     if(receiver->intervalCounter >=
             receiver->hkParameter.collectionIntervalTicks) {
         ReturnValue_t result = generateHousekeepingPacket(
-                receiver->dataId.dataSetSid);
+                receiver->dataId.dataSetSid, true
+				/*intervalToIntervalSeconds(receiver->isDiagnostics,
+				receiver->hkParameter.collectionIntervalTicks), true */);
         if(result != HasReturnvaluesIF::RETURN_OK) {
             // configuration error
             sif::debug << "LocalDataPoolManager::performHkOperation:"
diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h
index c6567c804..552aaff70 100644
--- a/datapoollocal/LocalDataPoolManager.h
+++ b/datapoollocal/LocalDataPoolManager.h
@@ -110,7 +110,8 @@ public:
 	 * @return
 	 */
 	ReturnValue_t generateHousekeepingPacket(sid_t sid,
-	        float collectionInterval = 0,
+			bool forDownlink,
+	        /*float collectionInterval, bool reportingEnabled, */
 	        MessageQueueId_t destination = MessageQueueIF::NO_QUEUE);
 	ReturnValue_t generateSetStructurePacket(sid_t sid);
 
@@ -248,7 +249,7 @@ private:
 	void setMinimalSamplingFrequency(float frequencySeconds);
 	ReturnValue_t serializeHkPacketIntoStore(
 	        HousekeepingPacketDownlink& hkPacket,
-	        store_address_t *storeId);
+	        store_address_t& storeId, bool forDownlink, size_t* serializedSize);
 
 	uint32_t intervalSecondsToInterval(bool isDiagnostics,
 	        float collectionIntervalSeconds);
diff --git a/globalfunctions/PeriodicOperationDivider.cpp b/globalfunctions/PeriodicOperationDivider.cpp
new file mode 100644
index 000000000..ad3b8bbd5
--- /dev/null
+++ b/globalfunctions/PeriodicOperationDivider.cpp
@@ -0,0 +1,34 @@
+#include "PeriodicOperationDivider.h"
+
+
+PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider,
+		bool resetAutomatically): resetAutomatically(resetAutomatically),
+		counter(divider), divider(divider) {
+}
+
+bool PeriodicOperationDivider::checkAndIncrement() {
+	if(counter >= divider) {
+		if(resetAutomatically) {
+			counter = 0;
+		}
+		return true;
+	}
+	counter ++;
+	return false;
+}
+
+void PeriodicOperationDivider::resetCounter() {
+	counter = 0;
+}
+
+void PeriodicOperationDivider::setDivider(uint32_t newDivider) {
+	divider = newDivider;
+}
+
+uint32_t PeriodicOperationDivider::getCounter() const {
+	return counter;
+}
+
+uint32_t PeriodicOperationDivider::getDivider() const {
+	return divider;
+}
diff --git a/globalfunctions/PeriodicOperationDivider.h b/globalfunctions/PeriodicOperationDivider.h
new file mode 100644
index 000000000..dd970fb8a
--- /dev/null
+++ b/globalfunctions/PeriodicOperationDivider.h
@@ -0,0 +1,55 @@
+#ifndef FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_
+#define FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_
+
+#include <cstdint>
+
+/**
+ * @brief	Lightweight helper class to facilitate periodic operation with
+ * 			decreased frequencies.
+ * @details
+ * This class is useful to perform operations which have to be performed
+ * with a reduced frequency, like debugging printouts in high periodic tasks
+ * or low priority operations.
+ */
+class PeriodicOperationDivider {
+public:
+	/**
+	 * Initialize with the desired divider and specify whether the internal
+	 * counter will be reset automatically.
+	 * @param divider
+	 * @param resetAutomatically
+	 */
+	PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true);
+
+	/**
+	 * Check whether operation is necessary.
+	 * If an operation is necessary and the class has been
+	 * configured to be reset automatically, the counter will be reset.
+	 * If not, the counter will be incremented.
+	 * @return
+	 * -@c true if the counter is larger or equal to the divider
+	 * -@c false otherwise
+	 */
+	bool checkAndIncrement();
+
+	/**
+	 * Can be used to reset the counter to 0 manually.
+	 */
+	void resetCounter();
+	uint32_t getCounter() const;
+
+	/**
+	 * Can be used to set a new divider value.
+	 * @param newDivider
+	 */
+	void setDivider(uint32_t newDivider);
+	uint32_t getDivider() const;
+private:
+	bool resetAutomatically = true;
+	uint32_t counter = 0;
+	uint32_t divider = 0;
+};
+
+
+
+#endif /* FSFW_GLOBALFUNCTIONS_PERIODICOPERATIONDIVIDER_H_ */
diff --git a/housekeeping/HousekeepingPacketDownlink.h b/housekeeping/HousekeepingPacketDownlink.h
index ee531bae7..0be1551d5 100644
--- a/housekeeping/HousekeepingPacketDownlink.h
+++ b/housekeeping/HousekeepingPacketDownlink.h
@@ -2,8 +2,6 @@
 #define FSFW_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_
 
 #include "../datapoollocal/LocalPoolDataSetBase.h"
-
-#include "../housekeeping/HousekeepingMessage.h"
 #include "../serialize/SerialLinkedListAdapter.h"
 #include "../storagemanager/StorageManagerIF.h"
 
@@ -16,67 +14,33 @@
  */
 class HousekeepingPacketDownlink: public SerialLinkedListAdapter<SerializeIF> {
 public:
-    HousekeepingPacketDownlink(sid_t sid, float collectionInterval, uint8_t
-            numberOfParameters, LocalPoolDataSetBase* dataSetPtr):
+    HousekeepingPacketDownlink(sid_t sid, /*bool reportingStatus,
+    		float collectionInterval, uint8_t numberOfParameters, */
+			LocalPoolDataSetBase* dataSetPtr):
             sourceId(sid.objectId), setId(sid.ownerSetId),
-            collectionInterval(collectionInterval),
-            numberOfParameters(numberOfParameters), hkData(dataSetPtr) {
+			/*reportingStatus(reportingStatus),
+			collectionInterval(collectionInterval),
+            numberOfParameters(numberOfParameters), */hkData(dataSetPtr) {
         setLinks();
     }
 
-    /**
-     * Helper functions which can be used to move HK data from the IPC store
-     * to the telemetry store. TODO: maybe not needed.
-     * @param formerStore
-     * @param storeId
-     * @param newStore
-     * @param newStoreId [out]
-     * @return
-     */
-    virtual ReturnValue_t moveToOtherStore(StorageManagerIF* formerStore,
-            store_address_t storeId, StorageManagerIF* newStore,
-            store_address_t* newStoreId) {
-        const uint8_t* dataPtr = nullptr;
-        size_t hkDataSize = 0;
-        ReturnValue_t result = formerStore->getData(storeId, &dataPtr,
-                &hkDataSize);
-        if(result != HasReturnvaluesIF::RETURN_OK) {
-            return result;
-        }
-
-        return newStore->addData(newStoreId, dataPtr, hkDataSize);
-    }
-
 private:
     void setLinks() {
         setStart(&sourceId);
         sourceId.setNext(&setId);
-        setId.setNext(&collectionInterval);
-        collectionInterval.setNext(&numberOfParameters);
-        numberOfParameters.setNext(&hkData);
+        setId.setNext(&hkData);
+        //setId.setNext(&reportingStatus);
+		//reportingStatus.setNext(&collectionInterval);
+        //collectionInterval.setNext(&numberOfParameters);
+        //numberOfParameters.setNext(&hkData);
     }
 
     SerializeElement<object_id_t> sourceId;
     SerializeElement<uint32_t> setId;
-    SerializeElement<float> collectionInterval;
-    SerializeElement<uint8_t> numberOfParameters;
+    //SerializeElement<uint8_t> reportingStatus;
+    //SerializeElement<float> collectionInterval;
+    //SerializeElement<uint8_t> numberOfParameters;
     LinkedElement<SerializeIF> hkData;
 };
 
 #endif /* FRAMEWORK_HOUSEKEEPING_HOUSEKEEPINGPACKETDOWNLINK_H_ */
-
-
-
-//    virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
-//                size_t maxSize, Endianness streamEndianness) const override {
-//        ReturnValue_t result = SerialLinkedListAdapter::serialize(buffer, size,
-//                maxSize, streamEndianness);
-//        if(result != HasReturnvaluesIF::RETURN_OK) {
-//            return result;
-//        }
-//        return dataSetPtr->serialize(buffer, size, maxSize, streamEndianness);
-//   }
-//
-//   virtual size_t getSerializedSize() const override {
-//
-//   }