1 #include "nlohmann/json.hpp"
2 #include "rde/external_storer_interface.hpp"
3 #include "rde/rde_handler.hpp"
4 
5 #include <memory>
6 #include <span>
7 
8 #include <gmock/gmock-matchers.h>
9 #include <gmock/gmock.h>
10 #include <gtest/gtest.h>
11 
12 namespace bios_bmc_smm_error_logger
13 {
14 namespace rde
15 {
16 
17 using ::testing::Return;
18 
19 /**
20  * @brief Dummy values for annotation dictionary. We do not need the annotation
21  * dictionary. So this contains a dictionary with some dummy values. But the RDE
22  * header is correct.
23  */
24 constexpr std::array<uint8_t, 38> mRcvDummyAnnotation{
25     {0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
26      0x0,  0x0,  0xc,  0x0,  0x0,  0xf0, 0xf0, 0xf1, 0x17, 0x1,
27      0x0,  0x0,  0x0,  0x0,  0x0,  0x16, 0x0,  0x5,  0x0,  0xc,
28      0x84, 0x0,  0x14, 0x0,  0x30, 0xa8, 0xc3, 0x3c}};
29 
30 constexpr std::array<uint8_t, 38> mRcvDummyInvalidChecksum{
31     {0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
32      0x0,  0x0,  0xc,  0x0,  0x0,  0xf0, 0xf0, 0xf1, 0x17, 0x1,
33      0x0,  0x0,  0x0,  0x0,  0x0,  0x16, 0x0,  0x5,  0x0,  0xc,
34      0x84, 0x0,  0x14, 0x0,  0x17, 0x86, 0x00, 0x00}};
35 
36 /**
37  * @brief MultipartReceive command with START_AND_END flag set.
38  */
39 constexpr std::array<uint8_t, 293> mRcvInput0StartAndEnd{
40     {0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x0,  0x0,
41      0xc,  0x0,  0x0,  0xf0, 0xf0, 0xf1, 0x17, 0x1,  0x0,  0x0,  0x0,  0x0,
42      0x0,  0x16, 0x0,  0x5,  0x0,  0xc,  0x84, 0x0,  0x14, 0x0,  0x0,  0x48,
43      0x0,  0x1,  0x0,  0x13, 0x90, 0x0,  0x56, 0x1,  0x0,  0x0,  0x0,  0x0,
44      0x0,  0x3,  0xa3, 0x0,  0x74, 0x2,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16,
45      0xa6, 0x0,  0x34, 0x3,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16, 0xbc, 0x0,
46      0x64, 0x4,  0x0,  0x0,  0x0,  0x0,  0x0,  0x13, 0xd2, 0x0,  0x0,  0x0,
47      0x0,  0x52, 0x0,  0x2,  0x0,  0x0,  0x0,  0x0,  0x74, 0x0,  0x0,  0x0,
48      0x0,  0x0,  0x0,  0xf,  0xe5, 0x0,  0x46, 0x1,  0x0,  0x66, 0x0,  0x3,
49      0x0,  0xb,  0xf4, 0x0,  0x50, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x9,
50      0xff, 0x0,  0x50, 0x1,  0x0,  0x0,  0x0,  0x0,  0x0,  0x7,  0x8,  0x1,
51      0x50, 0x2,  0x0,  0x0,  0x0,  0x0,  0x0,  0x7,  0xf,  0x1,  0x44, 0x75,
52      0x6d, 0x6d, 0x79, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x0,  0x43, 0x68,
53      0x69, 0x6c, 0x64, 0x41, 0x72, 0x72, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x70,
54      0x65, 0x72, 0x74, 0x79, 0x0,  0x49, 0x64, 0x0,  0x53, 0x61, 0x6d, 0x70,
55      0x6c, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x50, 0x72, 0x6f,
56      0x70, 0x65, 0x72, 0x74, 0x79, 0x0,  0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65,
57      0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65,
58      0x72, 0x74, 0x79, 0x0,  0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65,
59      0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0,  0x41,
60      0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61,
61      0x6e, 0x0,  0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
62      0x0,  0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x6f, 0x77, 0x6e, 0x0,  0x4c, 0x69,
63      0x6e, 0x6b, 0x55, 0x70, 0x0,  0x4e, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x0,
64      0x0,  0x8c, 0x87, 0xed, 0x74}};
65 
66 /**
67  * @brief MultipartReceive command with START flag set.
68  */
69 constexpr std::array<uint8_t, 166> mRcvInput1Start{
70     {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x0,  0x0,
71      0xc,  0x0,  0x0,  0xf0, 0xf0, 0xf1, 0x17, 0x1,  0x0,  0x0,  0x0,  0x0,
72      0x0,  0x16, 0x0,  0x5,  0x0,  0xc,  0x84, 0x0,  0x14, 0x0,  0x0,  0x48,
73      0x0,  0x1,  0x0,  0x13, 0x90, 0x0,  0x56, 0x1,  0x0,  0x0,  0x0,  0x0,
74      0x0,  0x3,  0xa3, 0x0,  0x74, 0x2,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16,
75      0xa6, 0x0,  0x34, 0x3,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16, 0xbc, 0x0,
76      0x64, 0x4,  0x0,  0x0,  0x0,  0x0,  0x0,  0x13, 0xd2, 0x0,  0x0,  0x0,
77      0x0,  0x52, 0x0,  0x2,  0x0,  0x0,  0x0,  0x0,  0x74, 0x0,  0x0,  0x0,
78      0x0,  0x0,  0x0,  0xf,  0xe5, 0x0,  0x46, 0x1,  0x0,  0x66, 0x0,  0x3,
79      0x0,  0xb,  0xf4, 0x0,  0x50, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x9,
80      0xff, 0x0,  0x50, 0x1,  0x0,  0x0,  0x0,  0x0,  0x0,  0x7,  0x8,  0x1,
81      0x50, 0x2,  0x0,  0x0,  0x0,  0x0,  0x0,  0x7,  0xf,  0x1,  0x44, 0x75,
82      0x6d, 0x6d, 0x79, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x0,  0x43, 0x68,
83      0x69, 0x6c, 0x64, 0x41, 0x72, 0x72, 0x61, 0x79, 0x50, 0x72}};
84 
85 /**
86  * @brief MultipartReceive command with END flag set.
87  */
88 constexpr std::array<uint8_t, 137> mRcvInput1End{
89     {0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x6f, 0x70,
90      0x65, 0x72, 0x74, 0x79, 0x0,  0x49, 0x64, 0x0,  0x53, 0x61, 0x6d, 0x70,
91      0x6c, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x50, 0x72, 0x6f,
92      0x70, 0x65, 0x72, 0x74, 0x79, 0x0,  0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65,
93      0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65,
94      0x72, 0x74, 0x79, 0x0,  0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65,
95      0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0,  0x41,
96      0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61,
97      0x6e, 0x0,  0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
98      0x0,  0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x6f, 0x77, 0x6e, 0x0,  0x4c, 0x69,
99      0x6e, 0x6b, 0x55, 0x70, 0x0,  0x4e, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x0,
100      0x0,  0x8c, 0x87, 0xed, 0x74}};
101 
102 /**
103  * @brief MultipartReceive command with START flag set.
104  */
105 constexpr std::array<uint8_t, 106> mRcvInput2Start{
106     {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x0,  0x00, 0x00, 0x0,  0x0,
107      0xc,  0x0,  0x0,  0xf0, 0xf0, 0xf1, 0x17, 0x1,  0x0,  0x0,  0x0,  0x0,
108      0x0,  0x16, 0x0,  0x5,  0x0,  0xc,  0x84, 0x0,  0x14, 0x0,  0x0,  0x48,
109      0x0,  0x1,  0x0,  0x13, 0x90, 0x0,  0x56, 0x1,  0x0,  0x0,  0x0,  0x0,
110      0x0,  0x3,  0xa3, 0x0,  0x74, 0x2,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16,
111      0xa6, 0x0,  0x34, 0x3,  0x0,  0x0,  0x0,  0x0,  0x0,  0x16, 0xbc, 0x0,
112      0x64, 0x4,  0x0,  0x0,  0x0,  0x0,  0x0,  0x13, 0xd2, 0x0,  0x0,  0x0,
113      0x0,  0x52, 0x0,  0x2,  0x0,  0x0,  0x0,  0x0,  0x74, 0x0,  0x0,  0x0,
114      0x0,  0x0,  0x0,  0xf,  0xe5, 0x0,  0x46, 0x1,  0x0,  0x66}};
115 
116 /**
117  * @brief MultipartReceive command with MIDDLE flag set.
118  */
119 constexpr std::array<uint8_t, 106> mRcvInput2Mid{
120     {0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x60, 0x0,  0x00, 0x00, 0x0,  0x3,
121      0x0,  0xb,  0xf4, 0x0,  0x50, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x9,
122      0xff, 0x0,  0x50, 0x1,  0x0,  0x0,  0x0,  0x0,  0x0,  0x7,  0x8,  0x1,
123      0x50, 0x2,  0x0,  0x0,  0x0,  0x0,  0x0,  0x7,  0xf,  0x1,  0x44, 0x75,
124      0x6d, 0x6d, 0x79, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x0,  0x43, 0x68,
125      0x69, 0x6c, 0x64, 0x41, 0x72, 0x72, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x70,
126      0x65, 0x72, 0x74, 0x79, 0x0,  0x49, 0x64, 0x0,  0x53, 0x61, 0x6d, 0x70,
127      0x6c, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x50, 0x72, 0x6f,
128      0x70, 0x65, 0x72, 0x74, 0x79, 0x0,  0x53, 0x61, 0x6d, 0x70}};
129 
130 /**
131  * @brief MultipartReceive command with END flag set.
132  */
133 constexpr std::array<uint8_t, 101> mRcvInput2End{
134     {0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x57, 0x0,  0x00, 0x00, 0x6c, 0x65,
135      0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65,
136      0x72, 0x74, 0x79, 0x0,  0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65,
137      0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0,  0x41,
138      0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61,
139      0x6e, 0x0,  0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
140      0x0,  0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x6f, 0x77, 0x6e, 0x0,  0x4c, 0x69,
141      0x6e, 0x6b, 0x55, 0x70, 0x0,  0x4e, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x0,
142      0x0,  0x8c, 0x87, 0xed, 0x74}};
143 
144 /**
145  * @brief RDEOperationInit command with encoded json/dummysimple.json as the
146  * payload.
147  */
148 constexpr std::array<uint8_t, 113> mInitOp{
149     {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00,
150      0x00, 0x60, 0x00, 0x00, 0x00, 0x0,  0xf0, 0xf0, 0xf1, 0x0,  0x0,  0x0,
151      0x1,  0x0,  0x0,  0x1,  0x54, 0x1,  0x5,  0x1,  0x2,  0x50, 0x1,  0x9,
152      0x44, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x49, 0x44, 0x0,  0x1,  0x6,  0x20,
153      0x1,  0x0,  0x1,  0x8,  0x60, 0x1,  0xb,  0x1,  0x2,  0x38, 0xea, 0x1,
154      0x0,  0x2,  0xa3, 0x23, 0x1,  0x0,  0x1,  0x4,  0x70, 0x1,  0x1,  0x0,
155      0x1,  0x0,  0x10, 0x1,  0x24, 0x1,  0x2,  0x1,  0x0,  0x0,  0x1,  0xf,
156      0x1,  0x2,  0x1,  0x0,  0x70, 0x1,  0x1,  0x1,  0x1,  0x2,  0x40, 0x1,
157      0x2,  0x1,  0x2,  0x1,  0x2,  0x0,  0x1,  0x9,  0x1,  0x1,  0x1,  0x2,
158      0x40, 0x1,  0x2,  0x1,  0x2}};
159 
160 class MockExternalStorer : public ExternalStorerInterface
161 {
162   public:
163     MOCK_METHOD(bool, publishJson, (std::string_view jsonStr), (override));
164 };
165 
166 class RdeHandlerTest : public ::testing::Test
167 {
168   public:
RdeHandlerTest()169     RdeHandlerTest() : mockExStorer(std::make_unique<MockExternalStorer>())
170     {
171         mockExStorerPtr = dynamic_cast<MockExternalStorer*>(mockExStorer.get());
172         rdeH = std::make_unique<RdeCommandHandler>(std::move(mockExStorer));
173     }
174 
175   protected:
176     std::unique_ptr<ExternalStorerInterface> mockExStorer;
177     std::unique_ptr<RdeCommandHandler> rdeH;
178     MockExternalStorer* mockExStorerPtr;
179     const std::string exJson =
180         R"({"Id":"Dummy ID","SampleIntegerProperty":null,"SampleRealProperty":-5576.9123,"SampleEnabledProperty":false,"ChildArrayProperty":[{"AnotherBoolean":true,"LinkStatus":"NoLink"},{"LinkStatus":"NoLink"}]})";
181 };
182 
TEST_F(RdeHandlerTest,DictionaryStartAndEndTest)183 TEST_F(RdeHandlerTest, DictionaryStartAndEndTest)
184 {
185     // Send a payload with START_AND_END flag.
186     EXPECT_THAT(
187         rdeH->decodeRdeCommand(std::span(mRcvInput0StartAndEnd),
188                                RdeCommandType::RdeMultiPartReceiveResponse),
189         RdeDecodeStatus::RdeStopFlagReceived);
190     EXPECT_THAT(rdeH->getDictionaryCount(), 1);
191     // Send annotation dictionary.
192     EXPECT_THAT(
193         rdeH->decodeRdeCommand(std::span(mRcvDummyAnnotation),
194                                RdeCommandType::RdeMultiPartReceiveResponse),
195         RdeDecodeStatus::RdeStopFlagReceived);
196     EXPECT_THAT(rdeH->getDictionaryCount(), 2);
197 
198     // Send the encoded payload.
199     EXPECT_CALL(*mockExStorerPtr, publishJson(exJson)).WillOnce(Return(true));
200     EXPECT_THAT(rdeH->decodeRdeCommand(std::span(mInitOp),
201                                        RdeCommandType::RdeOperationInitRequest),
202                 RdeDecodeStatus::RdeOk);
203 }
204 
TEST_F(RdeHandlerTest,DictionaryStartThenEndTest)205 TEST_F(RdeHandlerTest, DictionaryStartThenEndTest)
206 {
207     // Send a payload with START flag.
208     EXPECT_THAT(
209         rdeH->decodeRdeCommand(std::span(mRcvInput1Start),
210                                RdeCommandType::RdeMultiPartReceiveResponse),
211         RdeDecodeStatus::RdeOk);
212     // We didn't send END. So dictionary count should be 0.
213     EXPECT_THAT(rdeH->getDictionaryCount(), 0);
214     // Send a payload with END flag.
215     EXPECT_THAT(
216         rdeH->decodeRdeCommand(std::span(mRcvInput1End),
217                                RdeCommandType::RdeMultiPartReceiveResponse),
218         RdeDecodeStatus::RdeStopFlagReceived);
219     EXPECT_THAT(rdeH->getDictionaryCount(), 1);
220     // Send annotation dictionary.
221     EXPECT_THAT(
222         rdeH->decodeRdeCommand(std::span(mRcvDummyAnnotation),
223                                RdeCommandType::RdeMultiPartReceiveResponse),
224         RdeDecodeStatus::RdeStopFlagReceived);
225     EXPECT_THAT(rdeH->getDictionaryCount(), 2);
226 
227     // Send the encoded payload.
228     EXPECT_CALL(*mockExStorerPtr, publishJson(exJson)).WillOnce(Return(true));
229     EXPECT_THAT(rdeH->decodeRdeCommand(std::span(mInitOp),
230                                        RdeCommandType::RdeOperationInitRequest),
231                 RdeDecodeStatus::RdeOk);
232 
233     // Sending the START again for same resource ID should decrease the
234     // dictionary count.
235     EXPECT_THAT(
236         rdeH->decodeRdeCommand(std::span(mRcvInput1Start),
237                                RdeCommandType::RdeMultiPartReceiveResponse),
238         RdeDecodeStatus::RdeOk);
239     EXPECT_THAT(rdeH->getDictionaryCount(), 1);
240 }
241 
TEST_F(RdeHandlerTest,DictionaryStartMidEndTest)242 TEST_F(RdeHandlerTest, DictionaryStartMidEndTest)
243 {
244     // Send a payload with START flag.
245     EXPECT_THAT(
246         rdeH->decodeRdeCommand(std::span(mRcvInput2Start),
247                                RdeCommandType::RdeMultiPartReceiveResponse),
248         RdeDecodeStatus::RdeOk);
249     // We didn't send END. So dictionary count should be 0.
250     EXPECT_THAT(rdeH->getDictionaryCount(), 0);
251     // Send a payload with MIDDLE flag.
252     EXPECT_THAT(
253         rdeH->decodeRdeCommand(std::span(mRcvInput2Mid),
254                                RdeCommandType::RdeMultiPartReceiveResponse),
255         RdeDecodeStatus::RdeOk);
256     // We didn't send END. So dictionary count should be 0.
257     EXPECT_THAT(rdeH->getDictionaryCount(), 0);
258     // Send a payload with END flag.
259     EXPECT_THAT(
260         rdeH->decodeRdeCommand(std::span(mRcvInput2End),
261                                RdeCommandType::RdeMultiPartReceiveResponse),
262         RdeDecodeStatus::RdeStopFlagReceived);
263     EXPECT_THAT(rdeH->getDictionaryCount(), 1);
264 
265     // Send annotation dictionary.
266     EXPECT_THAT(
267         rdeH->decodeRdeCommand(std::span(mRcvDummyAnnotation),
268                                RdeCommandType::RdeMultiPartReceiveResponse),
269         RdeDecodeStatus::RdeStopFlagReceived);
270     EXPECT_THAT(rdeH->getDictionaryCount(), 2);
271 
272     // Send the encoded payload.
273     EXPECT_CALL(*mockExStorerPtr, publishJson(exJson)).WillOnce(Return(true));
274     EXPECT_THAT(rdeH->decodeRdeCommand(std::span(mInitOp),
275                                        RdeCommandType::RdeOperationInitRequest),
276                 RdeDecodeStatus::RdeOk);
277 }
278 
TEST_F(RdeHandlerTest,InvalidDictionaryFlowTest)279 TEST_F(RdeHandlerTest, InvalidDictionaryFlowTest)
280 {
281     // Send a payload with MIDDLE flag before START and it should fail.
282     EXPECT_THAT(
283         rdeH->decodeRdeCommand(std::span(mRcvInput2Mid),
284                                RdeCommandType::RdeMultiPartReceiveResponse),
285         RdeDecodeStatus::RdeInvalidPktOrder);
286     // Send a payload with END flag before START and it should fail.
287     EXPECT_THAT(
288         rdeH->decodeRdeCommand(std::span(mRcvInput2End),
289                                RdeCommandType::RdeMultiPartReceiveResponse),
290         RdeDecodeStatus::RdeInvalidPktOrder);
291 }
292 
TEST_F(RdeHandlerTest,MissingDictionaryTest)293 TEST_F(RdeHandlerTest, MissingDictionaryTest)
294 {
295     // Try decoding without any dictionaries.
296     EXPECT_THAT(rdeH->decodeRdeCommand(std::span(mInitOp),
297                                        RdeCommandType::RdeOperationInitRequest),
298                 RdeDecodeStatus::RdeNoDictionary);
299 
300     // Try decoding just with annotation dictionary.
301     EXPECT_THAT(
302         rdeH->decodeRdeCommand(std::span(mRcvDummyAnnotation),
303                                RdeCommandType::RdeMultiPartReceiveResponse),
304         RdeDecodeStatus::RdeStopFlagReceived);
305     EXPECT_THAT(rdeH->decodeRdeCommand(std::span(mInitOp),
306                                        RdeCommandType::RdeOperationInitRequest),
307                 RdeDecodeStatus::RdeNoDictionary);
308 }
309 
TEST_F(RdeHandlerTest,InvalidDictionaryChecksumTest)310 TEST_F(RdeHandlerTest, InvalidDictionaryChecksumTest)
311 {
312     // Send a dictionary with an invalid checksum.
313     EXPECT_THAT(
314         rdeH->decodeRdeCommand(std::span(mRcvDummyInvalidChecksum),
315                                RdeCommandType::RdeMultiPartReceiveResponse),
316         RdeDecodeStatus::RdeInvalidChecksum);
317 }
318 
319 } // namespace rde
320 } // namespace bios_bmc_smm_error_logger
321