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

RaSCSI scsimon Capture Tool

" << endl \ << "
Version " << rascsi_get_version_string() \
            << __DATE__ << " " << __TIME__ << endl \
            << "Copyright (C) 2016-2020 GIMONS" << endl \
            << "Copyright (C) 2020-2021 Contributors to the RaSCSI project" << endl \
            << "
" << endl \ << "
" << endl; } static const string html_footer = R"( )"; static void print_html_data(ofstream& html_fp, const data_capture *data_capture_array, DWORD capture_count) { const data_capture *data; bool prev_data_valid = false; bool curr_data_valid; DWORD selected_id = 0; BUS::phase_t prev_phase = BUS::busfree; bool close_row = false; int data_space_count = 0; bool collapsible_div_active = false; bool button_active = false; html_fp << "" << endl; for (DWORD idx = 0; idx < capture_count; idx++) { data = &data_capture_array[idx]; curr_data_valid = GetAck(data) && GetReq(data); BUS::phase_t phase = GetPhase(data); if (phase == BUS::selection && !GetBsy(data)) { selected_id = GetData(data); } 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->timestamp / 100000 << "" << GetPhaseStr(data) << "" << 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 char *filename, const data_capture *data_capture_array, DWORD capture_count) { LOGINFO("Creating HTML report file (%s)", filename); ofstream html_ofstream; html_ofstream.open(filename, ios::out); html_ofstream << html_header; print_copyright_info(html_ofstream); print_html_data(html_ofstream, data_capture_array, capture_count); html_ofstream << html_footer; html_ofstream.close(); }