blob: db6314d00c091b6dc259597f991a8fc15dc711fa [file] [log] [blame]
Manojkiran Edaef773052021-07-29 09:29:28 +05301#pragma once
2
3#include <config.h>
4
5#include <common/utils.hpp>
6
7#include <fstream>
8#include <iomanip>
9#include <iostream>
10#include <vector>
11namespace pldm
12{
13namespace flightrecorder
14{
15
16using ReqOrResponse = bool;
17using FlightRecorderData = std::vector<uint8_t>;
18using FlightRecorderTimeStamp = std::string;
19using FlightRecorderRecord =
20 std::tuple<FlightRecorderTimeStamp, ReqOrResponse, FlightRecorderData>;
21using FlightRecorderCassette = std::vector<FlightRecorderRecord>;
22static constexpr auto flightRecorderDumpPath = "/tmp/pldm_flight_recorder";
23
24/** @class FlightRecorder
25 *
26 * The class for implementing the PLDM flight recorder logic. This class
27 * handles the insertion of the data into the recorder and also provides
28 * API's to dump the flight recorder into a file.
29 */
30
31class FlightRecorder
32{
33 private:
34 FlightRecorder() : index(0)
35 {
36
37 flightRecorderPolicy = FLIGHT_RECORDER_MAX_ENTRIES ? true : false;
38 if (flightRecorderPolicy)
39 {
40 tapeRecorder = FlightRecorderCassette(FLIGHT_RECORDER_MAX_ENTRIES);
41 }
42 }
43
44 protected:
45 int index;
46 FlightRecorderCassette tapeRecorder;
47 bool flightRecorderPolicy;
48
49 public:
50 FlightRecorder(const FlightRecorder&) = delete;
51 FlightRecorder(FlightRecorder&&) = delete;
52 FlightRecorder& operator=(const FlightRecorder&) = delete;
53 FlightRecorder& operator=(FlightRecorder&&) = delete;
54 ~FlightRecorder() = default;
55
56 static FlightRecorder& GetInstance()
57 {
58 static FlightRecorder flightRecorder;
59 return flightRecorder;
60 }
61
62 /** @brief Add records to the flightRecorder
63 *
64 * @param[in] buffer - The request/respose byte buffer
65 * @param[in] isRequest - bool that captures if it is a request message or
66 * a response message
67 *
68 * @return void
69 */
70 void saveRecord(const FlightRecorderData& buffer, ReqOrResponse isRequest)
71 {
72 // if the flight recorder policy is enabled, then only insert the
73 // messages into the flight recorder, if not this function will be just
74 // a no-op
75 if (flightRecorderPolicy)
76 {
77 int currentIndex = index++;
78 tapeRecorder[currentIndex] = std::make_tuple(
79 pldm::utils::getCurrentSystemTime(), isRequest, buffer);
80 index =
81 (currentIndex == FLIGHT_RECORDER_MAX_ENTRIES - 1) ? 0 : index;
82 }
83 }
84
85 /** @brief play flight recorder
86 *
87 * @return void
88 */
89
90 void playRecorder()
91 {
92 if (flightRecorderPolicy)
93 {
94 std::ofstream recorderOutputFile(flightRecorderDumpPath);
95 std::cout << "Dumping the flight recorder into : "
96 << flightRecorderDumpPath << "\n";
97
98 for (const auto& message : tapeRecorder)
99 {
100 recorderOutputFile << std::get<FlightRecorderTimeStamp>(message)
101 << " : ";
102 if (std::get<ReqOrResponse>(message))
103 {
104 recorderOutputFile << "Tx : \n";
105 }
106 else
107 {
108 recorderOutputFile << "Rx : \n";
109 }
110 for (const auto& word : std::get<FlightRecorderData>(message))
111 {
112 recorderOutputFile << std::setfill('0') << std::setw(2)
113 << std::hex << (unsigned)word << " ";
114 }
115 recorderOutputFile << std::endl;
116 }
117 recorderOutputFile.close();
118 }
119 else
120 {
121 std::cerr << "Fight recorder policy is disabled\n";
122 }
123 }
124};
125
126} // namespace flightrecorder
127} // namespace pldm