blob: eb1a3682f8bb9f145f5b29af9e719f0143183de5 [file] [log] [blame]
Matt Spinlercb6b0592019-07-16 15:58:51 -05001#include "pel.hpp"
2
3#include "bcd_time.hpp"
4#include "log_id.hpp"
Matt Spinler131870c2019-09-25 13:29:04 -05005#include "section_factory.hpp"
Matt Spinlercb6b0592019-07-16 15:58:51 -05006#include "stream.hpp"
7
Matt Spinler07eefc52019-09-26 11:18:26 -05008#include <phosphor-logging/log.hpp>
9
Matt Spinlercb6b0592019-07-16 15:58:51 -050010namespace openpower
11{
12namespace pels
13{
Matt Spinlerb8323632019-09-20 15:11:04 -050014namespace message = openpower::pels::message;
15
16PEL::PEL(const message::Entry& entry, uint32_t obmcLogID, uint64_t timestamp,
17 phosphor::logging::Entry::Level severity)
18{
19 _ph = std::make_unique<PrivateHeader>(entry.componentID, obmcLogID,
20 timestamp);
21 _uh = std::make_unique<UserHeader>(entry, severity);
22
23 // Add future sections here and update the count
24
25 _ph->sectionCount() = 2;
26}
Matt Spinlercb6b0592019-07-16 15:58:51 -050027
Matt Spinler07eefc52019-09-26 11:18:26 -050028PEL::PEL(std::vector<uint8_t>& data) : PEL(data, 0)
Matt Spinlercb6b0592019-07-16 15:58:51 -050029{
30}
31
Matt Spinler07eefc52019-09-26 11:18:26 -050032PEL::PEL(std::vector<uint8_t>& data, uint32_t obmcLogID)
Matt Spinlercb6b0592019-07-16 15:58:51 -050033{
Matt Spinler07eefc52019-09-26 11:18:26 -050034 populateFromRawData(data, obmcLogID);
Matt Spinlercb6b0592019-07-16 15:58:51 -050035}
36
Matt Spinler07eefc52019-09-26 11:18:26 -050037void PEL::populateFromRawData(std::vector<uint8_t>& data, uint32_t obmcLogID)
Matt Spinlercb6b0592019-07-16 15:58:51 -050038{
Matt Spinler07eefc52019-09-26 11:18:26 -050039 Stream pelData{data};
Matt Spinlercb6b0592019-07-16 15:58:51 -050040 _ph = std::make_unique<PrivateHeader>(pelData);
41 if (obmcLogID != 0)
42 {
43 _ph->obmcLogID() = obmcLogID;
44 }
45
46 _uh = std::make_unique<UserHeader>(pelData);
Matt Spinler131870c2019-09-25 13:29:04 -050047
48 // Use the section factory to create the rest of the objects
49 for (size_t i = 2; i < _ph->sectionCount(); i++)
50 {
51 auto section = section_factory::create(pelData);
52 _optionalSections.push_back(std::move(section));
53 }
Matt Spinlercb6b0592019-07-16 15:58:51 -050054}
55
56bool PEL::valid() const
57{
58 bool valid = _ph->valid();
59
60 if (valid)
61 {
62 valid = _uh->valid();
63 }
64
Matt Spinler131870c2019-09-25 13:29:04 -050065 if (valid)
66 {
67 if (!std::all_of(_optionalSections.begin(), _optionalSections.end(),
68 [](const auto& section) { return section->valid(); }))
69 {
70 valid = false;
71 }
72 }
73
Matt Spinlercb6b0592019-07-16 15:58:51 -050074 return valid;
75}
76
77void PEL::setCommitTime()
78{
79 auto now = std::chrono::system_clock::now();
80 _ph->commitTimestamp() = getBCDTime(now);
81}
82
83void PEL::assignID()
84{
85 _ph->id() = generatePELID();
86}
87
88void PEL::flatten(std::vector<uint8_t>& pelBuffer)
89{
90 Stream pelData{pelBuffer};
Matt Spinlerb8323632019-09-20 15:11:04 -050091
Matt Spinler07eefc52019-09-26 11:18:26 -050092 if (!valid())
Matt Spinlercb6b0592019-07-16 15:58:51 -050093 {
Matt Spinler07eefc52019-09-26 11:18:26 -050094 using namespace phosphor::logging;
95 log<level::WARNING>("Unflattening an invalid PEL");
Matt Spinlercb6b0592019-07-16 15:58:51 -050096 }
97
Matt Spinler07eefc52019-09-26 11:18:26 -050098 _ph->flatten(pelData);
Matt Spinlerb8323632019-09-20 15:11:04 -050099 _uh->flatten(pelData);
Matt Spinler07eefc52019-09-26 11:18:26 -0500100
101 for (auto& section : _optionalSections)
102 {
103 section->flatten(pelData);
104 }
Matt Spinlercb6b0592019-07-16 15:58:51 -0500105}
106
107std::vector<uint8_t> PEL::data()
108{
Matt Spinler07eefc52019-09-26 11:18:26 -0500109 std::vector<uint8_t> pelData;
110 flatten(pelData);
111 return pelData;
Matt Spinlercb6b0592019-07-16 15:58:51 -0500112}
113
114} // namespace pels
115} // namespace openpower