blob: 2f8ea7dfe1a0fcbb8bd4b9adf67523580f869e14 [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 {
Manojkiran Edaef773052021-07-29 09:29:28 +053036 flightRecorderPolicy = FLIGHT_RECORDER_MAX_ENTRIES ? true : false;
37 if (flightRecorderPolicy)
38 {
39 tapeRecorder = FlightRecorderCassette(FLIGHT_RECORDER_MAX_ENTRIES);
40 }
41 }
42
43 protected:
44 int index;
45 FlightRecorderCassette tapeRecorder;
46 bool flightRecorderPolicy;
47
48 public:
49 FlightRecorder(const FlightRecorder&) = delete;
50 FlightRecorder(FlightRecorder&&) = delete;
51 FlightRecorder& operator=(const FlightRecorder&) = delete;
52 FlightRecorder& operator=(FlightRecorder&&) = delete;
53 ~FlightRecorder() = default;
54
55 static FlightRecorder& GetInstance()
56 {
57 static FlightRecorder flightRecorder;
58 return flightRecorder;
59 }
60
61 /** @brief Add records to the flightRecorder
62 *
63 * @param[in] buffer - The request/respose byte buffer
64 * @param[in] isRequest - bool that captures if it is a request message or
65 * a response message
66 *
67 * @return void
68 */
69 void saveRecord(const FlightRecorderData& buffer, ReqOrResponse isRequest)
70 {
71 // if the flight recorder policy is enabled, then only insert the
72 // messages into the flight recorder, if not this function will be just
73 // a no-op
74 if (flightRecorderPolicy)
75 {
76 int currentIndex = index++;
77 tapeRecorder[currentIndex] = std::make_tuple(
78 pldm::utils::getCurrentSystemTime(), isRequest, buffer);
79 index =
80 (currentIndex == FLIGHT_RECORDER_MAX_ENTRIES - 1) ? 0 : index;
81 }
82 }
83
84 /** @brief play flight recorder
85 *
86 * @return void
87 */
88
89 void playRecorder()
90 {
91 if (flightRecorderPolicy)
92 {
93 std::ofstream recorderOutputFile(flightRecorderDumpPath);
94 std::cout << "Dumping the flight recorder into : "
95 << flightRecorderDumpPath << "\n";
96
97 for (const auto& message : tapeRecorder)
98 {
99 recorderOutputFile << std::get<FlightRecorderTimeStamp>(message)
100 << " : ";
101 if (std::get<ReqOrResponse>(message))
102 {
103 recorderOutputFile << "Tx : \n";
104 }
105 else
106 {
107 recorderOutputFile << "Rx : \n";
108 }
109 for (const auto& word : std::get<FlightRecorderData>(message))
110 {
111 recorderOutputFile << std::setfill('0') << std::setw(2)
112 << std::hex << (unsigned)word << " ";
113 }
114 recorderOutputFile << std::endl;
115 }
116 recorderOutputFile.close();
117 }
118 else
119 {
120 std::cerr << "Fight recorder policy is disabled\n";
121 }
122 }
123};
124
125} // namespace flightrecorder
126} // namespace pldm