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