From f0d29c20f85c2af795d08a6fd65e4f35a183af6d Mon Sep 17 00:00:00 2001
From: thodkatz <thodkatz@gmail.com>
Date: Tue, 23 Apr 2019 21:34:11 +0300
Subject: [PATCH] Update documentation and define leap seconds

---
 inc/Helpers/TimeHelper.hpp | 20 ++++++++++++--------
 src/Helpers/TimeHelper.cpp |  5 +++--
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/inc/Helpers/TimeHelper.hpp b/inc/Helpers/TimeHelper.hpp
index 3fe15762..4b0c7e3e 100644
--- a/inc/Helpers/TimeHelper.hpp
+++ b/inc/Helpers/TimeHelper.hpp
@@ -8,6 +8,7 @@
 #define SECONDS_PER_MINUTE 60u
 #define SECONDS_PER_HOUR 3600u
 #define SECONDS_PER_DAY 86400u
+#define LEAP_SECONDS 27
 
 /**
  * This class formats the spacecraft time and cooperates closely with the ST[09] time management.
@@ -20,10 +21,10 @@
  * T-Field. The T-Field is consisted of two segments: 1) the `DAY` and the 2) `ms of day` segments. The P-field won't
  * be included in the code, because as the ECSS standards claims, it can be just implicitly declared.
  *
- * The CUC time format consists of two main fields: the time code preamble field (P-field) and the time specification
- * field(T-field). The T-Field contains the value of the time unit and the designer decides what the time unit will
- * be, so this is a subject for discussion. The recommended time unit from the standard is the second and it is
- * probably the best solution for accuracy.
+ * The CUC is TAI-based (TAI: International Atomic Time). It consists of two main fields: the time code preamble field
+ * (P-field) and the time specification field(T-field). The T-Field contains the value of the time unit and the designer
+ * decides what the time unit will be, so this is a subject for discussion. The recommended time unit from the
+ * standard is the second and it is probably the best solution for accuracy.
  *
  * @notes
  * The defined epoch for both time formats is 1 January 1958 00:00:00
@@ -102,11 +103,14 @@ public:
 	 *
 	 * Converts a UTC date to CUC time format.
 	 *
-	 * @note
+	 * @notes
 	 * The T-field is specified for the seconds passed from the defined epoch 1 January 1958. We use 4 octets(32
-	 * bits) for the time unit(seconds) because 32 bits for the seconds are enough to count 136 years! But if we use 24
+	 * bits) for the time unit (seconds) because 32 bits for the seconds are enough to count 136 years! But if we use 24
 	 * bits for the seconds then it will count 0,5 years and this isn't enough. Remember we can use only integers
-	 * numbers of octets for the time unit(second)
+	 * numbers of octets for the time unit (second)
+	 *
+	 * The CUC time format doesn't include leap seconds, so we need to add them because we assume that
+	 * the RTC will provide UTC format.
 	 *
 	 * @param TimeInfo is the data provided from RTC (UTC)
 	 * @return TimeFormat the CUC time format. More specific, 32 bits are used for the T-field (seconds since 1/1/1958)
@@ -122,7 +126,7 @@ public:
 	 * fixed size of 32 bits
 	 * @return the UTC date
 	 */
-	static TimeAndDate parseCUCtimeFormat(const uint8_t* data);
+	static TimeAndDate parseCUCtimeFormat(uint8_t* data);
 };
 
 #endif // ECSS_SERVICES_TIMEHELPER_HPP
diff --git a/src/Helpers/TimeHelper.cpp b/src/Helpers/TimeHelper.cpp
index 85248bed..ba14132e 100644
--- a/src/Helpers/TimeHelper.cpp
+++ b/src/Helpers/TimeHelper.cpp
@@ -127,12 +127,13 @@ TimeAndDate TimeHelper::parseCDStimeFormat(const uint8_t* data) {
 }
 
 uint32_t TimeHelper::generateCUCtimeFormat(struct TimeAndDate& TimeInfo) {
-	return utcToSeconds(TimeInfo);
+	return (utcToSeconds(TimeInfo) + LEAP_SECONDS);
 }
 
-TimeAndDate TimeHelper::parseCUCtimeFormat(const uint8_t* data) {
+TimeAndDate TimeHelper::parseCUCtimeFormat(uint8_t* data) {
 	uint32_t seconds = ((static_cast<uint32_t>(data[0])) << 24) | ((static_cast<uint32_t>(data[1]))) << 16 |
 	                   ((static_cast<uint32_t>(data[2]))) << 8 | (static_cast<uint32_t>(data[3]));
+	seconds -= LEAP_SECONDS;
 
 	return secondsToUTC(seconds);
 }
-- 
GitLab