1*b65280ffSSui Chenconst { spawnSync } = require('child_process'); 2*b65280ffSSui Chenconst md5File = require('md5-file'); 3*b65280ffSSui Chenconst https = require('https'); 4*b65280ffSSui Chen 5*b65280ffSSui Chenfunction OpenFileHandler() { 6*b65280ffSSui Chen console.log('Will open a dialog box ...'); 7*b65280ffSSui Chen const options = { 8*b65280ffSSui Chen title: 'Open a file or folder', 9*b65280ffSSui Chen }; 10*b65280ffSSui Chen let x = dialog.showOpenDialogSync(options) + ''; // Convert to string 11*b65280ffSSui Chen console.log('file name: ' + x) 12*b65280ffSSui Chen 13*b65280ffSSui Chen // Determine file type 14*b65280ffSSui Chen let is_asio_log = false; 15*b65280ffSSui Chen const data = fs.readFileSync(x, {encoding: 'utf-8'}); 16*b65280ffSSui Chen let lines = data.split('\n'); 17*b65280ffSSui Chen for (let i = 0; i < lines.length; i++) { 18*b65280ffSSui Chen if (lines[i].indexOf('@asio') == 0) { 19*b65280ffSSui Chen is_asio_log = true; 20*b65280ffSSui Chen break; 21*b65280ffSSui Chen } 22*b65280ffSSui Chen } 23*b65280ffSSui Chen 24*b65280ffSSui Chen if (is_asio_log) { 25*b65280ffSSui Chen ShowBlocker('Loading Boost ASIO handler tracking log'); 26*b65280ffSSui Chen console.log('This file is a Boost Asio handler tracking log'); 27*b65280ffSSui Chen ParseBoostHandlerTimeline(data); 28*b65280ffSSui Chen OnGroupByConditionChanged_ASIO(); 29*b65280ffSSui Chen if (boost_asio_handler_timeline_view.IsEmpty() == false) { 30*b65280ffSSui Chen boost_asio_handler_timeline_view.CurrentFileName = x; 31*b65280ffSSui Chen HideWelcomeScreen(); 32*b65280ffSSui Chen ShowASIOTimeline(); 33*b65280ffSSui Chen ShowNavigation(); 34*b65280ffSSui Chen UpdateFileNamesString(); 35*b65280ffSSui Chen } 36*b65280ffSSui Chen HideBlocker(); 37*b65280ffSSui Chen return; 38*b65280ffSSui Chen } 39*b65280ffSSui Chen 40*b65280ffSSui Chen OpenDBusPcapFile(x); 41*b65280ffSSui Chen 42*b65280ffSSui Chen UpdateLayout(); 43*b65280ffSSui Chen} 44*b65280ffSSui Chen 45*b65280ffSSui Chen// The file may be either DBus dump or Boost Asio handler log 46*b65280ffSSui Chendocument.getElementById('btn_open_file') 47*b65280ffSSui Chen .addEventListener('click', OpenFileHandler); 48*b65280ffSSui Chendocument.getElementById('btn_open_file2') 49*b65280ffSSui Chen .addEventListener('click', OpenFileHandler); 50*b65280ffSSui Chen 51*b65280ffSSui Chendocument.getElementById('bah1').addEventListener( 52*b65280ffSSui Chen 'click', OnGroupByConditionChanged_ASIO); 53*b65280ffSSui Chendocument.getElementById('bah2').addEventListener( 54*b65280ffSSui Chen 'click', OnGroupByConditionChanged_ASIO); 55*b65280ffSSui Chendocument.getElementById('bah3').addEventListener( 56*b65280ffSSui Chen 'click', OnGroupByConditionChanged_ASIO); 57*b65280ffSSui Chen 58*b65280ffSSui Chen// UI elements 59*b65280ffSSui Chenvar g_group_by_dbus = document.getElementById('span_group_by_dbus'); 60*b65280ffSSui Chenvar g_group_by_ipmi = document.getElementById('span_group_by_ipmi'); 61*b65280ffSSui Chenvar g_group_by_asio = 62*b65280ffSSui Chen document.getElementById('span_group_by_boost_asio_handler') 63*b65280ffSSui Chenvar g_canvas_ipmi = document.getElementById('my_canvas_ipmi'); 64*b65280ffSSui Chenvar g_canvas_dbus = document.getElementById('my_canvas_dbus'); 65*b65280ffSSui Chenvar g_canvas_asio = document.getElementById('my_canvas_boost_asio_handler'); 66*b65280ffSSui Chen 67*b65280ffSSui Chenvar g_dbus_pcap_status_content = document.getElementById('dbus_pcap_status_content'); 68*b65280ffSSui Chenvar g_dbus_pcap_error_content = document.getElementById('dbus_pcap_error_content'); 69*b65280ffSSui Chenvar g_btn_download_dbus_pcap = document.getElementById('btn_download_dbus_pcap'); 70*b65280ffSSui Chenvar g_welcome_screen_content = document.getElementById('welcome_screen_content'); 71*b65280ffSSui Chenvar g_scapy_error_content = document.getElementById('scapy_error_content'); 72*b65280ffSSui Chen 73*b65280ffSSui Chenvar g_btn_zoom_reset = document.getElementById('btn_zoom_reset'); 74*b65280ffSSui Chen 75*b65280ffSSui Chenfunction DownloadDbusPcap() { 76*b65280ffSSui Chen const url = 'https://raw.githubusercontent.com/openbmc/openbmc-tools/08ce0a5bad2b5c970af567c2e9888d444afe3946/dbus-pcap/dbus-pcap'; 77*b65280ffSSui Chen 78*b65280ffSSui Chen https.get(url, (res) => { 79*b65280ffSSui Chen const path = 'dbus-pcap'; 80*b65280ffSSui Chen const file_path = fs.createWriteStream(path); 81*b65280ffSSui Chen res.pipe(file_path); 82*b65280ffSSui Chen file_path.on('finish', () => { 83*b65280ffSSui Chen file_path.close(); 84*b65280ffSSui Chen alert("dbus-pcap download complete!"); 85*b65280ffSSui Chen CheckDbusPcapPresence(); 86*b65280ffSSui Chen }); 87*b65280ffSSui Chen }); 88*b65280ffSSui Chen} 89*b65280ffSSui Chen 90*b65280ffSSui Cheng_btn_download_dbus_pcap.addEventListener( 91*b65280ffSSui Chen 'click', DownloadDbusPcap); 92*b65280ffSSui Chen 93*b65280ffSSui Chenfunction ShowDBusTimeline() { 94*b65280ffSSui Chen g_canvas_dbus.style.display = 'block'; 95*b65280ffSSui Chen g_group_by_dbus.style.display = 'block'; 96*b65280ffSSui Chen} 97*b65280ffSSui Chenfunction ShowIPMITimeline() { 98*b65280ffSSui Chen g_canvas_ipmi.style.display = 'block'; 99*b65280ffSSui Chen g_group_by_ipmi.style.display = 'block'; 100*b65280ffSSui Chen} 101*b65280ffSSui Chenfunction ShowASIOTimeline() { 102*b65280ffSSui Chen g_canvas_asio.style.display = 'block'; 103*b65280ffSSui Chen g_group_by_asio.style.display = 'block'; 104*b65280ffSSui Chen} 105*b65280ffSSui Chen 106*b65280ffSSui Chen// Make sure the user has scapy.all installed 107*b65280ffSSui Chenfunction IsPythonInstallationOK() { 108*b65280ffSSui Chen const x = spawnSync('python3', ['-m', 'scapy.all']); 109*b65280ffSSui Chen return (x.status == 0); 110*b65280ffSSui Chen} 111*b65280ffSSui Chen 112*b65280ffSSui Chenfunction IsDbusPcapPresent() { 113*b65280ffSSui Chen // This should exist if the openbmc-tools repository 114*b65280ffSSui Chen // is checked out as a whole 115*b65280ffSSui Chen const dbus_pcap = '../dbus-pcap/dbus-pcap'; 116*b65280ffSSui Chen 117*b65280ffSSui Chen if (fs.existsSync('dbus-pcap')) { 118*b65280ffSSui Chen return true; 119*b65280ffSSui Chen } else if (fs.existsSync(dbus_pcap)) { // Create symlink 120*b65280ffSSui Chen fs.symlinkSync(dbus_pcap, './dbus-pcap'); 121*b65280ffSSui Chen return true; 122*b65280ffSSui Chen } else { 123*b65280ffSSui Chen return false; 124*b65280ffSSui Chen } 125*b65280ffSSui Chen} 126*b65280ffSSui Chen 127*b65280ffSSui Chenfunction CheckDependencies() { 128*b65280ffSSui Chen g_dbus_pcap_status_content.style.display = 'none'; 129*b65280ffSSui Chen g_dbus_pcap_error_content.style.display = 'none'; 130*b65280ffSSui Chen g_scapy_error_content.style.display = 'none'; 131*b65280ffSSui Chen g_welcome_screen_content.style.display = 'none'; 132*b65280ffSSui Chen 133*b65280ffSSui Chen const dbus_pcap_ok = IsDbusPcapPresent(); 134*b65280ffSSui Chen if (!dbus_pcap_ok) { 135*b65280ffSSui Chen g_dbus_pcap_error_content.style.display = 'block'; 136*b65280ffSSui Chen } 137*b65280ffSSui Chen 138*b65280ffSSui Chen const scapy_ok = IsPythonInstallationOK(); 139*b65280ffSSui Chen if (!scapy_ok) { 140*b65280ffSSui Chen g_scapy_error_content.style.display = 'block'; 141*b65280ffSSui Chen } 142*b65280ffSSui Chen 143*b65280ffSSui Chen let msg = ""; 144*b65280ffSSui Chen if (dbus_pcap_ok) { 145*b65280ffSSui Chen msg += 'dbus-pcap found, md5sum: ' + 146*b65280ffSSui Chen md5File.sync('dbus-pcap'); 147*b65280ffSSui Chen g_dbus_pcap_status_content.style.display = 'block'; 148*b65280ffSSui Chen g_dbus_pcap_status_content.textContent = msg; 149*b65280ffSSui Chen } 150*b65280ffSSui Chen 151*b65280ffSSui Chen if (dbus_pcap_ok && scapy_ok) { 152*b65280ffSSui Chen g_welcome_screen_content.style.display = 'block'; 153*b65280ffSSui Chen } 154*b65280ffSSui Chen} 155*b65280ffSSui Chen 156*b65280ffSSui Chenfunction Init() { 157*b65280ffSSui Chen console.log('[Init] Initialization'); 158*b65280ffSSui Chen ipmi_timeline_view.Canvas = document.getElementById('my_canvas_ipmi'); 159*b65280ffSSui Chen dbus_timeline_view.Canvas = document.getElementById('my_canvas_dbus'); 160*b65280ffSSui Chen boost_asio_handler_timeline_view.Canvas = 161*b65280ffSSui Chen document.getElementById('my_canvas_boost_asio_handler'); 162*b65280ffSSui Chen 163*b65280ffSSui Chen // Hide all canvases until the user loads files 164*b65280ffSSui Chen ipmi_timeline_view.Canvas.style.display = 'none'; 165*b65280ffSSui Chen dbus_timeline_view.Canvas.style.display = 'none'; 166*b65280ffSSui Chen boost_asio_handler_timeline_view.Canvas.style.display = 'none'; 167*b65280ffSSui Chen 168*b65280ffSSui Chen let v1 = ipmi_timeline_view; 169*b65280ffSSui Chen let v2 = dbus_timeline_view; 170*b65280ffSSui Chen let v3 = boost_asio_handler_timeline_view; 171*b65280ffSSui Chen 172*b65280ffSSui Chen // Link views 173*b65280ffSSui Chen v1.linked_views = [v2, v3]; 174*b65280ffSSui Chen v2.linked_views = [v1, v3]; 175*b65280ffSSui Chen v3.linked_views = [v1, v2]; 176*b65280ffSSui Chen 177*b65280ffSSui Chen // Set accent color 178*b65280ffSSui Chen v1.AccentColor = 'rgba(0,224,224,0.5)'; 179*b65280ffSSui Chen v2.AccentColor = 'rgba(0,128,0, 0.5)'; 180*b65280ffSSui Chen v3.AccentColor = '#E22'; 181*b65280ffSSui Chen 182*b65280ffSSui Chen CheckDependencies(); 183*b65280ffSSui Chen} 184*b65280ffSSui Chen 185*b65280ffSSui Chenvar g_WelcomeScreen = document.getElementById('welcome_screen'); 186*b65280ffSSui Chenfunction HideWelcomeScreen() { 187*b65280ffSSui Chen g_WelcomeScreen.style.display = 'none'; 188*b65280ffSSui Chen} 189*b65280ffSSui Chen 190*b65280ffSSui Chenvar g_Blocker = document.getElementById('blocker'); 191*b65280ffSSui Chenvar g_BlockerCaption = document.getElementById('blocker_caption'); 192*b65280ffSSui Chenfunction HideBlocker() { 193*b65280ffSSui Chen g_Blocker.style.display = 'none'; 194*b65280ffSSui Chen} 195*b65280ffSSui Chenfunction ShowBlocker(msg) { 196*b65280ffSSui Chen g_Blocker.style.display = 'block'; 197*b65280ffSSui Chen g_BlockerCaption.textContent = msg; 198*b65280ffSSui Chen} 199*b65280ffSSui Chen 200*b65280ffSSui Chenvar g_Navigation = document.getElementById('div_navi_and_replay'); 201*b65280ffSSui Chenfunction ShowNavigation() { 202*b65280ffSSui Chen g_Navigation.style.display = 'block'; 203*b65280ffSSui Chen} 204*b65280ffSSui Chen 205*b65280ffSSui Chenfunction UpdateFileNamesString() { 206*b65280ffSSui Chen let tmp = []; 207*b65280ffSSui Chen if (ipmi_timeline_view.CurrentFileName != '') { 208*b65280ffSSui Chen tmp.push('IPMI timeline: ' + ipmi_timeline_view.CurrentFileName) 209*b65280ffSSui Chen } 210*b65280ffSSui Chen if (dbus_timeline_view.CurrentFileName != '') { 211*b65280ffSSui Chen tmp.push('DBus timeline: ' + dbus_timeline_view.CurrentFileName) 212*b65280ffSSui Chen } 213*b65280ffSSui Chen if (boost_asio_handler_timeline_view.CurrentFileName != '') { 214*b65280ffSSui Chen tmp.push( 215*b65280ffSSui Chen 'ASIO timeline: ' + boost_asio_handler_timeline_view.CurrentFileName); 216*b65280ffSSui Chen } 217*b65280ffSSui Chen let s = tmp.join('<br/>'); 218*b65280ffSSui Chen document.getElementById('capture_info').innerHTML = s; 219*b65280ffSSui Chen} 220*b65280ffSSui Chen 221*b65280ffSSui Chenvar g_cb_debug_info = document.getElementById('cb_debuginfo'); 222*b65280ffSSui Chen 223*b65280ffSSui Chen 224*b65280ffSSui ChenInit(); 225