blob: fe6e906efb17ac9b5e4029da11f08fde75d0d935 [file] [log] [blame]
Manojkiran Edaef773052021-07-29 09:29:28 +05301#pragma once
2
Manojkiran Edaef773052021-07-29 09:29:28 +05303#include <common/utils.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -06004#include <phosphor-logging/lg2.hpp>
Manojkiran Edaef773052021-07-29 09:29:28 +05305
6#include <fstream>
7#include <iomanip>
8#include <iostream>
9#include <vector>
Riya Dixit49cfb132023-03-02 04:26:53 -060010
11PHOSPHOR_LOG2_USING;
12
Manojkiran Edaef773052021-07-29 09:29:28 +053013namespace pldm
14{
15namespace flightrecorder
16{
Manojkiran Edaef773052021-07-29 09:29:28 +053017using ReqOrResponse = bool;
18using FlightRecorderData = std::vector<uint8_t>;
19using FlightRecorderTimeStamp = std::string;
20using FlightRecorderRecord =
21 std::tuple<FlightRecorderTimeStamp, ReqOrResponse, FlightRecorderData>;
22using FlightRecorderCassette = std::vector<FlightRecorderRecord>;
23static constexpr auto flightRecorderDumpPath = "/tmp/pldm_flight_recorder";
24
25/** @class FlightRecorder
26 *
27 * The class for implementing the PLDM flight recorder logic. This class
28 * handles the insertion of the data into the recorder and also provides
29 * API's to dump the flight recorder into a file.
30 */
31
32class FlightRecorder
33{
34 private:
35 FlightRecorder() : index(0)
36 {
Manojkiran Edaef773052021-07-29 09:29:28 +053037 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);
Patrick Williams6da4f912023-05-10 07:50:53 -050080 index = (currentIndex == FLIGHT_RECORDER_MAX_ENTRIES - 1) ? 0
81 : index;
Manojkiran Edaef773052021-07-29 09:29:28 +053082 }
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);
Riya Dixit49cfb132023-03-02 04:26:53 -060095 info("Dumping the flight recorder into : {DUMP_PATH}", "DUMP_PATH",
96 flightRecorderDumpPath);
Manojkiran Edaef773052021-07-29 09:29:28 +053097 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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600120 error("Fight recorder policy is disabled");
Manojkiran Edaef773052021-07-29 09:29:28 +0530121 }
122 }
123};
124
125} // namespace flightrecorder
126} // namespace pldm