Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#include "session_logger.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <date/date.h>
|
||||
|
||||
#include <iso15118/session/logger.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
using LogEvent = iso15118::session::logging::Event;
|
||||
|
||||
std::string get_filename_for_current_time() {
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
const auto now_t = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::tm now_tm;
|
||||
gmtime_r(&now_t, &now_tm);
|
||||
|
||||
char buffer[64];
|
||||
strftime(buffer, sizeof(buffer), "%y%m%d_%H-%M-%S.yaml", &now_tm);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// static auto timepoint_to_string(const iso15118::session::logging::TimePoint& timepoint) {
|
||||
// using namespace date;
|
||||
// return static_cast<std::string>(timepoint);
|
||||
// }
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const iso15118::session::logging::ExiMessageDirection& direction) {
|
||||
using Direction = iso15118::session::logging::ExiMessageDirection;
|
||||
switch (direction) {
|
||||
case Direction::FROM_EV:
|
||||
return os << "FROM_EV";
|
||||
case Direction::TO_EV:
|
||||
return os << "TO_EV";
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
class SessionLog {
|
||||
public:
|
||||
SessionLog(const std::string& file_name) : file(file_name.c_str(), std::ios::out) {
|
||||
if (not file.good()) {
|
||||
throw std::runtime_error("Failed to open file " + file_name + " for writing iso15118 session log");
|
||||
}
|
||||
|
||||
EVLOG_info << "Created logfile at: " << file_name;
|
||||
}
|
||||
void operator()(const iso15118::session::logging::SimpleEvent& event) {
|
||||
file << "- type: INFO\n";
|
||||
add_timestamp(event.time_point);
|
||||
file << " info: \"" << event.info << "\"\n";
|
||||
}
|
||||
|
||||
void operator()(const iso15118::session::logging::ExiMessageEvent& event) {
|
||||
file << "- type: EXI\n";
|
||||
add_timestamp(event.time_point);
|
||||
file << " direction: " << event.direction << "\n";
|
||||
file << " sdp_payload_type: " << event.payload_type << "\n";
|
||||
add_hex_encoded_data(event.data, event.len);
|
||||
}
|
||||
|
||||
void flush() {
|
||||
file.flush();
|
||||
}
|
||||
|
||||
private:
|
||||
std::fstream file;
|
||||
|
||||
void add_timestamp(const iso15118::session::logging::TimePoint& timestamp) {
|
||||
if (not timestamp_initialized) {
|
||||
last_timestamp = timestamp;
|
||||
timestamp_initialized = true;
|
||||
}
|
||||
|
||||
const auto offset_ms = std::chrono::duration_cast<std::chrono::milliseconds>(timestamp - last_timestamp);
|
||||
file << " timestamp_offset: " << offset_ms.count() << "\n";
|
||||
|
||||
const auto dp = date::floor<date::days>(timestamp);
|
||||
const auto time = date::make_time(timestamp - dp);
|
||||
const auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(time.subseconds());
|
||||
file << " timestamp: \"";
|
||||
file << std::setfill('0') << std::setw(2) << time.hours().count() << ":";
|
||||
file << std::setfill('0') << std::setw(2) << time.minutes().count() << ":";
|
||||
file << std::setfill('0') << std::setw(2) << time.seconds().count() << ".";
|
||||
file << std::setfill('0') << std::setw(4) << milliseconds.count();
|
||||
file << "\"\n";
|
||||
|
||||
last_timestamp = timestamp;
|
||||
}
|
||||
|
||||
void add_hex_encoded_data(const uint8_t* data, size_t len) {
|
||||
file << " data: \"";
|
||||
|
||||
const auto flags = file.flags();
|
||||
|
||||
file << std::hex;
|
||||
|
||||
for (int i = 0; i < len; ++i) {
|
||||
file << std::setfill('0') << std::setw(2) << static_cast<int>(data[i]);
|
||||
}
|
||||
|
||||
file.flags(flags);
|
||||
file << "\"\n";
|
||||
}
|
||||
|
||||
iso15118::session::logging::TimePoint last_timestamp;
|
||||
bool timestamp_initialized{false};
|
||||
};
|
||||
|
||||
SessionLogger::SessionLogger(std::filesystem::path output_dir_) : output_dir(std::filesystem::absolute(output_dir_)) {
|
||||
// FIXME (aw): this is quite brute force ...
|
||||
if (not std::filesystem::exists(output_dir)) {
|
||||
std::filesystem::create_directory(output_dir);
|
||||
}
|
||||
|
||||
iso15118::session::logging::set_session_log_callback([this](std::uintptr_t id, const LogEvent& event) {
|
||||
auto log_it = logs.find(id);
|
||||
if (log_it == logs.end()) {
|
||||
const auto log_file_name = output_dir / get_filename_for_current_time();
|
||||
const auto emplaced = logs.emplace(id, std::make_unique<SessionLog>(log_file_name.string()));
|
||||
|
||||
log_it = emplaced.first;
|
||||
}
|
||||
|
||||
auto& log = *log_it->second;
|
||||
|
||||
std::visit(log, event);
|
||||
log.flush();
|
||||
});
|
||||
}
|
||||
|
||||
SessionLogger::~SessionLogger() = default;
|
||||
Reference in New Issue
Block a user