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