#pragma once #include #include #include #include #include #include PHOSPHOR_LOG2_USING; namespace pldm { namespace flightrecorder { using ReqOrResponse = bool; using FlightRecorderData = std::vector; using FlightRecorderTimeStamp = std::string; using FlightRecorderRecord = std::tuple; using FlightRecorderCassette = std::vector; static constexpr auto flightRecorderDumpPath = "/tmp/pldm_flight_recorder"; /** @class FlightRecorder * * The class for implementing the PLDM flight recorder logic. This class * handles the insertion of the data into the recorder and also provides * API's to dump the flight recorder into a file. */ class FlightRecorder { private: FlightRecorder() : index(0) { flightRecorderPolicy = FLIGHT_RECORDER_MAX_ENTRIES ? true : false; if (flightRecorderPolicy) { tapeRecorder = FlightRecorderCassette(FLIGHT_RECORDER_MAX_ENTRIES); } } protected: int index; FlightRecorderCassette tapeRecorder; bool flightRecorderPolicy; public: FlightRecorder(const FlightRecorder&) = delete; FlightRecorder(FlightRecorder&&) = delete; FlightRecorder& operator=(const FlightRecorder&) = delete; FlightRecorder& operator=(FlightRecorder&&) = delete; ~FlightRecorder() = default; static FlightRecorder& GetInstance() { static FlightRecorder flightRecorder; return flightRecorder; } /** @brief Add records to the flightRecorder * * @param[in] buffer - The request/response byte buffer * @param[in] isRequest - bool that captures if it is a request message or * a response message * * @return void */ void saveRecord(const FlightRecorderData& buffer, ReqOrResponse isRequest) { // if the flight recorder policy is enabled, then only insert the // messages into the flight recorder, if not this function will be just // a no-op if (flightRecorderPolicy) { int currentIndex = index++; tapeRecorder[currentIndex] = std::make_tuple( pldm::utils::getCurrentSystemTime(), isRequest, buffer); index = (currentIndex == FLIGHT_RECORDER_MAX_ENTRIES - 1) ? 0 : index; } } /** @brief play flight recorder * * @return void */ void playRecorder() { if (flightRecorderPolicy) { std::ofstream recorderOutputFile(flightRecorderDumpPath); info("Dumping the flight recorder into : {DUMP_PATH}", "DUMP_PATH", flightRecorderDumpPath); for (const auto& message : tapeRecorder) { recorderOutputFile << std::get(message) << " : "; if (std::get(message)) { recorderOutputFile << "Tx : \n"; } else { recorderOutputFile << "Rx : \n"; } for (const auto& word : std::get(message)) { recorderOutputFile << std::setfill('0') << std::setw(2) << std::hex << (unsigned)word << " "; } recorderOutputFile << std::endl; } recorderOutputFile.close(); } else { error("Fight recorder policy is disabled"); } } }; } // namespace flightrecorder } // namespace pldm