//--------------------------------------------------------------------------- // // SCSI Target Emulator PiSCSI // for Raspberry Pi // // Powered by XM6 TypeG Technology. // Copyright (C) 2016-2020 GIMONS // Copyright (C) 2021-2022 akuker // //--------------------------------------------------------------------------- #include "shared/log.h" #include "shared/piscsi_version.h" #include "sm_reports.h" #include #include using namespace std; const static string html_header = R"( )"; static void print_copyright_info(ofstream& html_fp) { html_fp << "" << endl \ << "

PiSCSI scsimon Capture Tool

" << endl \ << "
Version " << piscsi_get_version_string() \
            << __DATE__ << " " << __TIME__ << endl \
            << "Copyright (C) 2016-2020 GIMONS" << endl \
            << "Copyright (C) 2020-2021 Contributors to the PiSCSI project" << endl \
            << "
" << endl \ << "
" << endl; } static const string html_footer = R"( )"; static void print_html_data(ofstream& html_fp, const vector> &data_capture_array) { shared_ptr data; bool prev_data_valid = false; bool curr_data_valid; uint32_t selected_id = 0; phase_t prev_phase = phase_t::busfree; bool close_row = false; int data_space_count = 0; bool collapsible_div_active = false; bool button_active = false; html_fp << "" << endl; for (auto data: data_capture_array) { curr_data_valid = data->GetACK() && data->GetREQ(); phase_t phase = data->GetPhase(); if (phase == phase_t::selection && !data->GetBSY()) { selected_id = data->GetDAT(); } if (prev_phase != phase) { if (close_row) { if (collapsible_div_active) { html_fp << ""; } else if (button_active) { html_fp << ""; } html_fp << ""; if (data_space_count < 1) { html_fp << ""; } else { html_fp << ""; } html_fp << "" << endl; data_space_count = 0; } html_fp << ""; close_row = true; // Close the row the next time around html_fp << ""; html_fp << ""; html_fp << ""; html_fp << "
--wc: " << std::dec << "(0x" << std::hex << data_space_count << ")
" << (double)data->GetTimestamp() / 100000 << "" << data->GetPhaseStr() << "" << std::hex << selected_id << ""; } if (curr_data_valid && !prev_data_valid) { if (data_space_count == 0) { button_active = true; html_fp << "
" << endl; collapsible_div_active = true; button_active = false; } if (((data_space_count % 16) == 0) && (data_space_count > 17)) { html_fp << "
" << endl; } } prev_data_valid = curr_data_valid; prev_phase = phase; } } void scsimon_generate_html(const string &filename, const vector> &data_capture_array) { LOGINFO("Creating HTML report file (%s)", filename.c_str()) ofstream html_ofstream; html_ofstream.open(filename.c_str(), ios::out); html_ofstream << html_header; print_copyright_info(html_ofstream); print_html_data(html_ofstream, data_capture_array); html_ofstream << html_footer; html_ofstream.close(); }