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