commit bc7aed201a95f0355c31b99e023cc6afd1bf8f2d
Author: Thomas Schöpping <tschoepp@cit-ec.uni-bielefeld.de>
Date:   Mon Nov 11 18:18:43 2019 +0100

    calendar synchronization implemented

diff --git a/core/src/aos_main.cpp b/core/src/aos_main.cpp
index 322c566..684b81a 100644
--- a/core/src/aos_main.cpp
+++ b/core/src/aos_main.cpp
@@ -123,10 +123,10 @@ AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES
  * @param[in] mask    The event mask.
  * @param[in] flags   The event flags.
  */
-static inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
+inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
 {
 #if (AMIROOS_CFG_DBG == true)
-  aosprintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
+  aosDbgPrintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
 #else /* (AMIROOS_CFG_DBG == true) */
   (void)(mask);
   (void)(flags);
@@ -134,47 +134,8 @@ static inline void _unexpectedEventError(const eventmask_t mask, const eventflag
   return;
 }
 
-/**
- * @brief   Helper function to serialize data.
- *
- * @param[out]  dst   Pointer to the output buffer.
- * @param[in]   src   Data to be serialized.
- * @param[in]   n     Number of bytes to serialize.
- */
-inline void _serialize(uint8_t* dst, const uint64_t src, const uint8_t n)
-{
-  aosDbgCheck(dst != NULL);
-  aosDbgCheck(n > 0 && n <= 8);
-
-  for (uint8_t byte = 0; byte < n; ++byte) {
-    dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
-  }
-
-  return;
-}
-
-/**
- * @brief   Helper function to deserialize data.
- *
- * @param[in] src   Pointer to the buffer of data to be deserialzed.
- * @param[in] n     Number of bytes to deserialize.
- *
- * @return    The deserialized 32 bit data.
- */
-inline uint64_t _deserialize(uint8_t* src, const uint8_t n)
-{
-  aosDbgCheck(src != NULL);
-  aosDbgCheck(n > 0 && n <= 8);
-
-  uint64_t result = 0;
-  for (uint8_t byte = 0; byte < n; ++byte) {
-    result |= ((uint64_t)src[byte]) << (byte * 8);
-  }
-
-  return result;
-}
-
-#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
+#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_RTC == TRUE)) || defined(__DOXYGEN__)
+#if (AMIROOS_CFG_SSSP_MASTER == true) || defined(__DOXYGEN__)
 
 /**
  * @brief   Converter function to encode a TM value to a single unsigned 64 bit integer.
@@ -209,6 +170,47 @@ inline uint64_t _TM2U64(struct tm* src)
 }
 
 /**
+ * @brief   Serializes 64 bit unsigned integer input and stores it in a byte array.
+ * @details Serialization is performed in big-endian fashion.
+ *
+ * @param[out]  dst   Pointer to the output buffer.
+ * @param[in]   src   Data to be serialized.
+ */
+inline void _serializeU64(uint8_t* dst, const uint64_t src)
+{
+  aosDbgCheck(dst != NULL);
+
+  for (uint8_t byte = 0; byte < sizeof(uint64_t); ++byte) {
+    dst[byte] = ((src >> ((sizeof(uint64_t) - (byte+1)) * 8)) & 0xFF);
+  }
+
+  return;
+}
+
+#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
+#if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__)
+
+/**
+ * @brief   Deserialize 64 bit unsigned integer data from a buffer.
+ * @details Data is assumed to be serialized in big-endian fashion.
+ *
+ * @param[in] src   Pointer to the buffer of data to be deserialzed.
+ *
+ * @return    Deserialized 64 bit data.
+ */
+inline uint64_t _deserializeU64(uint8_t* src)
+{
+  aosDbgCheck(src != NULL);
+
+  uint64_t result = 0;
+  for (uint8_t byte = 0; byte < sizeof(uint64_t); ++byte) {
+    result |= ((uint64_t)src[byte] << ((sizeof(uint64_t) - (byte+1)) * 8));
+  }
+
+  return result;
+}
+
+/**
  * @brief   Converter functiomn to retrieve the encoded TM value from an unsigned 64 bit integer.
  *
  * @details For information on the encoding, please refer to @p _TM2U64 function.
@@ -233,7 +235,8 @@ inline void _U642TM(struct tm* dst, const uint64_t src)
   return;
 }
 
-#endif /* (HAL_USE_RTC == TRUE) */
+#endif /* (AMIROOS_CFG_SSSP_MASTER != true) */
+#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_RTC == TRUE) */
 
 /**
  * @brief   Application entry point.
@@ -657,7 +660,58 @@ int main(void)
 
 #if (HAL_USE_RTC == TRUE)
 
-  //TODO: Calendar synchronization
+  /*
+   * calendar synchronization
+   *
+   * Although calendar synchronization does not inherently rely on SSSP, this
+   * implementation uses the moduleSsspBcbX() functions, defined by SSSP in
+   * order to save redundant code. Furthermore, it is rather unlikely that
+   * system wide synchronization of calendars is desired when SSSP is disabled
+   * anyway.
+   */
+ if (shutdown == AOS_SHUTDOWN_NONE) {
+#if (AMIROOS_CFG_SSSP_MASTER == true)
+   // temporary variables
+   struct tm t;
+   uint8_t buffer[sizeof(uint64_t)];
+
+   // get current date/time
+   aosSysGetDateTime(&t);
+   // encode & serialize
+   _serializeU64(buffer, _TM2U64(&t));
+   // transmit
+   aosDbgPrintf("transmitting current date/time...\t");
+   if (moduleSsspBcbTransmit(buffer, sizeof(uint64_t)) == AOS_SSSP_BCB_SUCCESS) {
+     aosDbgPrintf("ok\n");
+   } else {
+     aosDbgPrintf("fail\n");
+   }
+#else /* (AMIROOS_CFG_SSSP_MASTER == true) */
+   // temporary variables
+   aos_timestamp_t start, now;
+   aos_ssspbcbstatus_t bcbstatus;
+   uint8_t buffer[sizeof(uint64_t)];
+   struct tm t;
+
+   // receive
+   aosDbgPrintf("receiving current date/time...\t");
+   aosSysGetUptime(&start);
+   do {
+     bcbstatus = moduleSsspBcbReceive(buffer, sizeof(uint64_t));
+     aosSysGetUptime(&now);
+   } while ((bcbstatus != AOS_SSSP_BCB_SUCCESS) && ((now - start) < AOS_SSSP_TIMEOUT));
+   // if something was received
+   if (bcbstatus == AOS_SSSP_BCB_SUCCESS) {
+     // deserialize & decode
+     _U642TM(&t, _deserializeU64(buffer));
+     // set current date/time
+     aosSysSetDateTime(&t);
+     aosDbgPrintf("ok\n");
+   } else {
+     aosDbgPrintf("fail\n");
+   }
+#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
+ }
 
 #endif /* (HAL_USE_RTC == TRUE) */
 #endif /* (AMIROOS_CFG_SSSP_MSI == true) */
