1 #pragma once
2 #include "stream.hpp"
3
4 #include <chrono>
5
6 namespace openpower
7 {
8 namespace pels
9 {
10
11 /**
12 * @brief A structure that contains a PEL timestamp in BCD.
13 */
14 struct BCDTime
15 {
16 uint8_t yearMSB;
17 uint8_t yearLSB;
18 uint8_t month;
19 uint8_t day;
20 uint8_t hour;
21 uint8_t minutes;
22 uint8_t seconds;
23 uint8_t hundredths;
24
BCDTimeopenpower::pels::BCDTime25 BCDTime() :
26 yearMSB(0), yearLSB(0), month(0), day(0), hour(0), minutes(0),
27 seconds(0), hundredths(0)
28 {}
29
BCDTimeopenpower::pels::BCDTime30 BCDTime(uint8_t yearMSB, uint8_t yearLSB, uint8_t month, uint8_t day,
31 uint8_t hour, uint8_t minutes, uint8_t seconds,
32 uint8_t hundredths) :
33 yearMSB(yearMSB),
34 yearLSB(yearLSB), month(month), day(day), hour(hour), minutes(minutes),
35 seconds(seconds), hundredths(hundredths)
36 {}
37
38 bool operator==(const BCDTime& right) const;
39 bool operator!=(const BCDTime& right) const;
40
41 } __attribute__((packed));
42
43 /**
44 * @brief Converts a time_point into a BCD time
45 *
46 * @param[in] time - the time_point to convert
47 * @return BCDTime - the BCD time
48 */
49 BCDTime getBCDTime(std::chrono::time_point<std::chrono::system_clock>& time);
50
51 /**
52 * @brief Converts the number of milliseconds since the epoch into BCD time
53 *
54 * @param[in] milliseconds - Number of milliseconds since the epoch
55 * @return BCDTime - the BCD time
56 */
57 BCDTime getBCDTime(uint64_t milliseconds);
58
59 /**
60 * @brief Convert a BCDTime value into the number of
61 * milliseconds since the epoch (1/1/1970).
62 *
63 * @param[in] bcdTime - The BCD time value
64 * @return uint64_t - The milliseconds value
65 */
66 uint64_t getMillisecondsSinceEpoch(const BCDTime& bcdTime);
67
68 /**
69 * @brief Converts a number to a BCD.
70 *
71 * For example 32 -> 0x32.
72 *
73 * Source: PLDM repository
74 *
75 * @param[in] value - the value to convert.
76 *
77 * @return T - the BCD value
78 */
79 template <typename T>
toBCD(T decimal)80 T toBCD(T decimal)
81 {
82 T bcd = 0;
83 T remainder = 0;
84 auto count = 0;
85
86 while (decimal)
87 {
88 remainder = decimal % 10;
89 bcd = bcd + (remainder << count);
90 decimal = decimal / 10;
91 count += 4;
92 }
93
94 return bcd;
95 }
96
97 /**
98 * @brief Converts a BCD byte to a decimal number.
99 *
100 * For example 0x22 -> 22.
101 *
102 * @param[in] bcd - The value in BCD
103 * @return int - The number in decimal
104 */
fromBCD(uint8_t bcd)105 inline int fromBCD(uint8_t bcd)
106 {
107 return (((bcd & 0xF0) >> 4) * 10) + (bcd & 0xF);
108 }
109
110 /**
111 * @brief Stream extraction operator for BCDTime
112 *
113 * @param[in] s - the Stream
114 * @param[out] time - the BCD time
115 *
116 * @return Stream&
117 */
118 Stream& operator>>(Stream& s, BCDTime& time);
119
120 /**
121 * @brief Stream insertion operator for BCDTime
122 *
123 * @param[in/out] s - the Stream
124 * @param[in] time - the BCD time
125 *
126 * @return Stream&
127 */
128 Stream& operator<<(Stream& s, const BCDTime& time);
129
130 } // namespace pels
131 } // namespace openpower
132